📄 fad.sound.c
字号:
/** * libFAD - Flash Animation Decode library * Copyright (C) 2005-2006 VGSystem Technologies, Inc. * * libFAD is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * source distribution. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: fad.sound.c,v 1.19 2006/03/01 09:46:12 wrxzzj Exp $ */#include "fad.sound.h"#include "fad.bits.h"#include <pthread.h>typedef enum { ADPCM_DEC_MONO, ADPCM_DEC_STEREO_LEFT, ADPCM_DEC_STEREO_RIGHT} adpcm_decode_type_t;struct _adpcm_state_s { short valprev; /* Previous output value */ char index; /* Index into stepsize table */};typedef struct _adpcm_state_s adpcm_state_t;static s32_t idx_table[4][16] = { {-1, 2}, {-1, -1, 2, 4}, {-1, -1, -1, -1, 2, 4, 6, 8}, {-1, -1, -1, -1, -1, -1, -1, -1, 2, 4, 6, 8, 10, 13, 16}};static s32_t stepsize_table[89] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767};static void _adpcm_decode(bits_t* bits, s16_t* buffer, u8_t nbits, adpcm_state_t* state, adpcm_decode_type_t type) { u8_t val[4] = {2, 4, 8, 16}; s16_t* outptr = NULL; s32_t sign, delta, step, valpred, vpdiff, index, size = nbits<<12; if(type == ADPCM_DEC_STEREO_RIGHT) { outptr = ++buffer; bits->npad = nbits; } else { bits->npad = 0; outptr = buffer; } valpred = state->valprev; index = state->index; step = stepsize_table[index]; while(size--) { delta = bits_get_ubits(bits, nbits); if(type != ADPCM_DEC_MONO) { /**stereo sound skip left/right sample*/ bits->npad += nbits; if(bits->npad >= 8) { bits->npad -= 8; bits->bufptr++; } } index += idx_table[nbits-2][delta-val[nbits-2]]; if(index < 0) index = 0; if(index > 88) index = 88; sign = delta&(1<<nbits); delta = delta&(0x7F>>(8-nbits)); vpdiff = step>>(nbits-1); switch(nbits) { case 2: if(delta&1) vpdiff += step; break; case 3: if(delta&2) vpdiff += step; if(delta&1) vpdiff += step>>1; break; case 4: if(delta&4) vpdiff += step; if(delta&2) vpdiff += step>>1; if(delta&1) vpdiff += step>>2; break; case 5: if(delta&8) vpdiff += step; if(delta&4) vpdiff += step>>1; if(delta&2) vpdiff += step>>2; if(delta&1) vpdiff += step>>3; break; } if(sign) valpred -= vpdiff; else valpred += vpdiff; if(valpred > 32767) valpred = 32767; else if(valpred < -32767) valpred = -32767; step = stepsize_table[index]; *outptr++ = valpred; if(type != ADPCM_DEC_MONO) outptr++; } state->valprev = valpred; state->index = index;}s32_t event_sound_decode(fad_frame_t* frame, fad_stream_t* s) { event_sound_t* es = NULL; u16_t id; u32_t nsample; es = calloc(1, sizeof(event_sound_t)); if(es == NULL) return -1; id = bits_get_u16(&s->bits); bits_seek_nbytes(&s->bits, 1); es->attr = bits_get_u8(&s->bits); nsample = bits_get_u32(&s->bits); if(nsample == 0) { free(es); return -1; } es->data = (u8_t* )bits_tell(&s->bits); es->nsize = s->tag_len - 8; s->dict->put(s->dict, es, id); FAD_ERROR("append event sound to dictionary, id = %d, attr = %x, nsample = %d\n", id, es->attr, nsample); return 0;}void fad_sound_render_adpcm (fad_render_t *render, u8_t *data, u8_t attr, s32_t nsize) { u8_t nbits; bits_t bits; adpcm_state_t lstate, rstate; u16_t *samples = NULL, nsample = 4096<<(attr&0x01); bits_init(&bits); bits_buffer(&bits, data); nbits = bits_get_ubits(&bits, 2)+2; lstate.valprev = bits_get_u16(&bits); lstate.index = bits_get_ubits(&bits, 6); samples = calloc(nsample, sizeof(u16_t)); if(samples == NULL) goto mem_error; if(attr&0x01) { _adpcm_decode(&bits, samples, nbits, &lstate, ADPCM_DEC_MONO); } else { rstate.valprev = bits_get_u16(&bits); rstate.index = bits_get_ubits(&bits, 6); _adpcm_decode(&bits, samples, nbits, &lstate, ADPCM_DEC_STEREO_LEFT); _adpcm_decode(&bits, samples, nbits, &rstate, ADPCM_DEC_STEREO_RIGHT); } default_render_write_pcm(render, samples, nsample); free(samples);mem_error: bits_finish(&bits);}static signed short fixed2short(mad_fixed_t fixed) { fixed += (1L << (MAD_F_FRACBITS -16)); if(fixed >= MAD_F_ONE) fixed = MAD_F_ONE - 1; else if(fixed < -MAD_F_ONE) fixed = -MAD_F_ONE; return (signed short) (fixed >> (MAD_F_FRACBITS + 1 - 16));}void fad_sound_render_mpeg3 (fad_render_t *render, u8_t *data_ptr, u8_t attr, s32_t nsize, struct mad_frame *frame, struct mad_synth *synth, struct mad_stream *stream ) {#define PCM_BUFSIZE 2048 u16_t idx = 0; u8_t pcm_buff[PCM_BUFSIZE] = {0}, *pcm_ptr = pcm_buff; struct mad_frame my_frame, *frame_ptr = NULL; struct mad_synth my_synth, *synth_ptr = NULL; struct mad_stream my_stream, *stream_ptr = NULL; if(frame == NULL) { mad_frame_init(&my_frame); mad_synth_init(&my_synth); mad_stream_init(&my_stream); synth_ptr = &my_synth; frame_ptr = &my_frame; stream_ptr = &my_stream; } else { synth_ptr = synth; frame_ptr = frame; stream_ptr = stream; } //FAD_ERROR("render mpeg3 size = %d\n", nsize); mad_stream_buffer(stream_ptr, data_ptr, nsize); stream_ptr->error = 0; do { if(stream_ptr->buffer == NULL || stream_ptr->error == MAD_ERROR_BUFLEN) { s32_t remain_size = 0; if(stream_ptr->next_frame != NULL) { remain_size = stream_ptr->bufend - stream_ptr->next_frame; //FAD_ERROR("unused mpeg3 data, just jump, remain_size = %d.\n", remain_size); } break; } if(mad_frame_decode(frame_ptr, stream_ptr)) { if(MAD_RECOVERABLE(stream_ptr->error) || stream_ptr->error == MAD_ERROR_BUFLEN) continue; else { FAD_ERROR("unrecoverable error in mad decoder, break.\n"); break; } } mad_synth_frame(synth_ptr, frame_ptr); /** if(frame->mad_synth.pcm.length < frame->mp3_nseek) { frame->mp3_nseek -= frame->mad_synth.pcm.length; FAD_ERROR("seek mp3 sample count = %d\n", frame->mad_synth.pcm.length); continue; } FAD_ERROR("seek mp3 sample count = %d\n", frame->mp3_nseek);*/ //FAD_ERROR("decode mpeg3 sound length = %d\n", synth_ptr->pcm.length); for(idx=0/*frame->mp3_nseek, frame->mp3_nseek = 0*/; idx<synth_ptr->pcm.length; idx++) { s16_t sample = fixed2short(synth_ptr->pcm.samples[0][idx]); *pcm_ptr++ = sample&0xff; *pcm_ptr++ = (sample>>8)&0xff; if(synth_ptr->pcm.channels == 2) { sample = fixed2short(synth_ptr->pcm.samples[1][idx]); *pcm_ptr++ = sample&0xff; *pcm_ptr++ = (sample>>8)&0xff; } if(pcm_ptr - pcm_buff == PCM_BUFSIZE) { default_render_write_pcm(render, pcm_buff, PCM_BUFSIZE); pcm_ptr = pcm_buff; } } if(pcm_ptr > pcm_buff) { default_render_write_pcm(render, pcm_buff, pcm_ptr-pcm_buff); pcm_ptr = pcm_buff; } } while(1); if(frame == NULL) { mad_frame_finish(&my_frame); mad_stream_finish(&my_stream); mad_synth_finish(&my_synth); }}void fad_sound_render_raw (fad_render_t *render, u8_t *data_ptr, u8_t attr, s32_t nsize) { default_render_write_pcm(render, data_ptr, nsize);}s32_t stream_sound_head_decode(fad_frame_t* frame, fad_stream_t* s) { u32_t rate[] = {5512, 11025, 22050, 44100}; u8_t nbits = 8, nchannel = 1; u16_t nsample = 0; bits_seek_nbytes(&s->bits, 1); frame->ss_attr = bits_get_u8(&s->bits); nsample = bits_get_u16(&s->bits); if(nsample <= 0) return -1; return default_render_open_snddev(frame->render, frame->ss_attr);}s32_t stream_sound_block_decode(fad_frame_t* frame, fad_stream_t* s) { u16_t nsample; s16_t nseek; switch(frame->ss_attr&0xf0) { case 0x10: { nsample = bits_get_u16(&s->bits); frame->ss_nsize = s->tag_len - 2; /**skip sample count*/ frame->ss_buff = bits_tell(&s->bits); } break; case 0x20: { nsample = bits_get_u16(&s->bits); nseek = bits_get_s16(&s->bits); FAD_ERROR("mpeg3 stream sound, nsample = %d, nseek = %d\n", nsample, nseek); frame->ss_nsize = s->tag_len - 4; /**skip sample count & seek number*/ frame->ss_buff = bits_tell(&s->bits); } break; case 0x60: FAD_ERROR("Nellymoser stream sound isn't support in sound stream.\n"); break; case 0x00: case 0x30: FAD_ERROR("uncompress stream sound isn't support in sound stream.\n"); break; } FAD_FRAME_SET_STREAMSOUND(frame->attr); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -