diff dec_audio.c @ 746:cd1f0d4de0b8

new audio playback and A-V sync code
author arpi_esp
date Thu, 10 May 2001 03:39:54 +0000
parents e14114170e01
children 32a8e9e43d94
line wrap: on
line diff
--- a/dec_audio.c	Wed May 09 23:41:01 2001 +0000
+++ b/dec_audio.c	Thu May 10 03:39:54 2001 +0000
@@ -52,16 +52,19 @@
 sh_audio->samplerate=0;
 //sh_audio->pcm_bswap=0;
 
-sh_audio->a_buffer_size=16384;  // default size, maybe not enough for Win32/ACM
+sh_audio->a_buffer_size=2*MAX_OUTBURST;  // default size, maybe not enough for Win32/ACM
 sh_audio->a_buffer=NULL;
 
+sh_audio->a_in_buffer_len=0;
+
 if(driver==4){
   // Win32 ACM audio codec:
   if(init_acm_audio_codec(sh_audio)){
+    sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec;
     sh_audio->channels=sh_audio->o_wf.nChannels;
     sh_audio->samplerate=sh_audio->o_wf.nSamplesPerSec;
-    if(sh_audio->a_buffer_size<sh_audio->audio_out_minsize+OUTBURST)
-        sh_audio->a_buffer_size=sh_audio->audio_out_minsize+OUTBURST;
+    if(sh_audio->a_buffer_size<sh_audio->audio_out_minsize+MAX_OUTBURST)
+        sh_audio->a_buffer_size=sh_audio->audio_out_minsize+MAX_OUTBURST;
   } else {
     printf("Could not load/initialize Win32/ACM AUDIO codec (missing DLL file?)\n");
     driver=0;
@@ -80,6 +83,7 @@
     printf("ERROR: Could not load/initialize Win32/DirctShow AUDIO codec: %s\n",sh_audio->codec->dll);
     driver=0;
   } else {
+    sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec;
     sh_audio->channels=sh_audio->wf->nChannels;
     sh_audio->samplerate=sh_audio->wf->nSamplesPerSec;
     sh_audio->audio_in_minsize=2*sh_audio->wf->nBlockAlign;
@@ -111,6 +115,7 @@
 case 2: {
     // AVI PCM Audio:
     WAVEFORMATEX *h=sh_audio->wf;
+    sh_audio->i_bps=h->nAvgBytesPerSec;
     sh_audio->channels=h->nChannels;
     sh_audio->samplerate=h->nSamplesPerSec;
     sh_audio->samplesize=(h->wBitsPerSample+7)/8;
@@ -120,6 +125,7 @@
     // DVD PCM Audio:
     sh_audio->channels=2;
     sh_audio->samplerate=48000;
+    sh_audio->i_bps=2*2*48000;
 //    sh_audio->pcm_bswap=1;
     break;
 }
@@ -138,8 +144,12 @@
   ac3_init();
   sh_audio->ac3_frame = ac3_decode_frame();
   if(sh_audio->ac3_frame){
-    sh_audio->samplerate=((ac3_frame_t*)sh_audio->ac3_frame)->sampling_rate;
+    ac3_frame_t* fr=(ac3_frame_t*)sh_audio->ac3_frame;
+    sh_audio->samplerate=fr->sampling_rate;
     sh_audio->channels=2;
+    // 1 frame: 6*256 samples     1 sec: sh_audio->samplerate samples
+    //sh_audio->i_bps=fr->frame_size*fr->sampling_rate/(6*256);
+    sh_audio->i_bps=fr->bit_rate*(1000/8);
   } else {
     driver=0; // bad frame -> disable audio
   }
@@ -150,6 +160,7 @@
   Gen_aLaw_2_Signed(); // init table
   sh_audio->channels=sh_audio->wf->nChannels;
   sh_audio->samplerate=sh_audio->wf->nSamplesPerSec;
+  sh_audio->i_bps=sh_audio->channels*sh_audio->samplerate;
   break;
 }
 case 6: {
@@ -157,6 +168,10 @@
   GSM_Init();
   sh_audio->channels=sh_audio->wf->nChannels;
   sh_audio->samplerate=sh_audio->wf->nSamplesPerSec;
+  // decodes 65 byte -> 320 short
+  // 1 sec: sh_audio->channels*sh_audio->samplerate  samples
+  // 1 frame: 320 samples
+  sh_audio->i_bps=65*(sh_audio->channels*sh_audio->samplerate)/320;  // 1:10
   break;
 }
 case 1: {
@@ -172,6 +187,7 @@
 //  printf("]\n");
   sh_audio->channels=2; // hack
   sh_audio->samplerate=MP3_samplerate;
+  sh_audio->i_bps=MP3_bitrate*(1000/8);
   break;
 }
 }
@@ -191,9 +207,12 @@
   return driver;
 }
 
-// Audio decoding
+// Audio decoding:
 
-int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int maxlen){
+// Decode a single frame (mp3,acm etc) or 'minlen' bytes (pcm/alaw etc)
+// buffer length is 'maxlen' bytes, it shouldn't be exceeded...
+
+int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen){
     int len=-1;
     switch(sh_audio->codec->driver){
       case 1: // MPEG layer 2 or 3
@@ -201,13 +220,14 @@
         sh_audio->channels=2; // hack
         break;
       case 2: // AVI PCM
-      { len=demux_read_data(sh_audio->ds,buf,OUTBURST);
+      { len=demux_read_data(sh_audio->ds,buf,minlen);
         break;
       }
       case 8: // DVD PCM
       { int j;
-        len=demux_read_data(sh_audio->ds,buf,OUTBURST);
+        len=demux_read_data(sh_audio->ds,buf,minlen);
           //if(i&1){ printf("Warning! pcm_audio_size&1 !=0  (%d)\n",i);i&=~1; }
+          // swap endian:
           for(j=0;j<len;j+=2){
             char x=buf[j];
             buf[j]=buf[j+1];
@@ -216,7 +236,7 @@
         break;
       }
       case 5:  // aLaw decoder
-      { int l=demux_read_data(sh_audio->ds,buf,OUTBURST/2);
+      { int l=demux_read_data(sh_audio->ds,buf,minlen/2);
         unsigned short *d=(unsigned short *) buf;
         unsigned char *s=buf;
         len=2*l;
@@ -228,13 +248,10 @@
       }
       case 6:  // MS-GSM decoder
       { unsigned char buf[65]; // 65 bytes / frame
-            len=0;
-            while(len<OUTBURST){
-                if(demux_read_data(sh_audio->ds,buf,65)!=65) break; // EOF
-                XA_MSGSM_Decoder(buf,(unsigned short *) buf); // decodes 65 byte -> 320 short
-//  		XA_GSM_Decoder(buf,(unsigned short *) &sh_audio->a_buffer[sh_audio->a_buffer_len]); // decodes 33 byte -> 160 short
-                len+=2*320;
-            }
+        if(demux_read_data(sh_audio->ds,buf,65)!=65) break; // EOF
+        XA_MSGSM_Decoder(buf,(unsigned short *) buf); // decodes 65 byte -> 320 short
+//  	    XA_GSM_Decoder(buf,(unsigned short *) &sh_audio->a_buffer[sh_audio->a_buffer_len]); // decodes 33 byte -> 160 short
+        len=2*320;
         break;
       }
       case 3: // AC3 decoder
@@ -249,9 +266,10 @@
         //printf("{3:%d}",avi_header.idx_pos);fflush(stdout);
         break;
       case 4:
-      { len=acm_decode_audio(sh_audio,buf,maxlen);
+        len=acm_decode_audio(sh_audio,buf,maxlen);
+//        len=acm_decode_audio(sh_audio,buf,minlen);
         break;
-      }
+
 #ifdef USE_DIRECTSHOW
       case 7: // DirectShow
       { int ret;
@@ -267,7 +285,8 @@
         }
         DS_AudioDecoder_Convert(sh_audio->a_in_buffer,sh_audio->a_in_buffer_len,
             buf,maxlen, &size_in,&size_out);
-        if(verbose>2)printf("DShow: audio %d -> %d converted  (in_buf_len=%d of %d)\n",size_in,size_out,sh_audio->a_in_buffer_len,sh_audio->a_in_buffer_size);
+        //if(verbose>2)
+        printf("DShow: audio %d -> %d converted  (in_buf_len=%d of %d)  %d\n",size_in,size_out,sh_audio->a_in_buffer_len,sh_audio->a_in_buffer_size,ds_tell_pts(sh_audio->ds));
         if(size_in>=sh_audio->a_in_buffer_len){
           sh_audio->a_in_buffer_len=0;
         } else {