galat****@lists*****
galat****@lists*****
2006年 10月 19日 (木) 12:26:33 JST
Index: gtalk/do_output.c diff -u gtalk/do_output.c:1.19 gtalk/do_output.c:1.20 --- gtalk/do_output.c:1.19 Thu Sep 14 22:01:25 2006 +++ gtalk/do_output.c Thu Oct 19 12:26:33 2006 @@ -8,7 +8,8 @@ /* Keiichi Tokuda, Takayoshi Yoshimura, Heiga Zen */ /* (Nagoya Institute of Technology) */ /* All rights reserved */ - +/* */ +/* $Id: do_output.c,v 1.20 2006/10/19 03:26:33 sako Exp $ */ /* 波形を生成しながらの音声出力処理は pthread を用いて実装されている。 これは AUTO_DA が定義されていれば,組み込まれる。 @@ -39,6 +40,7 @@ void inqSpeakUtt(); void inqSpeakStat(); void do_output_file(char *); +void abort_auto_output(); #ifdef USE_SPLIB #include "do_output_sp.c" @@ -58,6 +60,8 @@ int org_vol, org_channels, org_precision, org_freq; int forced_stereo; #endif /* LINUX */ +int current_pos; +int prev_tell_pos_ms; #ifdef SOLARIS audio_info_t org_data; @@ -113,7 +117,11 @@ short *out; { int i; + int pos, pos_ms, interval_ms; + int samp_rate; + samp_rate = data_type[DTYPE].sample; + // fwrite( out, sizeof(short), leng, adfp); for( i=0; i<leng; ++i ) { fwrite( &(out[i]), sizeof(short), 1, adfp); @@ -121,9 +129,38 @@ if( forced_stereo ) { fwrite( &(out[i]), sizeof(short), 1, adfp); } + + if(current_pos % 128 == 0) { +#ifdef LINUX + count_info info; + + if( ioctl( ADFD, SNDCTL_DSP_GETOPTR, &info ) != -1 ) { + pos = info.bytes / 2; + if( forced_stereo ) { + pos /= 2; + } + } else { + pos = current_pos; + } +#else + pos = current_pos; +#endif + pos_ms = (1000 * pos) / samp_rate; + interval_ms = pos_ms - prev_tell_pos_ms; + + if( slot_Speak_syncinterval > 0 && interval_ms >= slot_Speak_syncinterval ) { + RepMsg("tell Speak.sync = %d\n", pos_ms); + /*prev_tell_pos_ms = pos_ms;*/ + while( prev_tell_pos_ms + slot_Speak_syncinterval <= pos_ms ) { + prev_tell_pos_ms += slot_Speak_syncinterval; + } + } + } + ++current_pos; } write( ADFD, out, 0); fflush( adfp); + } void init_audiodev(dtype) @@ -184,6 +221,8 @@ ioctl(ADFD,AUDIO_SETINFO,&data); #endif /* SOLARIS */ + current_pos = 0; + prev_tell_pos_ms = 0; } void reset_audiodev() @@ -206,6 +245,8 @@ ioctl( ACFD, AUDIO_SETINFO, &org_data); close( ACFD); #endif /* SOLARIS */ + current_pos = 0; + prev_tell_pos_ms = 0; } /*---------------------------------------------------------------------*/ Index: gtalk/do_output_sp.c diff -u gtalk/do_output_sp.c:1.3 gtalk/do_output_sp.c:1.4 --- gtalk/do_output_sp.c:1.3 Sat Sep 2 09:58:09 2006 +++ gtalk/do_output_sp.c Thu Oct 19 12:26:33 2006 @@ -1,18 +1,22 @@ +/* $Id: do_output_sp.c,v 1.4 2006/10/19 03:26:33 sako Exp $ */ #include <sp/spBaseLib.h> #include <sp/spAudioLib.h> #define GTALK_AUDIO_BLOCKSIZE 1024 +#define GTALK_USE_SP_PLUGIN_OUTPUT +int RepMsg(char *, ...); void abort_auto_output(); static volatile spAudio gtalk_sp_audio = NULL; static volatile int gtalk_aborted_flag = 0; - -int in_auto_play; +static volatile long gtalk_prev_tell_pos_ms = 0; /* nonzero value restarts play from beginning on replay */ static int gtalk_replay_init_flag = 0; +int in_auto_play; + void output_speaker(int total) {} void init_output() {} @@ -21,16 +25,28 @@ void set_da_signal() {} -void abort_demanded_output() { - if (gtalk_sp_audio != NULL) { - long position; +static int get_current_pos(spAudio audio) +{ + int pos_ms; + long position; - if (spGetAudioOutputPosition(gtalk_sp_audio, &position) == SP_TRUE) { - talked_DA_msec = (1000 * position) / SAMPLE_RATE; - spDebug(1, "abort_output", + pos_ms = -1; + + if (audio != NULL) { + if (spGetAudioOutputPosition(audio, &position) == SP_TRUE) { + pos_ms = (1000 * position) / SAMPLE_RATE; + spDebug(80, "get_current_pos", "spGetAudioOutputPosition: position = %ld, da_msec = %d, SAMPLE_RATE = %d\n", - position, talked_DA_msec, SAMPLE_RATE); + position, pos_ms, SAMPLE_RATE); } + } + + return pos_ms; +} + +void abort_demanded_output() { + if (gtalk_sp_audio != NULL) { + talked_DA_msec = get_current_pos(gtalk_sp_audio); if (!gtalk_aborted_flag) { spDebug(1, "abort_output", "output aborted\n"); @@ -44,6 +60,32 @@ } +spBool output_pos_func(spAudio audio, spAudioCallbackType call_type, + void *data1, void *data2, void *user_data) +{ + long pos_ms; + long *pos; + long current_interval; + + if (call_type == SP_AUDIO_OUTPUT_POSITION_CALLBACK) { + pos = (long *)data1; + pos_ms = 1000 * (*pos) / SAMPLE_RATE; + current_interval = pos_ms - gtalk_prev_tell_pos_ms; + spDebug(100, "output_pos_func", + "pos = %ld, pos_ms = %ld, slot_Speak_syncinterval = %d, current_interval = %ld\n", + *pos, pos_ms, slot_Speak_syncinterval, current_interval); + + if (slot_Speak_syncinterval > 0 && current_interval >= (long)slot_Speak_syncinterval) { + if (!gtalk_aborted_flag) { + RepMsg("tell Speak.sync = %ld\n", pos_ms); + } + gtalk_prev_tell_pos_ms = pos_ms; + } + } + + return SP_TRUE; +} + static spThreadReturn do_output_thread(void *data) { int total; @@ -55,10 +97,16 @@ total = *(int *)data; + if (in_auto_play && slot_Auto_play_delay > 0) { + spMSleep(slot_Auto_play_delay); + } + if (gtalk_sp_audio == NULL) { gtalk_sp_audio = spInitAudio(); spSetAudioSampleRate(gtalk_sp_audio, (double)SAMPLE_RATE); spSetAudioBufferSize(gtalk_sp_audio, GTALK_AUDIO_BLOCKSIZE); + spSetAudioCallbackFunc(gtalk_sp_audio, SP_AUDIO_OUTPUT_POSITION_CALLBACK, + output_pos_func, NULL); } /* open "write only" mode */ @@ -70,6 +118,8 @@ offset = 0; block_length = GTALK_AUDIO_BLOCKSIZE * sizeof(short); + gtalk_prev_tell_pos_ms = 0; + while (!gtalk_aborted_flag && offset < total) { spDebug(80, "do_output_thread", "offset = %ld, total = %ld\n", offset, total); @@ -79,18 +129,13 @@ offset += block_length; } - if (!gtalk_aborted_flag) { - long position; + spCloseAudioDevice(gtalk_sp_audio); - if (spGetAudioOutputPosition(gtalk_sp_audio, &position) == SP_TRUE) { - talked_DA_msec = (1000 * position) / SAMPLE_RATE; - } + if (!gtalk_aborted_flag) { if ( prop_Speak_len == AutoOutput ) inqSpeakLen(); if ( prop_Speak_utt == AutoOutput ) inqSpeakUtt(); } - spCloseAudioDevice(gtalk_sp_audio); - strcpy( slot_Speak_stat, "IDLE" ); if( prop_Speak_stat == AutoOutput ) inqSpeakStat(); @@ -103,7 +148,7 @@ void do_output_file_sp(char *sfile) { -#if 1 +#ifdef GTALK_USE_SP_PLUGIN_OUTPUT static char o_plugin_name[SP_MAX_LINE]; spPlugin *o_plugin; spWaveInfo wave_info; @@ -132,50 +177,46 @@ return; } -void do_output(char *fn) +void do_output_da() { static int total; - - in_auto_play = 0; + static void *thread = NULL; /*total = SAMPLE_RATE * FRAME_RATE * (totalframe - 1) / 1000;*/ total = wave.nsample; - if(fn == NULL){ - static void *thread = NULL; - talked_DA_msec = -1; - already_talked = 1; + talked_DA_msec = -1; + already_talked = 1; - if (thread != NULL) { - if (gtalk_sp_audio != NULL && gtalk_replay_init_flag) { - spStopAudio(gtalk_sp_audio); - } - - spWaitThread(thread); - spDestroyThread(thread); + if (thread != NULL) { + if (gtalk_sp_audio != NULL && gtalk_replay_init_flag) { + spStopAudio(gtalk_sp_audio); } - spDebug(1, "do_output", "creating thread...\n"); - gtalk_aborted_flag = 0; + spWaitThread(thread); + spDestroyThread(thread); + } + spDebug(1, "do_output_da", "creating thread...\n"); - if ((thread = spCreateThread(0, SP_THREAD_PRIORITY_NORMAL, - do_output_thread, (void *)&total)) == NULL) { - spDebug(1, "do_output", "Can't create audio thread\n"); - return; - } + gtalk_aborted_flag = 0; - spDebug(1, "do_output", "creating thread done\n"); + if ((thread = spCreateThread(0, SP_THREAD_PRIORITY_NORMAL, + do_output_thread, (void *)&total)) == NULL) { + spDebug(1, "do_output", "Can't create audio thread\n"); + return; + } + + spDebug(1, "do_output_da", "creating thread done\n"); +} + +void do_output(char *fn) +{ + in_auto_play = 0; + + if(fn == NULL){ + do_output_da(); } else { -#if 0 - FILE *fp; - - if ((fp = fopen(fn, "wb")) != NULL) { - fwrite(wave.data, sizeof (short), total, fp); - fclose(fp); - } -#else do_output_file_sp( fn ); -#endif } } @@ -197,62 +238,15 @@ --------------------------------------------------------------------*/ #ifdef AUTO_DA - void do_auto_output() { - static int total; - static void *thread = NULL; - - in_auto_play = 1; - - /*total = SAMPLE_RATE * FRAME_RATE * (totalframe - 1) / 1000;*/ - total = wave.nsample; - - talked_DA_msec = -1; - already_talked = 1; - - if (thread != NULL) { - if (gtalk_sp_audio != NULL && gtalk_replay_init_flag) { - spStopAudio(gtalk_sp_audio); - } + in_auto_play = 1; - spWaitThread(thread); - spDestroyThread(thread); - } - spDebug(1, "do_output", "creating thread...\n"); - - gtalk_aborted_flag = 0; - - if ((thread = spCreateThread(0, SP_THREAD_PRIORITY_NORMAL, - do_output_thread, (void *)&total)) == NULL) { - spDebug(1, "do_output", "Can't create audio thread\n"); - return; - } - - spDebug(1, "do_output", "creating thread done\n"); + do_output_da(); } void abort_auto_output() { - if (gtalk_sp_audio != NULL) { - long position; - - if (spGetAudioOutputPosition(gtalk_sp_audio, &position) == SP_TRUE) { - talked_DA_msec = (1000 * position) / SAMPLE_RATE; - spDebug(1, "abort_output", - "spGetAudioOutputPosition: position = %ld, da_msec = %d, SAMPLE_RATE = %d\n", - position, talked_DA_msec, SAMPLE_RATE); - } - - if (!gtalk_aborted_flag) { - spDebug(1, "abort_output", "output aborted\n"); - spStopAudio(gtalk_sp_audio); - gtalk_aborted_flag = 1; - } - - if ( prop_Speak_len == AutoOutput ) inqSpeakLen(); - if ( prop_Speak_utt == AutoOutput ) inqSpeakUtt(); - } - + abort_demanded_output(); } #endif /* AUTO_DA */ Index: gtalk/main.c diff -u gtalk/main.c:1.28 gtalk/main.c:1.29 --- gtalk/main.c:1.28 Fri Oct 13 18:44:44 2006 +++ gtalk/main.c Thu Oct 19 12:26:33 2006 @@ -1,8 +1,10 @@ /* Copyright (c) 2003-2006 */ /* Interactive Speech Technology Consortium (ISTC) */ /* All rights reserved */ - +/* */ /* The code is developed by Yamashita-lab, Ritsumeikan University */ +/* */ +/* $Id: main.c,v 1.29 2006/10/19 03:26:33 sako Exp $ */ #include <stdio.h> #include <stdlib.h> @@ -121,6 +123,7 @@ SlotProp prop_Speak_utt; SlotProp prop_Speak_len; SlotProp prop_Speak_stat; +SlotProp prop_Speak_syncinterval; /* slots */ char slot_Run[20]; @@ -146,6 +149,7 @@ int slot_Log_text; int slot_Log_arranged_text; int slot_Log_sentence; +int slot_Speak_syncinterval; /* chaone */ #ifdef WIN32 @@ -219,6 +223,7 @@ int server_getline ( char *buf, int buf_size ); void server_destroy ( void ); /********↑***********************/ +void SetRun( char *rel, char *val); extern FILE *fp_err; @@ -242,6 +247,7 @@ prop_Speak_utt = AutoOutput; prop_Speak_len = AutoOutput; prop_Speak_stat = AutoOutput; + prop_Speak_syncinterval = AutoOutput; } /* 初期化: プログラム起動時に一度だけ実行 */ @@ -282,6 +288,7 @@ slot_Speech_file[0] = '\0'; slot_Pros_file[0] = '\0'; prosBuf.nPhoneme = 0; + slot_Speak_syncinterval = 1000; } void refresh_prosBuf() @@ -496,6 +503,11 @@ RepMsg( "rep Speak.stat = %s\n", slot_Speak_stat ); } +void inqSpeakSyncinterval() +{ + RepMsg( "rep Speak.syncinterval = %d\n", slot_Speak_syncinterval ); +} + /*---------------------------------------------------------*/ /* set command */ /*---------------------------------------------------------*/ @@ -632,6 +644,20 @@ */ } +void setSpeakSyncinterval( char *rel, char *val ) +{ + int interval; + + if( strcmp(rel,"=")!=0 ) { unknown_com(); return; } + + interval = atoi( val ); + + if( interval >= 0) { + slot_Speak_syncinterval = interval; + if( prop_Speak_syncinterval == AutoOutput ) inqSpeakSyncinterval(); + } +} + /*-------------------*/ void setSave( char *rel, char *filename ) @@ -945,6 +971,7 @@ case S_SpeechFile: setSpeechFile( v_arg[2], v_arg[3] ); break; case S_ProsFile: setProsFile( v_arg[2], v_arg[3] ); break; case S_ParsedText: setParsedText( v_arg[2], v_arg[3] ); break; + case S_Speak_syncinterval: setSpeakSyncinterval( v_arg[2], v_arg[3] ); break; case S_AutoPlay: slot_Auto_play = setLogYesNo( v_arg[2], v_arg[3] ); break; case S_AutoPlayDelay: @@ -997,6 +1024,7 @@ case S_Speak_utt: inqSpeakUtt(); break; case S_Speak_len: inqSpeakLen(); break; case S_Speak_stat: inqSpeakStat(); break; + case S_Speak_syncinterval: inqSpeakSyncinterval(); break; case S_Log: RepMsg( "rep Log = %s\n", slot_Log_file ); break; case S_Log_conf: @@ -1056,6 +1084,7 @@ case S_Speak_utt: prop_Speak_utt = prop; break; case S_Speak_len: prop_Speak_len = prop; break; case S_Speak_stat: prop_Speak_stat = prop; break; + case S_Speak_syncinterval: prop_Speak_syncinterval = prop; break; default: unknown_com(); } Index: gtalk/read_conf.c diff -u gtalk/read_conf.c:1.16 gtalk/read_conf.c:1.17 --- gtalk/read_conf.c:1.16 Sat Sep 2 09:58:09 2006 +++ gtalk/read_conf.c Thu Oct 19 12:26:33 2006 @@ -1,7 +1,8 @@ /* Copyright (c) 2000-2006 */ /* Yamashita Lab., Ritsumeikan University */ /* All rights reserved */ - +/* */ +/* $Id: read_conf.c,v 1.17 2006/10/19 03:26:33 sako Exp $ */ #include <stdio.h> #include <stdlib.h> @@ -99,6 +100,8 @@ } } else if( strcmp(cpara,"AUTO-PLAY-DELAY")==0 ) { slot_Auto_play_delay = atoi( val ); + } else if( strcmp(cpara,"SYNC-INTERVAL")==0 ) { + slot_Speak_syncinterval = atoi( val ); } else if( strcmp(cpara,"SPEAKER-ID")==0 ) { if( n_speaker > 0 ) check_speaker_conf( n_speaker-1 ); speaker[n_speaker].code = malloc_char( val, "speaker.code" ); Index: gtalk/slot.h diff -u gtalk/slot.h:1.14 gtalk/slot.h:1.15 --- gtalk/slot.h:1.14 Sat Sep 2 09:58:09 2006 +++ gtalk/slot.h Thu Oct 19 12:26:33 2006 @@ -1,6 +1,8 @@ /* Copyright (c) 2000-2006 */ /* Yamashita Lab., Ritsumeikan University */ /* All rights reserved */ +/* */ +/* $Id: slot.h,v 1.15 2006/10/19 03:26:33 sako Exp $ */ /* List of Slot */ @@ -22,6 +24,7 @@ #define S_Speak_utt 34 #define S_Speak_len 35 #define S_Speak_stat 36 +#define S_Speak_syncinterval 37 #define S_Save 40 #define S_SpeechFile 41 #define S_SavePros 42 @@ -67,6 +70,7 @@ { S_Speak_utt, "Speak.utt" }, { S_Speak_len, "Speak.len" }, { S_Speak_stat, "Speak.stat" }, + { S_Speak_syncinterval, "Speak.syncinterval" }, { S_Save, "Save" }, { S_SpeechFile, "SpeechFile" }, { S_SavePros, "SavePros" }, @@ -113,6 +117,7 @@ extern SlotProp prop_Speak_utt; extern SlotProp prop_Speak_len; extern SlotProp prop_Speak_stat; +extern SlotProp prop_Speak_syncinterval; /* slots */ @@ -141,3 +146,4 @@ extern int slot_Log_aphrase; extern int slot_Log_breath; extern int slot_Log_sentence; +extern int slot_Speak_syncinterval;