📄 sound.c
字号:
#include <string.h>#include <config.h>#ifdef HAVE_MAD#include <mad.h>#else#define getbits mpg_getbits#include "mpglib/mpglib.h"#undef getbits#endif#include "swfdec_internal.h"void adpcm_decode(SwfdecDecoder *s,SwfdecObject *obj);SwfdecSoundBuffer *swfdec_sound_buffer_new(int len);void swfdec_decoder_sound_buffer_append(SwfdecDecoder *s, SwfdecSoundBuffer *buffer);void swfdec_sound_free(SwfdecObject *object){ SwfdecSound *sound = object->priv; if(sound->sound_buf)g_free(sound->sound_buf); g_free(sound);}#ifdef HAVE_MADvoid mp3_decode_mad(SwfdecObject *obj){ struct mad_stream stream; struct mad_frame frame; struct mad_synth synth; SwfdecSound *sound = obj->priv; int ret; mad_stream_init(&stream); mad_frame_init(&frame); mad_synth_init(&synth); mad_stream_buffer(&stream, sound->orig_data, sound->orig_len); while(1){ ret = mad_frame_decode(&frame, &stream); if(ret == -1 && stream.error == MAD_ERROR_BUFLEN){ break; } if(ret == -1){ printf("stream error 0x%04x\n",stream.error); return; } mad_synth_frame(&synth, &frame); } mad_synth_finish(&synth); mad_frame_finish(&frame); mad_stream_finish(&stream);}int tag_func_sound_stream_block(SwfdecDecoder *s){ SwfdecObject *obj; SwfdecSound *sound; int ret; int n_samples, n_left; /* for MPEG, data starts after 4 byte header */ obj = s->stream_sound_obj; sound = obj->priv; if(sound->format != 2){ SWF_DEBUG(4,"tag_func_define_sound: unknown format %d\n",sound->format); return SWF_OK; } n_samples = get_u16(&s->b); n_left = get_u16(&s->b); //printf("sound stream %d %d %d\n", ack1, ack2, s->sound_offset/2); if(s->tag_len - 4 == 0){ /* the end? */ return SWF_OK; } memcpy(sound->tmpbuf + sound->tmpbuflen, s->b.ptr, s->tag_len - 4); sound->tmpbuflen += s->tag_len - 4; mad_stream_buffer(&sound->stream, sound->tmpbuf, sound->tmpbuflen); while(sound->tmpbuflen >= 0){ ret = mad_frame_decode(&sound->frame, &sound->stream); if(ret == -1 && sound->stream.error == MAD_ERROR_BUFLEN){ //fprintf(stderr,"error buflen\n"); break; } if(ret == -1){ fprintf(stderr,"stream error 0x%04x\n", sound->stream.error); return SWF_ERROR; } mad_synth_frame(&sound->synth, &sound->frame); if(sound->synth.pcm.samplerate==11025){ SwfdecSoundBuffer *buffer; short *data; int i; buffer = swfdec_sound_buffer_new(sound->synth.pcm.length*2*2*4); data = (short *)buffer->data; if(sound->synth.pcm.channels==2){ for(i=0;i<sound->synth.pcm.length;i++){ short c0,c1; c0 = sound->synth.pcm.samples[0][i]>>14; c1 = sound->synth.pcm.samples[1][i]>>14; *data++ = c0; *data++ = c1; *data++ = c0; *data++ = c1; *data++ = c0; *data++ = c1; *data++ = c0; *data++ = c1; } }else{ for(i=0;i<sound->synth.pcm.length;i++){ short c0; c0 = sound->synth.pcm.samples[0][i]>>14; *data++ = c0; *data++ = c0; *data++ = c0; *data++ = c0; *data++ = c0; *data++ = c0; *data++ = c0; *data++ = c0; } } swfdec_decoder_sound_buffer_append(s,buffer); }else if(sound->synth.pcm.samplerate==22050){ SwfdecSoundBuffer *buffer; short *data; int i; buffer = swfdec_sound_buffer_new(sound->synth.pcm.length*2*2*2); data = (short *)buffer->data; if(sound->synth.pcm.channels==2){ for(i=0;i<sound->synth.pcm.length;i++){ short c0,c1; c0 = sound->synth.pcm.samples[0][i]>>14; c1 = sound->synth.pcm.samples[1][i]>>14; *data++ = c0; *data++ = c1; *data++ = c0; *data++ = c1; } }else{ for(i=0;i<sound->synth.pcm.length;i++){ short c0; c0 = sound->synth.pcm.samples[0][i]>>14; *data++ = c0; *data++ = c0; *data++ = c0; *data++ = c0; } } swfdec_decoder_sound_buffer_append(s,buffer); }else{ fprintf(stderr,"sample rate not handled (%d)\n", sound->synth.pcm.samplerate); } } sound->tmpbuflen -= sound->stream.next_frame - sound->tmpbuf; memmove(sound->tmpbuf, sound->stream.next_frame, sound->tmpbuflen); s->b.ptr += s->tag_len - 4; return SWF_OK;}#endif#ifndef HAVE_MADvoid mp3_decode_mpglib(SwfdecObject *obj){ MpglibDecoder *mp; int n; int offset = 0; int ret; SwfdecSound *sound = obj->priv; mp = mpglib_decoder_new(); ret = mpglib_decoder_decode(mp, (void *)sound->orig_data, sound->orig_len, sound->sound_buf, sound->sound_len, &n); fprintf(stderr,"decoding %d bytes\n",sound->orig_len); while(ret==MPGLIB_OK){ offset += n; ret = mpglib_decoder_decode(mp, NULL, 0, sound->sound_buf, sound->sound_len, &n); } fprintf(stderr,"total decoded %d\n",offset + n);}#endifint tag_func_define_sound(SwfdecDecoder *s){ //static char *format_str[16] = { "uncompressed", "adpcm", "mpeg" }; //static int rate_n[4] = { 5512.5, 11025, 22050, 44100 }; bits_t *b = &s->b; int id; int format; int rate; int size; int type; int n_samples; SwfdecObject *obj; SwfdecSound *sound; int len; id = get_u16(b); format = getbits(b,4); rate = getbits(b,2); size = getbits(b,1); type = getbits(b,1); n_samples = get_u32(b); obj = swfdec_object_new(s,id); sound = g_new0(SwfdecSound,1); obj->priv = sound; obj->type = SWF_OBJECT_SOUND; sound->n_samples = n_samples; sound->format = format; switch(format){ case 2: /* unknown */ len = get_u16(b); sound->orig_data = b->ptr; sound->orig_len = s->tag_len - 9; sound->sound_len = 10000; sound->sound_buf = malloc(sound->sound_len);#ifdef HAVE_MAD mp3_decode_mad(obj);#else mp3_decode_mpglib(obj);#endif s->b.ptr += s->tag_len - 9; break; case 1: //printf(" size = %d (%d bit)\n", size, size ? 16 : 8); //printf(" type = %d (%d channels)\n", type, type + 1); //printf(" n_samples = %d\n", n_samples); adpcm_decode(s,obj); break; default: SWF_DEBUG(4,"tag_func_define_sound: unknown format %d\n",format); } return SWF_OK;}void swfdec_decoder_sound_buffer_append(SwfdecDecoder *s, SwfdecSoundBuffer *buffer){ s->stream_sound_buffers = g_list_append(s->stream_sound_buffers, buffer);}SwfdecSoundBuffer *swfdec_sound_buffer_new(int len){ SwfdecSoundBuffer *sb; sb = g_new0(SwfdecSoundBuffer,1); sb->len = len; sb->offset = 0; sb->data = g_malloc(len); return sb;}#ifndef HAVE_MADint tag_func_sound_stream_block(SwfdecDecoder *s){ SwfdecObject *obj; SwfdecSound *sound; SwfdecSoundBuffer *buffer; int ret; int n; int n_samples, n_left; /* for MPEG, data starts after 4 byte header */ obj = s->stream_sound_obj; sound = obj->priv; if(sound->format != 2){ SWF_DEBUG(4,"tag_func_define_sound: unknown format %d\n",sound->format); return SWF_OK; } n_samples = get_u16(&s->b); n_left = get_u16(&s->b); //printf("sound stream %d %d %d\n", ack1, ack2, s->sound_offset/2); if(s->tag_len - 4 == 0){ /* the end? */ return SWF_OK; } buffer = swfdec_sound_buffer_new(4608); fwrite(s->b.ptr,s->tag_len - 4, 1, stdout); ret = mpglib_decoder_decode(sound->mp, s->b.ptr, s->tag_len - 4, buffer->data, buffer->len, &n); while(ret==MPGLIB_OK){ int i; for(i=0;i<64;i++){ fprintf(stderr,"%02x ",((unsigned char *)buffer->data)[i]); if((i%16)==15)fprintf(stderr,"\n"); } swfdec_decoder_sound_buffer_append(s,buffer); buffer = swfdec_sound_buffer_new(4608); ret = mpglib_decoder_decode(sound->mp, NULL, 0, buffer->data, buffer->len, &n); } if(ret==MPGLIB_ERR){ SWF_DEBUG(4,"mp3 stream error\n"); } g_free(buffer->data); g_free(buffer); s->b.ptr += s->tag_len - 4; return SWF_OK;}#endifint tag_func_sound_stream_head(SwfdecDecoder *s){ //static char *format_str[16] = { "uncompressed", "adpcm", "mpeg" }; //static int rate_n[4] = { 5512.5, 11025, 22050, 44100 }; bits_t *b = &s->b; int mix_format; int format; int rate; int size; int type; int n_samples; int unknown; SwfdecObject *obj; SwfdecSound *sound; mix_format = get_u8(b); format = getbits(b,4); rate = getbits(b,2); size = getbits(b,1); type = getbits(b,1); n_samples = get_u16(b); unknown = get_u16(b); //printf(" mix_format = %d\n", mix_format); //printf(" format = %d (%s)\n", format, format_str[format]); //printf(" rate = %d (%d Hz) [spec: reserved]\n", rate, rate_n[rate]); //printf(" size = %d (%d bit)\n", size, size ? 16 : 8); //printf(" type = %d (%d channels)\n", type, type + 1); //printf(" n_samples = %d\n", n_samples); /* XXX per frame? */ //printf(" unknown = %d\n", unknown); obj = swfdec_object_new(s,0); s->stream_sound_obj = obj; sound = g_new0(SwfdecSound,1); obj->priv = sound; obj->type = SWF_OBJECT_SOUND; sound->format = format; switch(format){ case 2:#ifdef HAVE_MAD mad_stream_init(&sound->stream); mad_frame_init(&sound->frame); mad_synth_init(&sound->synth);#else sound->mp = mpglib_decoder_new();#endif break; default: SWF_DEBUG(4,"unimplemented sound format\n"); } return SWF_OK;}static void get_soundinfo(bits_t *b){ int syncflags; int has_envelope; int has_loops; int has_out_point; int has_in_point; int in_point = 0; int out_point = 0; int loop_count = 0; int envelope_n_points = 0; int mark44; int level0; int level1; int i; syncflags = getbits(b,4); has_envelope = getbits(b,1); has_loops = getbits(b,1); has_out_point = getbits(b,1); has_in_point = getbits(b,1); if(has_in_point){ in_point = get_u32(b); } if(has_out_point){ out_point = get_u32(b); } if(has_loops){ loop_count = get_u16(b); } if(has_envelope){ envelope_n_points = get_u8(b); } //printf(" syncflags = %d\n", syncflags); //printf(" has_envelope = %d\n", has_envelope); //printf(" has_loops = %d\n", has_loops); //printf(" has_out_point = %d\n", has_out_point); //printf(" has_in_point = %d\n", has_in_point); //printf(" in_point = %d\n", in_point); //printf(" out_point = %d\n", out_point); //printf(" loop_count = %d\n", loop_count); //printf(" envelope_n_points = %d\n", envelope_n_points); for(i=0;i<envelope_n_points;i++){ mark44 = get_u32(b); level0 = get_u16(b); level1 = get_u16(b); //printf(" mark44 = %d\n",mark44); //printf(" level0 = %d\n",level0); //printf(" level1 = %d\n",level1); }}int tag_func_start_sound(SwfdecDecoder *s){ bits_t *b = &s->b; int id; id = get_u16(b); //printf(" id = %d\n", id); get_soundinfo(b); return SWF_OK;}int tag_func_define_button_sound(SwfdecDecoder *s){ int id; int i; int state; id = get_u16(&s->b); //printf(" id = %d\n",id); for(i=0;i<4;i++){ state = get_u16(&s->b); //printf(" state = %d\n",state); if(state){ get_soundinfo(&s->b); } } return SWF_OK;}int index_adjust[16] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8,};int step_size[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};void adpcm_decode(SwfdecDecoder *s,SwfdecObject *obj){ bits_t *bits = &s->b; SwfdecSound *sound = obj->priv; int n_bits; int sample; int index; int x; int i; int diff; int n, n_samples; int j = 0;#if 0 sample = get_u8(bits)<<8; sample |= get_u8(bits); printf("sample %d\n",sample);#endif n_bits = getbits(bits,2) + 2; //printf("n_bits = %d\n",n_bits); if(n_bits!=4)return; n_samples = sound->n_samples; while(n_samples){ n = n_samples; if(n>4096)n=4096; sample = getsbits(bits,16); //printf("sample = %d\n",sample); index = getbits(bits,6); //printf("index = %d\n",index); for(i=1;i<n;i++){ x = getbits(bits,n_bits); diff = (step_size[index]*(x&0x7))>>2; diff += step_size[index]>>3; if(x&8)diff=-diff; sample += diff; if(sample<-32768)sample=-32768; if(sample>32767)sample=32767; index += index_adjust[x]; if(index<0)index=0; if(index>88)index=88; j++; } n_samples -= n; }}void swfdec_sound_render(SwfdecDecoder *s){ int len; GList *g; SwfdecSoundBuffer *buffer; SwfdecSoundBuffer *buf; int offset = 0; int n; len = 2*2*(44100/s->rate); buffer = swfdec_sound_buffer_new(len); memset(buffer->data,0,len); while(1){ if(!s->stream_sound_buffers)break; g = g_list_first(s->stream_sound_buffers); if(!g)break; buf = (SwfdecSoundBuffer *)g->data; n = MIN(buf->len - buf->offset,len - offset); /* FIXME this isn't composing */ memcpy(buffer->data + offset, buf->data + buf->offset,n); offset += n; buf->offset += n; if(buf->offset >= buf->len){ g_free(buf->data); s->stream_sound_buffers = g_list_delete_link(s->stream_sound_buffers,g); } if(offset >= len){ break; } } SWF_DEBUG(0,"sound buffer: len=%d filled %d\n",len,offset); s->sound_buffers = g_list_append(s->sound_buffers, buffer);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -