00001
00049
00050
00051
00052
00053
00054
00055 #include <sent/stddefs.h>
00056 #include <sent/speech.h>
00057 #include <sent/adin.h>
00058
00059
00060 #include "pa/portaudio.h"
00061
00062
00063 #undef DDEBUG
00064
00065
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
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
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
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
00160 if (sizeof(SP16) != paInt16) {
00161 j_error("SP16 != paInt16\n");
00162 }
00163
00164
00165 current = processed = 0;
00166 speech = (SP16 *)mymalloc(sizeof(SP16) * cycle_buffer_len);
00167 buffer_overflowed = FALSE;
00168
00169
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
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
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);
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