/** * Try to read @a sampnum samples and returns actual sample num recorded. * * @param buf [out] samples obtained in this function * @param sampnum [in] wanted number of samples to be read * * @return actural number of read samples, -1 if EOF, -2 if error. */ int adin_file_read(SP16 *buf, int sampnum) { FILE *fp; int cnt; fp = gfp; if (wav_p) { cnt = fread(buf, sizeof(SP16), sampnum, fp); if (cnt == 0) { if (feof(fp)) return -1; /* EOF */ if (ferror(fp)) { jlog("Error: adin_file: an error occured while reading file\n"); adin_file_close(); return -2; /* error */ } } if (nowlen + cnt > maxlen) { cnt = maxlen - nowlen; } nowlen += cnt; } else { if (has_pre) { buf[0] = pre_data[0]; buf[1] = pre_data[1]; has_pre = FALSE; cnt = fread(&(buf[2]), sizeof(SP16), sampnum - 2, fp); if (cnt == 0) { if (feof(fp)) return -1; /* EOF */ if (ferror(fp)) { jlog("Error: adin_file: an error occured file reading file\n"); adin_file_close(); return -2; /* error */ } } cnt += 2; } else { cnt = fread(buf, sizeof(SP16), sampnum, fp); if (cnt == 0) { if (feof(fp)) return -1; /* EOF */ if (ferror(fp)) { jlog("Error: adin_file: an error occured file reading file\n"); adin_file_close(); return -2; /* error */ } } } } /* all .wav data are in little endian */ /* assume .raw data are in big endian */ #ifdef WORDS_BIGENDIAN if (wav_p) swap_sample_bytes(buf, cnt); #else if (!wav_p) swap_sample_bytes(buf, cnt); #endif return cnt; }
/** * Write waveform data in big endian to a file descriptor * * @param fd [in] file descriptor * @param buf [in] array of speech data * @param len [in] length of above * * @return number of bytes written, -1 on error. */ int wrsamp(int fd, SP16 *buf, int len) { int ret; #ifndef WORDS_BIGENDIAN /* swap byte order to BIG ENDIAN */ swap_sample_bytes(buf, len); #endif ret = write(fd, buf, len * sizeof(SP16)); #ifndef WORDS_BIGENDIAN /* undo byte swap */ swap_sample_bytes(buf, len); #endif return(ret); }
/** * Try to read @a sampnum samples and returns actual sample num recorded. * * @param buf [out] samples obtained in this function * @param sampnum [in] wanted number of samples to be read * * @return actural number of read samples, -1 if EOF, -2 if error. */ int adin_stdin_read(SP16 *buf, int sampnum) { int cnt; if (wav_p) { cnt = fread(buf, sizeof(SP16), sampnum, stdin); if (cnt == 0) { if (feof(stdin)) return -1; /* EOF */ if (ferror(stdin)) { jlog("Error: adin_stdin: an error occured while reading stdin\n"); return -2; /* error */ } } } else { if (has_pre) { buf[0] = pre_data[0]; buf[1] = pre_data[1]; has_pre = FALSE; cnt = fread(&(buf[2]), sizeof(SP16), sampnum - 2, stdin); if (cnt == 0) { if (feof(stdin)) return -1; /* EOF */ if (ferror(stdin)) { jlog("Error: adin_stdin: an error occured while reading stdin\n"); return -2; /* error */ } } cnt += 2; } else { cnt = fread(buf, sizeof(SP16), sampnum, stdin); if (cnt == 0) { if (feof(stdin)) return -1; /* EOF */ if (ferror(stdin)) { jlog("Error: adin_stdin: an error occured while reading stdin\n"); return -2; /* error */ } } } } /* all .wav data are in little endian */ /* assume .raw data are in big endian */ #ifdef WORDS_BIGENDIAN if (wav_p) swap_sample_bytes(buf, cnt); #else if (!wav_p) swap_sample_bytes(buf, cnt); #endif return cnt; }
/** * @brief Read samples from device * * Try to read @a sampnum samples and returns actual number of recorded * samples currently available. This function will block until at least one * sample can be obtained. * * @param buf [out] samples obtained in this function * @param sampnum [in] wanted number of samples to be read * * @return actural number of read samples, -2 if error. */ int adin_mic_read(SP16 *buf, int sampnum) { int size,cnt; audio_buf_info info; /* wait till at least one sample can be read */ poll(fds, 1, POLLINTERVAL); /* get actual sample num in the device buffer */ if (ioctl(audio_fd, SNDCTL_DSP_GETISPACE, &info) == -1) { jlog("Error: adin_freebsd: adin_mic_read: sndctl_dsp_getispace"); return(-2); } /* get them as much as possible */ size = sampnum * sizeof(SP16); if (size > info.bytes) size = info.bytes; cnt = read(audio_fd, buf, size); if ( cnt < 0 ) { jlog("Error: adin_freebsd: adin_mic_read: read error\n"); return ( -2 ); } cnt /= sizeof(short); if (need_swap) swap_sample_bytes(buf, cnt); return(cnt); }
/** * @brief Read samples from device * * Try to read @a sampnum samples and returns actual number of recorded * samples currently available. This function will block at most * MAXPOLLINTERVAL msec, until at least one sample can be obtained. * If no data has been obtained after waiting for MAXPOLLINTERVAL msec, * returns 0. * * When stereo input, only left channel will be used. * * @param buf [out] samples obtained in this function * @param sampnum [in] wanted number of samples to be read * * @return actural number of read samples, 0 of no sample has been captured in * MAXPOLLINTERVAL msec, -2 if error. */ int adin_oss_read(SP16 *buf, int sampnum) { #ifndef HAS_OSS return -2; #else int size,cnt,i; audio_buf_info info; fd_set rfds; struct timeval tv; int status; /* check for incoming samples in device buffer */ /* if there is at least one sample fragment, go next */ /* if not exist, wait for the data to come for at most MAXPOLLINTERVAL msec */ /* if no sample fragment has come in the MAXPOLLINTERVAL period, go next */ FD_ZERO(&rfds); FD_SET(audio_fd, &rfds); tv.tv_sec = 0; tv.tv_usec = MAXPOLLINTERVAL * 1000; status = select(audio_fd+1, &rfds, NULL, NULL, &tv); if (status < 0) { /* select() failed */ jlog("Error: adin_oss: failed to poll device\n"); return(-2); /* error */ } if (FD_ISSET(audio_fd, &rfds)) { /* has some data */ /* get sample num that can be read without blocking */ if (ioctl(audio_fd, SNDCTL_DSP_GETISPACE, &info) == -1) { jlog("Error: adin_oss: failed to get number of samples in the buffer\n"); return(-2); } /* get them as much as possible */ size = sampnum * sizeof(SP16); if (size > info.bytes) size = info.bytes; if (size < frag_size) size = frag_size; size &= ~ 1; /* Force 16bit alignment */ cnt = read(audio_fd, buf, size); if ( cnt < 0 ) { jlog("Error: adin_oss: failed to read samples\n"); return ( -2 ); } cnt /= sizeof(short); if (stereo_rec) { /* remove R channel */ for(i=1;i<cnt;i+=2) buf[(i-1)/2]=buf[i]; cnt/=2; } if (need_swap) swap_sample_bytes(buf, cnt); } else { /* no data after waiting */ jlog("Warning: adin_oss: no data fragment after %d msec?\n", MAXPOLLINTERVAL); cnt = 0; } return(cnt); #endif /* HAS_OSS */ }
/** * @brief Read samples from NetAudio port. * * Try to read @a sampnum samples and returns actual number of recorded * samples currently available. This function will block until * at least some samples are obtained. * * @param buf [out] samples obtained in this function * @param sampnum [in] wanted number of samples to be read * * @return actural number of read samples, -1 if an error occured. */ int NA_read(SP16 *buf, int sampnum) { int cnt; cnt = NARead(port, (char *)buf, sampnum * sizeof(SP16)) / sizeof(SP16); if (need_swap) swap_sample_bytes(buf, cnt); return(cnt); }
/** * <JA> * 読み込んだサンプル列をソケットデスクリプタ "fd" 上のadinnetサーバに送信 * するコールバック関数 * * @param now [in] 録音されたサンプル列 * @param len [in] 長さ(サンプル数) * * @return エラー時 -1,処理成功時 0,処理成功+区間終端検出時 1 を返す. * </JA> * <EN> * Callback handler to record the sample fragments to adinnet server * pointed by the socket descriptor "fd". * * @param now [in] recorded fragments of speech sample * @param len [in] length of above in samples * * @return -1 on device error (require caller to exit and terminate input), * 0 on success (allow caller to continue), * 1 on succeeded but segmentation detected (require caller to exit but * input will continue in the next call. * </EN> */ static int adin_callback_adinnet(SP16 *now, int len, Recog *recog) { int count; int start, w; int i; start = 0; if (recog->jconf->input.speech_input == SP_MIC && speechlen == 0) { /* this is first up-trigger */ if (rewind_msec > 0 && !recog->adin->is_valid_data) { /* not spoken currently but has data to process at first trigger */ /* it means that there are old spoken segments */ /* disgard them */ printf("disgard already recorded %d samples\n", len); return 0; } /* erase "<<<please speak>>>" text on tty */ fprintf(stderr, "\r \r"); if (rewind_msec > 0) { /* when -rewind value set larger than 0, the speech data spoken while pause will be considered back to the specified msec. */ printf("buffered samples=%d\n", len); w = rewind_msec * sfreq / 1000; if (len > w) { start = len - w; len = w; } else { start = 0; } printf("will process from %d\n", start); } } #ifdef WORDS_BIGENDIAN swap_sample_bytes(&(now[start]), len); #endif for (i=0;i<adinnet_servnum;i++) { count = wt(sd[i], (char *)&(now[start]), len * sizeof(SP16)); if (count < 0) { perror("adintool: cannot write"); fprintf(stderr, "failed to send data to %s:%d\n", adinnet_serv[i], adinnet_port[i]); } } #ifdef WORDS_BIGENDIAN swap_sample_bytes(&(now[start]), len); #endif /* accumulate sample num of this segment */ speechlen += len; #ifdef HAVE_PTHREAD if (recog->adin->enable_thread) { /* if input length reaches limit, rehash the ad-in buffer */ if (recog->adin->speechlen > MAXSPEECHLEN - 16000) { recog->adin->rehash = TRUE; fprintf(stderr, "+"); } } #endif /* display progress in dots */ fprintf(stderr, "."); return(0); }