/* HTS106_Audio_open: open audio device */ static void HTS106_Audio_open(HTS106_Audio * audio, int sampling_rate, int max_buff_size) { if (audio->sampling_rate == sampling_rate && audio->max_buff_size == max_buff_size) return; HTS106_Audio_close(audio); audio->sampling_rate = sampling_rate; audio->max_buff_size = max_buff_size; if (audio->max_buff_size <= 0) return; audio->err = Pa_Initialize(); if (audio->err != paNoError) HTS106_error(0, "hts_engine: Failed to initialize your output audio device to play waveform.\n"); audio->parameters.device = Pa_GetDefaultOutputDevice(); audio->parameters.channelCount = 1; audio->parameters.sampleFormat = paInt16; audio->parameters.suggestedLatency = Pa_GetDeviceInfo(audio->parameters.device)->defaultLowOutputLatency; audio->parameters.hostApiSpecificStreamInfo = NULL; audio->err = Pa_OpenStream(&audio->stream, NULL, &audio->parameters, sampling_rate, max_buff_size, paClipOff, NULL, NULL); if (audio->err != paNoError) HTS106_error(0, "hts_engine: Failed to open your output audio device to play waveform.\n"); audio->err = Pa_StartStream(audio->stream); if (audio->err != paNoError) HTS106_error(0, "hts_engine: Failed to start your output audio device to play waveform.\n"); audio->buff = (short *) HTS106_calloc(max_buff_size, sizeof(short)); audio->buff_size = 0; }
/* HTS106_Audio_close: close audio device */ static void HTS106_Audio_close(HTS106_Audio * audio) { MMRESULT error; if (audio->max_buff_size <= 0) return; /* stop audio */ error = waveOutReset(audio->hwaveout); if (error != MMSYSERR_NOERROR) HTS106_error(0, "hts_engine: Cannot stop and reset your output audio device.\n"); /* unprepare */ error = waveOutUnprepareHeader(audio->hwaveout, &(audio->buff_1), sizeof(WAVEHDR)); if (error != MMSYSERR_NOERROR) HTS106_error(0, "hts_engine: Cannot cleanup the audio datablocks to play waveform.\n"); error = waveOutUnprepareHeader(audio->hwaveout, &(audio->buff_2), sizeof(WAVEHDR)); if (error != MMSYSERR_NOERROR) HTS106_error(0, "hts_engine: Cannot cleanup the audio datablocks to play waveform.\n"); /* close */ error = waveOutClose(audio->hwaveout); if (error != MMSYSERR_NOERROR) HTS106_error(0, "hts_engine: Failed to close your output audio device.\n"); HTS106_free(audio->buff_1.lpData); HTS106_free(audio->buff_2.lpData); HTS106_free(audio->buff); }
/* HTS106_Audio_open: open audio device */ static void HTS106_Audio_open(HTS106_Audio * audio, int sampling_rate, int max_buff_size) { MMRESULT error; if (audio->sampling_rate == sampling_rate && audio->max_buff_size == max_buff_size) return; HTS106_Audio_close(audio); audio->sampling_rate = sampling_rate; audio->max_buff_size = max_buff_size; if (audio->max_buff_size <= 0) return; /* queue */ audio->which_buff = 1; audio->now_buff_1 = FALSE; audio->now_buff_2 = FALSE; audio->buff = (short *) HTS106_calloc(max_buff_size, sizeof(short)); /* format */ audio->waveformatex.wFormatTag = WAVE_FORMAT_PCM; audio->waveformatex.nChannels = AUDIO_CHANNEL; audio->waveformatex.nSamplesPerSec = sampling_rate; audio->waveformatex.wBitsPerSample = sizeof(short) * 8; audio->waveformatex.nBlockAlign = AUDIO_CHANNEL * audio->waveformatex.wBitsPerSample / 8; audio->waveformatex.nAvgBytesPerSec = sampling_rate * audio->waveformatex.nBlockAlign; /* open */ error = waveOutOpen(&audio->hwaveout, WAVE_MAPPER, &audio->waveformatex, (DWORD) HTS106_Audio_callback_function, (DWORD) audio, CALLBACK_FUNCTION); if (error != MMSYSERR_NOERROR) HTS106_error(0, "hts_engine: Failed to open your output audio device to play waveform.\n"); /* prepare */ audio->buff_1.lpData = (LPSTR) HTS106_calloc(max_buff_size, sizeof(short)); audio->buff_1.dwBufferLength = max_buff_size * sizeof(short); audio->buff_1.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; audio->buff_1.dwLoops = 1; audio->buff_1.lpNext = 0; audio->buff_1.reserved = 0; error = waveOutPrepareHeader(audio->hwaveout, &(audio->buff_1), sizeof(WAVEHDR)); if (error != MMSYSERR_NOERROR) HTS106_error(0, "hts_engine: Cannot initialize audio datablocks to play waveform.\n"); audio->buff_2.lpData = (LPSTR) HTS106_calloc(max_buff_size, sizeof(short)); audio->buff_2.dwBufferLength = max_buff_size * sizeof(short); audio->buff_2.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; audio->buff_2.dwLoops = 1; audio->buff_2.lpNext = 0; audio->buff_2.reserved = 0; error = waveOutPrepareHeader(audio->hwaveout, &(audio->buff_2), sizeof(WAVEHDR)); if (error != MMSYSERR_NOERROR) HTS106_error(0, "hts_engine: Cannot initialize audio datablocks to play waveform.\n"); }
/* HTS106_Audio_write_buffer: send buffer to audio device */ static void HTS106_Audio_write_buffer(HTS106_Audio * audio) { MMRESULT error; if (audio->which_buff == 1) { while (audio->now_buff_1 == TRUE) Sleep(AUDIO_WAIT_BUFF_MS); audio->now_buff_1 = TRUE; audio->which_buff = 2; memcpy(audio->buff_1.lpData, audio->buff, audio->buff_size * sizeof(short)); audio->buff_1.dwBufferLength = audio->buff_size * sizeof(short); error = waveOutWrite(audio->hwaveout, &(audio->buff_1), sizeof(WAVEHDR)); } else { while (audio->now_buff_2 == TRUE) Sleep(AUDIO_WAIT_BUFF_MS); audio->now_buff_2 = TRUE; audio->which_buff = 1; memcpy(audio->buff_2.lpData, audio->buff, audio->buff_size * sizeof(short)); audio->buff_2.dwBufferLength = audio->buff_size * sizeof(short); error = waveOutWrite(audio->hwaveout, &(audio->buff_2), sizeof(WAVEHDR)); } if (error != MMSYSERR_NOERROR) HTS106_error(0, "hts_engine: Cannot send datablocks to your output audio device to play waveform.\n"); }
/* HTS106_Audio_flush: flush remain data */ void HTS106_Audio_flush(HTS106_Audio * audio) { if (audio->buff_size > 0) { audio->err = Pa_WriteStream(audio->stream, audio->buff, audio->buff_size); if (audio->err != paNoError && audio->err != paOutputUnderflowed) HTS106_error(0, "hts_engine: Cannot send datablocks to your output audio device to play waveform.\n"); audio->buff_size = 0; } }
/* HTS106_Audio_write: send data to audio device */ void HTS106_Audio_write(HTS106_Audio * audio, short data) { audio->buff[audio->buff_size++] = data; if (audio->buff_size >= audio->max_buff_size) { audio->err = Pa_WriteStream(audio->stream, audio->buff, audio->max_buff_size); if (audio->err != paNoError && audio->err != paOutputUnderflowed) HTS106_error(0, "hts_engine: Cannot send datablocks to your output audio device to play waveform.\n"); audio->buff_size = 0; } }
/* HTS106_Audio_close: close audio device */ static void HTS106_Audio_close(HTS106_Audio * audio) { if (audio->max_buff_size <= 0) return; if (audio->buff_size > 0) { audio->err = Pa_WriteStream(audio->stream, audio->buff, audio->buff_size); if (audio->err != paNoError && audio->err != paOutputUnderflowed) HTS106_error(0, "hts_engine: Cannot send datablocks to your output audio device to play waveform.\n"); audio->buff_size = 0; } HTS106_free(audio->buff); audio->err = Pa_StopStream(audio->stream); if (audio->err != paNoError) HTS106_error(0, "hts_engine: Cannot stop your output audio device.\n"); audio->err = Pa_CloseStream(audio->stream); if (audio->err != paNoError) HTS106_error(0, "hts_engine: Failed to close your output audio device.\n"); Pa_Terminate(); }
// HTS106_set_duration: set duration from state duration probability distribution double mHTS106_set_duration( int * duration, double * mean, double * vari, int size, double frame_length ) { int i, j; double temp1, temp2; double rho = 0.0; int sum = 0; int target_length; // if the frame length is not specified, only the mean vector is used if( frame_length == 0.0 ) { for( i = 0; i < size; i++ ) { duration[i] = ( int )( mean[i] + 0.5 ); if( duration[i] < 1 ) duration[i] = 1; sum += duration[i]; } return( double )sum; } // get the target frame length target_length = ( int )( frame_length + 0.5 ); // check the specified duration if( target_length <= size ) { if( target_length < size ) HTS106_error( -1,( char * )"HTS106_set_duration: Specified frame length is too short.\n" ); for( i = 0; i < size; i++ ) duration[i] = 1; return( double )size; } // RHO calculation temp1 = 0.0; temp2 = 0.0; for( i = 0; i < size; i++ ) { temp1 += mean[i]; temp2 += vari[i]; } rho = ( ( double )target_length - temp1 )/ temp2; // first estimation for( i = 0; i < size; i++ ) { duration[i] = ( int )( mean[i] + rho * vari[i] + 0.5 ); if( duration[i] < 1 ) duration[i] = 1; sum += duration[i]; } // loop estimation while( target_length != sum ) { // search flexible state and modify its duration if( target_length > sum ) { j = -1; for( i = 0; i < size; i++ ) { temp2 = abs( rho -( ( double )duration[i] + 1 - mean[i] )/ vari[i] ); if( j < 0 || temp1 < temp2 ) { j = i; temp1 = temp2; } } sum++; duration[j]++; } else { j = -1; for( i = 0; i < size; i++ ) { if( duration[i] > 1 ) { temp2 = abs( rho -( ( double )duration[i] - 1 - mean[i] )/ vari[i] ); if( j < 0 || temp1 < temp2 ) { j = i; temp1 = temp2; } } } sum--; duration[j]--; } } return( double )target_length; }