Mercurial > mplayer.hg
comparison dec_audio.c @ 758:5a92a5601666
better audio out buffering & sample_format added
author | arpi_esp |
---|---|
date | Fri, 11 May 2001 01:22:35 +0000 |
parents | 32a8e9e43d94 |
children | ef5d1ab14218 |
comparison
equal
deleted
inserted
replaced
757:8814b8de8b4e | 758:5a92a5601666 |
---|---|
1 | 1 |
2 #include <stdio.h> | 2 #include <stdio.h> |
3 #include <stdlib.h> | 3 #include <stdlib.h> |
4 | |
5 #include <sys/soundcard.h> | |
4 | 6 |
5 #include "config.h" | 7 #include "config.h" |
6 | 8 |
7 extern int verbose; // defined in mplayer.c | 9 extern int verbose; // defined in mplayer.c |
8 | 10 |
44 int init_audio(sh_audio_t *sh_audio){ | 46 int init_audio(sh_audio_t *sh_audio){ |
45 | 47 |
46 int driver=sh_audio->codec->driver; | 48 int driver=sh_audio->codec->driver; |
47 | 49 |
48 extern int init_acm_audio_codec(sh_audio_t *sh_audio); | 50 extern int init_acm_audio_codec(sh_audio_t *sh_audio); |
49 extern int acm_decode_audio(sh_audio_t *sh_audio, void* a_buffer,int len); | 51 //extern int acm_decode_audio(sh_audio_t *sh_audio, void* a_buffer,int len); |
52 extern int acm_decode_audio(sh_audio_t *sh_audio, void* a_buffer,int minlen,int maxlen); | |
50 | 53 |
51 sh_audio->samplesize=2; | 54 sh_audio->samplesize=2; |
55 sh_audio->sample_format=AFMT_S16_LE; | |
52 sh_audio->samplerate=0; | 56 sh_audio->samplerate=0; |
53 //sh_audio->pcm_bswap=0; | 57 //sh_audio->pcm_bswap=0; |
54 | 58 |
55 sh_audio->a_buffer_size=2*MAX_OUTBURST; // default size, maybe not enough for Win32/ACM | 59 sh_audio->a_buffer_size=0; |
56 sh_audio->a_buffer=NULL; | 60 sh_audio->a_buffer=NULL; |
57 | 61 |
58 sh_audio->a_in_buffer_len=0; | 62 sh_audio->a_in_buffer_len=0; |
59 | 63 |
60 if(driver==4){ | 64 // setup required min. in/out buffer size: |
65 sh_audio->audio_out_minsize=8192;// default size, maybe not enough for Win32/ACM | |
66 | |
67 switch(driver){ | |
68 case 4: | |
61 // Win32 ACM audio codec: | 69 // Win32 ACM audio codec: |
62 if(init_acm_audio_codec(sh_audio)){ | 70 if(init_acm_audio_codec(sh_audio)){ |
63 sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec; | 71 sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec; |
64 sh_audio->channels=sh_audio->o_wf.nChannels; | 72 sh_audio->channels=sh_audio->o_wf.nChannels; |
65 sh_audio->samplerate=sh_audio->o_wf.nSamplesPerSec; | 73 sh_audio->samplerate=sh_audio->o_wf.nSamplesPerSec; |
66 if(sh_audio->a_buffer_size<sh_audio->audio_out_minsize+MAX_OUTBURST) | 74 // if(sh_audio->audio_out_minsize>16384) sh_audio->audio_out_minsize=16384; |
67 sh_audio->a_buffer_size=sh_audio->audio_out_minsize+MAX_OUTBURST; | 75 // sh_audio->a_buffer_size=sh_audio->audio_out_minsize; |
76 // if(sh_audio->a_buffer_size<sh_audio->audio_out_minsize+MAX_OUTBURST) | |
77 // sh_audio->a_buffer_size=sh_audio->audio_out_minsize+MAX_OUTBURST; | |
68 } else { | 78 } else { |
69 printf("Could not load/initialize Win32/ACM AUDIO codec (missing DLL file?)\n"); | 79 printf("Could not load/initialize Win32/ACM AUDIO codec (missing DLL file?)\n"); |
70 driver=0; | 80 driver=0; |
71 } | 81 } |
72 } | 82 break; |
73 | 83 case 7: |
74 if(driver==7){ | |
75 #ifndef USE_DIRECTSHOW | 84 #ifndef USE_DIRECTSHOW |
76 printf("Compiled without DirectShow support -> force nosound :(\n"); | 85 printf("Compiled without DirectShow support -> force nosound :(\n"); |
77 driver=0; | 86 driver=0; |
78 #else | 87 #else |
79 // Win32 DShow audio codec: | 88 // Win32 DShow audio codec: |
80 // printf("DShow_audio: channs=%d rate=%d\n",sh_audio->channels,sh_audio->samplerate); | 89 // printf("DShow_audio: channs=%d rate=%d\n",sh_audio->channels,sh_audio->samplerate); |
81 | |
82 if(DS_AudioDecoder_Open(sh_audio->codec->dll,&sh_audio->codec->guid,sh_audio->wf)){ | 90 if(DS_AudioDecoder_Open(sh_audio->codec->dll,&sh_audio->codec->guid,sh_audio->wf)){ |
83 printf("ERROR: Could not load/initialize Win32/DirctShow AUDIO codec: %s\n",sh_audio->codec->dll); | 91 printf("ERROR: Could not load/initialize Win32/DirctShow AUDIO codec: %s\n",sh_audio->codec->dll); |
84 driver=0; | 92 driver=0; |
85 } else { | 93 } else { |
86 sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec; | 94 sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec; |
89 sh_audio->audio_in_minsize=2*sh_audio->wf->nBlockAlign; | 97 sh_audio->audio_in_minsize=2*sh_audio->wf->nBlockAlign; |
90 if(sh_audio->audio_in_minsize<8192) sh_audio->audio_in_minsize=8192; | 98 if(sh_audio->audio_in_minsize<8192) sh_audio->audio_in_minsize=8192; |
91 sh_audio->a_in_buffer_size=sh_audio->audio_in_minsize; | 99 sh_audio->a_in_buffer_size=sh_audio->audio_in_minsize; |
92 sh_audio->a_in_buffer=malloc(sh_audio->a_in_buffer_size); | 100 sh_audio->a_in_buffer=malloc(sh_audio->a_in_buffer_size); |
93 sh_audio->a_in_buffer_len=0; | 101 sh_audio->a_in_buffer_len=0; |
102 sh_audio->audio_out_minsize=16384; | |
94 } | 103 } |
95 #endif | 104 #endif |
105 break; | |
106 case 2: | |
107 case 8: | |
108 case 5: | |
109 // PCM, aLaw | |
110 sh_audio->audio_out_minsize=2048; | |
111 break; | |
112 case 3: | |
113 // Dolby AC3 audio: | |
114 sh_audio->audio_out_minsize=4*256*6; | |
115 break; | |
116 case 6: | |
117 // MS-GSM audio codec: | |
118 sh_audio->audio_out_minsize=4*320; | |
119 break; | |
120 case 1: | |
121 // MPEG Audio: | |
122 sh_audio->audio_out_minsize=4608; | |
123 break; | |
96 } | 124 } |
97 | 125 |
98 if(!driver) return 0; | 126 if(!driver) return 0; |
99 | 127 |
100 // allocate audio out buffer: | 128 // allocate audio out buffer: |
129 sh_audio->a_buffer_size=sh_audio->audio_out_minsize+MAX_OUTBURST; // worst case calc. | |
130 | |
131 printf("dec_audio: Allocating %d + %d = %d bytes for output buffer\n", | |
132 sh_audio->audio_out_minsize,MAX_OUTBURST,sh_audio->a_buffer_size); | |
133 | |
101 sh_audio->a_buffer=malloc(sh_audio->a_buffer_size); | 134 sh_audio->a_buffer=malloc(sh_audio->a_buffer_size); |
135 if(!sh_audio->a_buffer){ | |
136 printf("Cannot allocate audio out buffer\n"); | |
137 return 0; | |
138 } | |
102 memset(sh_audio->a_buffer,0,sh_audio->a_buffer_size); | 139 memset(sh_audio->a_buffer,0,sh_audio->a_buffer_size); |
103 sh_audio->a_buffer_len=0; | 140 sh_audio->a_buffer_len=0; |
104 | 141 |
105 switch(driver){ | 142 switch(driver){ |
106 case 4: { | 143 case 4: { |
107 int ret=acm_decode_audio(sh_audio,sh_audio->a_buffer,sh_audio->a_buffer_size); | 144 int ret=acm_decode_audio(sh_audio,sh_audio->a_buffer,4096,sh_audio->a_buffer_size); |
108 if(ret<0){ | 145 if(ret<0){ |
109 printf("ACM decoding error: %d\n",ret); | 146 printf("ACM decoding error: %d\n",ret); |
110 driver=0; | 147 driver=0; |
111 } | 148 } |
112 sh_audio->a_buffer_len=ret; | 149 sh_audio->a_buffer_len=ret; |
117 WAVEFORMATEX *h=sh_audio->wf; | 154 WAVEFORMATEX *h=sh_audio->wf; |
118 sh_audio->i_bps=h->nAvgBytesPerSec; | 155 sh_audio->i_bps=h->nAvgBytesPerSec; |
119 sh_audio->channels=h->nChannels; | 156 sh_audio->channels=h->nChannels; |
120 sh_audio->samplerate=h->nSamplesPerSec; | 157 sh_audio->samplerate=h->nSamplesPerSec; |
121 sh_audio->samplesize=(h->wBitsPerSample+7)/8; | 158 sh_audio->samplesize=(h->wBitsPerSample+7)/8; |
159 switch(sh_audio->format){ // hardware formats: | |
160 case 0x6: sh_audio->sample_format=AFMT_A_LAW;break; | |
161 case 0x7: sh_audio->sample_format=AFMT_MU_LAW;break; | |
162 case 0x11: sh_audio->sample_format=AFMT_IMA_ADPCM;break; | |
163 case 0x50: sh_audio->sample_format=AFMT_MPEG;break; | |
164 // case 0x2000: sh_audio->sample_format=AFMT_AC3; | |
165 default: sh_audio->sample_format=(sh_audio->samplesize==2)?AFMT_S16_LE:AFMT_U8; | |
166 } | |
122 break; | 167 break; |
123 } | 168 } |
124 case 8: { | 169 case 8: { |
125 // DVD PCM Audio: | 170 // DVD PCM Audio: |
126 sh_audio->channels=2; | 171 sh_audio->channels=2; |
155 } | 200 } |
156 break; | 201 break; |
157 } | 202 } |
158 case 5: { | 203 case 5: { |
159 // aLaw audio codec: | 204 // aLaw audio codec: |
160 Gen_aLaw_2_Signed(); // init table | 205 if(sh_audio->format==6) |
206 Gen_aLaw_2_Signed(); // init table | |
207 else | |
208 Gen_uLaw_2_Signed(); // init table | |
161 sh_audio->channels=sh_audio->wf->nChannels; | 209 sh_audio->channels=sh_audio->wf->nChannels; |
162 sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; | 210 sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; |
163 sh_audio->i_bps=sh_audio->channels*sh_audio->samplerate; | 211 sh_audio->i_bps=sh_audio->channels*sh_audio->samplerate; |
164 break; | 212 break; |
165 } | 213 } |
238 case 5: // aLaw decoder | 286 case 5: // aLaw decoder |
239 { int l=demux_read_data(sh_audio->ds,buf,minlen/2); | 287 { int l=demux_read_data(sh_audio->ds,buf,minlen/2); |
240 unsigned short *d=(unsigned short *) buf; | 288 unsigned short *d=(unsigned short *) buf; |
241 unsigned char *s=buf; | 289 unsigned char *s=buf; |
242 len=2*l; | 290 len=2*l; |
243 while(l>0){ | 291 if(sh_audio->format==6){ |
244 --l; | 292 // aLaw |
245 d[l]=xa_alaw_2_sign[s[l]]; | 293 while(l>0){ --l; d[l]=xa_alaw_2_sign[s[l]]; } |
294 } else { | |
295 // uLaw | |
296 while(l>0){ --l; d[l]=xa_ulaw_2_sign[s[l]]; } | |
246 } | 297 } |
247 break; | 298 break; |
248 } | 299 } |
249 case 6: // MS-GSM decoder | 300 case 6: // MS-GSM decoder |
250 { unsigned char buf[65]; // 65 bytes / frame | 301 { unsigned char buf[65]; // 65 bytes / frame |
264 sh_audio->ac3_frame=NULL; | 315 sh_audio->ac3_frame=NULL; |
265 } | 316 } |
266 //printf("{3:%d}",avi_header.idx_pos);fflush(stdout); | 317 //printf("{3:%d}",avi_header.idx_pos);fflush(stdout); |
267 break; | 318 break; |
268 case 4: | 319 case 4: |
269 len=acm_decode_audio(sh_audio,buf,maxlen); | 320 // len=sh_audio->audio_out_minsize; // optimal decoded fragment size |
270 // len=acm_decode_audio(sh_audio,buf,minlen); | 321 // if(len<minlen) len=minlen; else |
322 // if(len>maxlen) len=maxlen; | |
323 // len=acm_decode_audio(sh_audio,buf,len); | |
324 len=acm_decode_audio(sh_audio,buf,minlen,maxlen); | |
271 break; | 325 break; |
272 | 326 |
273 #ifdef USE_DIRECTSHOW | 327 #ifdef USE_DIRECTSHOW |
274 case 7: // DirectShow | 328 case 7: // DirectShow |
275 { int ret; | 329 { int ret; |