libsent/src/adin/adin_portaudio.c

説明を見る。
00001 
00049 /*
00050  * Copyright (c) 2004-2005 Shikano Lab., Nara Institute of Science and Technology
00051  * Copyright (c) 2005-2006 Julius project team, Nagoya Institute of Technology
00052  * All rights reserved
00053  */
00054 
00055 #include <sent/stddefs.h>
00056 #include <sent/speech.h>
00057 #include <sent/adin.h>
00058 
00059 /* sound header */
00060 #include "pa/portaudio.h"
00061 
00062 
00063 #undef DDEBUG
00064 
00065 /* temporal buffer */
00066 static SP16 *speech;            
00067 static int current;             
00068 static int processed;           
00069 static boolean buffer_overflowed = FALSE; 
00070 static int cycle_buffer_len;    
00071 
00084 static int
00085 Callback(void *inbuf, void *outbuf, unsigned long len, PaTimestamp outTime, void *userdata)
00086 {
00087   SP16 *now;
00088   int avail;
00089   int processed_local;
00090   int written;
00091 
00092   now = inbuf;
00093 
00094   processed_local = processed;
00095 
00096 #ifdef DDEBUG
00097   printf("callback-1: processed=%d, current=%d: recordlen=%d\n", processed_local, current, len);
00098 #endif
00099 
00100   /* check overflow */
00101   if (processed_local > current) {
00102     avail = processed_local - current;
00103   } else {
00104     avail = cycle_buffer_len + processed_local - current;
00105   }
00106   if (len > avail) {
00107 #ifdef DDEBUG
00108     printf("callback-*: buffer overflow!\n");
00109 #endif
00110     buffer_overflowed = TRUE;
00111     len = avail;
00112   }
00113 
00114   /* store to buffer */
00115   if (current + len <= cycle_buffer_len) {
00116     memcpy(&(speech[current]), now, len * sizeof(SP16));
00117 #ifdef DDEBUG
00118     printf("callback-2: [%d..%d] %d samples written\n", current, current+len, len);
00119 #endif
00120   } else {
00121     written = cycle_buffer_len - current;
00122     memcpy(&(speech[current]), now, written * sizeof(SP16));
00123 #ifdef DDEBUG
00124     printf("callback-2-1: [%d..%d] %d samples written\n", current, current+written, written);
00125 #endif
00126     memcpy(&(speech[0]), &(now[written]), (len - written) * sizeof(SP16));
00127 #ifdef DDEBUG
00128     printf("callback-2-2: ->[%d..%d] %d samples written (total %d samples)\n", 0, len-written, len-written, len);
00129 #endif
00130   }
00131   current += len;
00132   if (current >= cycle_buffer_len) current -= cycle_buffer_len;
00133 #ifdef DDEBUG
00134   printf("callback-3: new current: %d\n", current);
00135 #endif
00136 
00137   return(0);
00138 }
00139 
00140 static PortAudioStream *stream;         
00141 
00150 boolean
00151 adin_mic_standby(int sfreq, void *dummy)
00152 {
00153   PaError err;
00154 
00155   /* set cycle buffer length */
00156   cycle_buffer_len = INPUT_DELAY_SEC * sfreq;
00157   j_printerr("Audio cycle buffer length: %d bytes\n", cycle_buffer_len * sizeof(SP16));
00158 
00159   /* for safety... */
00160   if (sizeof(SP16) != paInt16) {
00161     j_error("SP16 != paInt16\n");
00162   }
00163 
00164   /* allocate and init */
00165   current = processed = 0;
00166   speech = (SP16 *)mymalloc(sizeof(SP16) * cycle_buffer_len);
00167   buffer_overflowed = FALSE;
00168 
00169   /* initialize device and open stream */
00170   err = Pa_Initialize();
00171   if (err != paNoError) {
00172     j_printerr("Error: %s\n", Pa_GetErrorText(err));
00173     return(FALSE);
00174   }
00175   
00176   err = Pa_OpenDefaultStream(&stream, 1, 0, paInt16, sfreq, 128, 0, 
00177                              Callback, NULL);
00178   if (err != paNoError) {
00179     j_printerr("Error: %s\n", Pa_GetErrorText(err));
00180     return(FALSE);
00181   }
00182 
00183   return(TRUE);
00184 }
00185 
00191 boolean
00192 adin_mic_start()
00193 {
00194   PaError err;
00195 
00196   /* start stream */
00197   err = Pa_StartStream(stream);
00198   if (err != paNoError) {
00199     j_printerr("Error: %s\n", Pa_GetErrorText(err));
00200     return(FALSE);
00201   }
00202   
00203   return(TRUE);
00204 }
00205 
00211 boolean
00212 adin_mic_stop()
00213 {
00214   PaError err;
00215 
00216   /* stop stream */
00217   err = Pa_StopStream(stream);
00218   if (err != paNoError) {
00219     j_printerr("Error: %s\n", Pa_GetErrorText(err));
00220     return(FALSE);
00221   }
00222   
00223   return TRUE;
00224 }
00225 
00238 int
00239 adin_mic_read(SP16 *buf, int sampnum)
00240 {
00241   int current_local;
00242   int avail;
00243   int len;
00244 
00245   if (buffer_overflowed) {
00246     j_printerr("Error: input buffer OVERFLOW, increase INPUT_DELAY_SEC in sent/speech.h\n");
00247     buffer_overflowed = FALSE;
00248   }
00249 
00250   while (current == processed) {
00251 #ifdef DDEBUG
00252     printf("process  : current == processed: %d: wait\n", current);
00253 #endif
00254     Pa_Sleep(50);               /* wait for 100ms, till some input comes */
00255   }
00256 
00257   current_local = current;
00258 
00259 #ifdef DDEBUG
00260   printf("process-1: processed=%d, current=%d\n", processed, current_local);
00261 #endif
00262 
00263   if (processed < current_local) {
00264     avail = current_local - processed;
00265     if (avail > sampnum) avail = sampnum;
00266     memcpy(buf, &(speech[processed]), avail * sizeof(SP16));
00267 #ifdef DDEBUG
00268     printf("process-2: [%d..%d] %d samples read\n", processed, processed+avail, avail);
00269 #endif
00270     len = avail;
00271     processed += avail;
00272   } else {
00273     avail = cycle_buffer_len - processed;
00274     if (avail > sampnum) avail = sampnum;
00275     memcpy(buf, &(speech[processed]), avail * sizeof(SP16));
00276 #ifdef DDEBUG
00277     printf("process-2-1: [%d..%d] %d samples read\n", processed, processed+avail, avail);
00278 #endif
00279     len = avail;
00280     processed += avail;
00281     if (processed >= cycle_buffer_len) processed -= cycle_buffer_len;
00282     if (sampnum - avail > 0) {
00283       if (sampnum - avail < current_local) {
00284         avail = sampnum - avail;
00285       } else {
00286         avail = current_local;
00287       }
00288       if (avail > 0) {
00289         memcpy(&(buf[len]), &(speech[0]), avail * sizeof(SP16));
00290 #ifdef DDEBUG
00291         printf("process-2-2: [%d..%d] %d samples read (total %d)\n", 0, avail, avail, len + avail);
00292 #endif
00293         len += avail;
00294         processed += avail;
00295         if (processed >= cycle_buffer_len) processed -= cycle_buffer_len;
00296       }
00297     }
00298   }
00299 #ifdef DDEBUG
00300   printf("process-3: new processed: %d\n", processed);
00301 #endif
00302   return len;
00303 }
00304 

Juliusに対してTue Dec 26 16:19:28 2006に生成されました。  doxygen 1.5.0