00001
00050
00051
00052
00053
00054
00055
00056 #include <sent/stddefs.h>
00057 #include <sent/speech.h>
00058 #include <sent/adin.h>
00059
00060
00061 #include "pa/portaudio.h"
00062
00063
00064 #undef DDEBUG
00065
00072 #define MAX_FRAGMENT_MSEC 128
00073
00074
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
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
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
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
00173 if (sizeof(SP16) != paInt16) {
00174 jlog("Error: adin_portaudio: SP16 != paInt16 !!\n");
00175 return FALSE;
00176 }
00177
00178
00179 current = processed = 0;
00180 speech = (SP16 *)mymalloc(sizeof(SP16) * cycle_buffer_len);
00181 buffer_overflowed = FALSE;
00182
00183
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
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
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
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);
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