//////////////////////////////////////////////////////////////// // 音声合成を開始します。 // 引数: mode 音声合成のモードを指定します // b2 F: 分析フレーム BIT // F=0 10ms/フレーム // F=1 20ms/フレーム // b1-0 S: 発声速度 BIT // S=00: NORMAL SPEED // S=01: SLOW SPEED // S=10: FAST SPEED // 返値: int エラーコード //////////////////////////////////////////////////////////////// int cD7752::Start( int mode ) { const static int frame_size[8] = { 100, // 10ms, NORMAL 120, // 10ms, SLOW 80, // 10ms, FAST 100, // PROHIBITED 200, // 20ms, NORMAL 240, // 20ms, SLOW 160, // 20ms, FAST 200, // PROHIBITED }; // フィルタパラメータの初期値 const static int f_default[5] = { 126, 64, 121, 111, 96 }; const static int b_default[5] = { 9, 4, 9, 9, 11 }; // パラメータ変数の初期化 FrameSize = frame_size[mode & 7]; for( int i=0; i<5; i++ ){ Y[i][0] = 0; Y[i][1] = 0; Coef.f[i] = I2F( f_default[i] ); Coef.b[i] = I2F( b_default[i] ); } PitchCount = 0; Coef.amp = 0; Coef.pitch = I2F( 30 ); return D7752_ERR_SUCCESS; }
K find(K a, K b) { I at=a->t, an=a->n, bt=b->t; P(at>0,DOE) if(-4==at && 4==bt)DO(an, if(kS(a)[i]==*kS(b))R Ki(i)) if(-3==at && 3==bt)DO(an, if(kC(a)[i]==*kC(b))R Ki(i)) if(-2==at && 2==bt)DO(an, if(!FC(kF(a)[i],*kF(b)))R Ki(i)) if(-2==at && 1==bt){F fb=I2F(*kI(b));DO(an, if(!FC(kF(a)[i],fb))R Ki(i));}
void bx_virt_timer_c::timer_handler(void) { if(!virtual_timers_realtime) { Bit64u temp_final_time = bx_pc_system.time_usec(); temp_final_time -= current_virtual_time; while (temp_final_time) { if((temp_final_time)>(virtual_next_event_time)) { temp_final_time -= virtual_next_event_time; advance_virtual_time(virtual_next_event_time); } else { advance_virtual_time(temp_final_time); temp_final_time -= temp_final_time; } } bx_pc_system.activate_timer(system_timer_id, (Bit32u)BX_MIN(0x7FFFFFFF,(virtual_next_event_time>2)?(virtual_next_event_time-2):1), 0); return; } Bit64u usec_delta = bx_pc_system.time_usec()-last_usec; if (usec_delta) { #if BX_HAVE_REALTIME_USEC Bit64u ticks_delta = 0; Bit64u real_time_delta = GET_VIRT_REALTIME64_USEC() - last_real_time - real_time_delay; Bit64u real_time_total = real_time_delta + total_real_usec; Bit64u system_time_delta = (Bit64u)usec_delta + (Bit64u)stored_delta; if(real_time_delta) { last_realtime_delta = real_time_delta; last_realtime_ticks = total_ticks; } ticks_per_second = USEC_PER_SECOND; //Start out with the number of ticks we would like // to have to line up with real time. ticks_delta = real_time_total - total_ticks; if(real_time_total < total_ticks) { //This slows us down if we're already ahead. // probably only an issue on startup, but it solves some problems. ticks_delta = 0; } if(ticks_delta + total_ticks - last_realtime_ticks > (F2I(MAX_MULT * I2F(last_realtime_delta)))) { //This keeps us from going too fast in relation to real time. #if 0 ticks_delta = (F2I(MAX_MULT * I2F(last_realtime_delta))) + last_realtime_ticks - total_ticks; #endif ticks_per_second = F2I(MAX_MULT * I2F(USEC_PER_SECOND)); } if(ticks_delta > system_time_delta * USEC_PER_SECOND / MIN_USEC_PER_SECOND) { //This keeps us from having too few instructions between ticks. ticks_delta = system_time_delta * USEC_PER_SECOND / MIN_USEC_PER_SECOND; } if(ticks_delta > virtual_next_event_time) { //This keeps us from missing ticks. ticks_delta = virtual_next_event_time; } if(ticks_delta) { # if DEBUG_REALTIME_WITH_PRINTF //Every second print some info. if(((last_real_time + real_time_delta) / USEC_PER_SECOND) > (last_real_time / USEC_PER_SECOND)) { Bit64u temp1, temp2, temp3, temp4; temp1 = (Bit64u) total_real_usec; temp2 = (total_real_usec); temp3 = (Bit64u)total_ticks; temp4 = (Bit64u)((total_real_usec) - total_ticks); printf("useconds: " FMT_LL "u, ", temp1); printf("expect ticks: " FMT_LL "u, ", temp2); printf("ticks: " FMT_LL "u, ", temp3); printf("diff: "FMT_LL "u\n", temp4); } # endif last_real_time += real_time_delta; total_real_usec += real_time_delta; last_system_usec += system_time_delta; stored_delta = 0; total_ticks += ticks_delta; } else { stored_delta = system_time_delta; } Bit64u a = usec_per_second, b; if(real_time_delta) { //FIXME Bit64u em_realtime_delta = last_system_usec + stored_delta - em_last_realtime; b=((Bit64u)USEC_PER_SECOND * em_realtime_delta / real_time_delta); em_last_realtime = last_system_usec + stored_delta; } else { b=a; } usec_per_second = ALPHA_LOWER(a,b); #else BX_ASSERT(0); #endif #if BX_HAVE_REALTIME_USEC advance_virtual_time(ticks_delta); #endif } last_usec=last_usec + usec_delta; bx_pc_system.deactivate_timer(system_timer_id); BX_ASSERT(virtual_next_event_time); bx_pc_system.activate_timer(system_timer_id, (Bit32u)BX_MIN(0x7FFFFFFF,BX_MAX(1,TICKS_TO_USEC(virtual_next_event_time))), 0); }
//////////////////////////////////////////////////////////////// // 1フレーム分の音声を合成します。 // 引数: frame 合成した波形データの格納先。1フレーム分の個数 // 返値: int エラーコード //////////////////////////////////////////////////////////////// int cD7752::Synth( BYTE *param, D7752_SAMPLE *frame ) { int vu; int qmag; D7752Coef *curr; D7752Coef incr, next; if( !param || !frame ) return D7752_ERR_PARAM; curr = &Coef; // まず、パラメータを係数に展開する qmag = (param[0] & 4) != 0 ? 1 : 0; for( int i=0; i<5; i++ ){ int f = (param[i+1] >> 3) & 31; if( f & 16 ) f -= 32; next.f[i] = curr->f[i] + I2F( f << qmag ); int b = param[i+1] & 7; if( b & 4 ) b -= 8; next.b[i] = curr->b[i] + I2F( b << qmag ); } next.amp = I2F( ( param[6] >> 4 ) & 15 ); int p = param[6] & 7; if( p & 4 ) p -= 8; next.pitch = curr->pitch + I2F(p); // 線形補完用の増分値の計算 incr.amp = ( next.amp - curr->amp ) / FrameSize; incr.pitch = ( next.pitch - curr->pitch ) / FrameSize; for( int i=0; i<5; i++ ){ incr.b[i] = ( next.b[i] - curr->b[i] ) / FrameSize; incr.f[i] = ( next.f[i] - curr->f[i] ) / FrameSize; } // インパルス・ノイズの発生有無をチェック vu = param[0] & 1 ? 1 : 2; vu |= param[6] & 4 ? 3 : 0; // 合成する for( int i=0; i<FrameSize; i++ ){ int y = 0; // インパルス発生 int c = F2I( curr->pitch ); if( PitchCount > (c > 0 ? c : 128) ){ if( vu & 1 ) y = amp_table[F2I(curr->amp)] * 16 - 1; PitchCount = 0; } PitchCount++; // ノイズ発生 if( vu & 2 ) if( rand() & 1 ) y += amp_table[F2I(curr->amp)] * 4 - 1; // XXX ノイズ詳細不明 // 謎のディジタルフィルタ for( int j=0; j<5; j++ ){ int t; t = Y[j][0] * iir1[ F2I( curr->f[j] ) & 0x7f ] / 8192; y += t * iir1[(F2I( curr->b[j] ) * 2 + 1) & 0x7f] / 8192; y -= Y[j][1] * iir2[ F2I( curr->b[j] ) & 0x3f ] / 8192; y = y > 8191 ? 8191 : y < -8192 ? -8192 : y; Y[j][1] = Y[j][0]; Y[j][0] = y; } // データを保存 *frame++ = y; // パラメータを増分 curr->amp += incr.amp; curr->pitch += incr.pitch; for( int j=0; j<5; j++ ){ curr->b[j] += incr.b[j]; curr->f[j] += incr.f[j]; } } // パラメータをシフトする memcpy( curr, &next, sizeof(D7752Coef) ); return D7752_ERR_SUCCESS; }
void GLSpaceObject::render(){ glFrontFace(GL_CW); glutSolidTeapot(I2F(size)); glFrontFace(GL_CCW); }