libsent/src/adin/adin_portaudio.c

Go to the documentation of this file.
00001 
00050 /*
00051  * Copyright (c) 2004-2005 Shikano Lab., Nara Institute of Science and Technology
00052  * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology
00053  * All rights reserved
00054  */
00055 
00056 #include <sent/stddefs.h>
00057 #include <sent/speech.h>
00058 #include <sent/adin.h>
00059 
00060 /* sound header */
00061 #include "pa/portaudio.h"
00062 
00063 
00064 #undef DDEBUG
00065 
00072 #define MAX_FRAGMENT_MSEC 128
00073 
00074 /* temporal buffer */
00075 static SP16 *speech;            
00076 static int current;             
00077 static int processed;           
00078 static boolean buffer_overflowed = FALSE; 
00079 static int cycle_buffer_len;    
00080 
00093 static int
00094 Callback(void *inbuf, void *outbuf, unsigned long len, PaTimestamp outTime, void *userdata)
00095 {
00096   SP16 *now;
00097   int avail;
00098   int processed_local;
00099   int written;
00100 
00101   now = inbuf;
00102 
00103   processed_local = processed;
00104 
00105 #ifdef DDEBUG
00106   printf("callback-1: processed=%d, current=%d: recordlen=%d\n", processed_local, current, len);
00107 #endif
00108 
00109   /* check overflow */
00110   if (processed_local > current) {
00111     avail = processed_local - current;
00112   } else {
00113     avail = cycle_buffer_len + processed_local - current;
00114   }
00115   if (len > avail) {
00116 #ifdef DDEBUG
00117     printf("callback-*: buffer overflow!\n");
00118 #endif
00119     buffer_overflowed = TRUE;
00120     len = avail;
00121   }
00122 
00123   /* store to buffer */
00124   if (current + len <= cycle_buffer_len) {
00125     memcpy(&(speech[current]), now, len * sizeof(SP16));
00126 #ifdef DDEBUG
00127     printf("callback-2: [%d..%d] %d samples written\n", current, current+len, len);
00128 #endif
00129   } else {
00130     written = cycle_buffer_len - current;
00131     memcpy(&(speech[current]), now, written * sizeof(SP16));
00132 #ifdef DDEBUG
00133     printf("callback-2-1: [%d..%d] %d samples written\n", current, current+written, written);
00134 #endif
00135     memcpy(&(speech[0]), &(now[written]), (len - written) * sizeof(SP16));
00136 #ifdef DDEBUG
00137     printf("callback-2-2: ->[%d..%d] %d samples written (total %d samples)\n", 0, len-written, len-written, len);
00138 #endif
00139   }
00140   current += len;
00141   if (current >= cycle_buffer_len) current -= cycle_buffer_len;
00142 #ifdef DDEBUG
00143   printf("callback-3: new current: %d\n", current);
00144 #endif
00145 
00146   return(0);
00147 }
00148 
00149 static PortAudioStream *stream;         
00150 
00159 boolean
00160 adin_mic_standby(int sfreq, void *dummy)
00161 {
00162   PaError err;
00163   int frames_per_buffer, num_buffer;
00164   int latency;
00165   char *p;
00166 
00167   /* set cycle buffer length */
00168   cycle_buffer_len = INPUT_DELAY_SEC * sfreq;
00169   jlog("Stat: adin_portaudio: INPUT_DELAY_SEC = %d\n", INPUT_DELAY_SEC);
00170   jlog("Stat: adin_portaudio: audio cycle buffer length = %d bytes\n", cycle_buffer_len * sizeof(SP16));
00171 
00172   /* for safety... */
00173   if (sizeof(SP16) != paInt16) {
00174     jlog("Error: adin_portaudio: SP16 != paInt16 !!\n");
00175     return FALSE;
00176   }
00177 
00178   /* allocate and init */
00179   current = processed = 0;
00180   speech = (SP16 *)mymalloc(sizeof(SP16) * cycle_buffer_len);
00181   buffer_overflowed = FALSE;
00182 
00183   /* set buffer parameter*/
00184   if ((p = getenv("LATENCY_MSEC")) != NULL) {
00185     latency = atoi(p);
00186     jlog("Stat: adin_portaudio: set latency to %d msec (obtained from LATENCY_MSEC)\n", latency);
00187   } else {
00188     latency = MAX_FRAGMENT_MSEC;
00189     jlog("Stat: adin_portaudio: set latency to %d msec\n", latency);
00190   }
00191   frames_per_buffer = 256;
00192   num_buffer = sfreq * latency / (frames_per_buffer * 1000);
00193   jlog("Stat: adin_portaudio: framesPerBuffer=%d, NumBuffers(guess)=%d (%d)\n",
00194            frames_per_buffer, num_buffer, 
00195            Pa_GetMinNumBuffers(frames_per_buffer, sfreq));
00196   jlog("Stat: adin_portaudio: audio I/O Latency = %d msec (data fragment = %d frames)\n",
00197            (frames_per_buffer * num_buffer) * 1000 / sfreq, 
00198            (frames_per_buffer * num_buffer));
00199 
00200   /* initialize device and open stream */
00201   err = Pa_Initialize();
00202   if (err != paNoError) {
00203     jlog("Error: adin_portaudio: failed to initialize: %s\n", Pa_GetErrorText(err));
00204     return(FALSE);
00205   }
00206 
00207   err = Pa_OpenDefaultStream(&stream, 1, 0, paInt16, sfreq, 
00208                              frames_per_buffer, num_buffer, 
00209                              Callback, NULL);
00210   if (err != paNoError) {
00211     jlog("Error: adin_portaudio: error in opening stream: %s\n", Pa_GetErrorText(err));
00212     return(FALSE);
00213   }
00214 
00215   return(TRUE);
00216 }
00217 
00223 boolean
00224 adin_mic_begin()
00225 {
00226   PaError err;
00227 
00228   /* start stream */
00229   err = Pa_StartStream(stream);
00230   if (err != paNoError) {
00231     jlog("Error: adin_portaudio: failed to begin stream: %s\n", Pa_GetErrorText(err));
00232     return(FALSE);
00233   }
00234   
00235   return(TRUE);
00236 }
00237 
00243 boolean
00244 adin_mic_end()
00245 {
00246   PaError err;
00247 
00248   /* stop stream */
00249   err = Pa_StopStream(stream);
00250   if (err != paNoError) {
00251     jlog("Error: adin_portaudio: failed to stop stream: %s\n", Pa_GetErrorText(err));
00252     return(FALSE);
00253   }
00254   
00255   return TRUE;
00256 }
00257 
00270 int
00271 adin_mic_read(SP16 *buf, int sampnum)
00272 {
00273   int current_local;
00274   int avail;
00275   int len;
00276 
00277   if (buffer_overflowed) {
00278     jlog("Error: adin_portaudio: input buffer OVERFLOW, increase INPUT_DELAY_SEC in sent/speech.h\n");
00279     buffer_overflowed = FALSE;
00280   }
00281 
00282   while (current == processed) {
00283 #ifdef DDEBUG
00284     printf("process  : current == processed: %d: wait\n", current);
00285 #endif
00286     Pa_Sleep(30); /* wait till some input comes */
00287   }
00288 
00289   current_local = current;
00290 
00291 #ifdef DDEBUG
00292   printf("process-1: processed=%d, current=%d\n", processed, current_local);
00293 #endif
00294 
00295   if (processed < current_local) {
00296     avail = current_local - processed;
00297     if (avail > sampnum) avail = sampnum;
00298     memcpy(buf, &(speech[processed]), avail * sizeof(SP16));
00299 #ifdef DDEBUG
00300     printf("process-2: [%d..%d] %d samples read\n", processed, processed+avail, avail);
00301 #endif
00302     len = avail;
00303     processed += avail;
00304   } else {
00305     avail = cycle_buffer_len - processed;
00306     if (avail > sampnum) avail = sampnum;
00307     memcpy(buf, &(speech[processed]), avail * sizeof(SP16));
00308 #ifdef DDEBUG
00309     printf("process-2-1: [%d..%d] %d samples read\n", processed, processed+avail, avail);
00310 #endif
00311     len = avail;
00312     processed += avail;
00313     if (processed >= cycle_buffer_len) processed -= cycle_buffer_len;
00314     if (sampnum - avail > 0) {
00315       if (sampnum - avail < current_local) {
00316         avail = sampnum - avail;
00317       } else {
00318         avail = current_local;
00319       }
00320       if (avail > 0) {
00321         memcpy(&(buf[len]), &(speech[0]), avail * sizeof(SP16));
00322 #ifdef DDEBUG
00323         printf("process-2-2: [%d..%d] %d samples read (total %d)\n", 0, avail, avail, len + avail);
00324 #endif
00325         len += avail;
00326         processed += avail;
00327         if (processed >= cycle_buffer_len) processed -= cycle_buffer_len;
00328       }
00329     }
00330   }
00331 #ifdef DDEBUG
00332   printf("process-3: new processed: %d\n", processed);
00333 #endif
00334   return len;
00335 }
00336 

Generated on Tue Dec 18 15:59:54 2007 for Julius by  doxygen 1.5.4