ofAgingMesh ofApp::createFrequencySpectrumMesh(complex* spectrum, size_t spectrumSize) { ofAgingMesh mesh(1.0f); mesh.setMode(OF_PRIMITIVE_LINE_STRIP); float start = 50.f; float end = windowWidth - 50.f; float increment = (end - start) / spectrumSize; for (size_t i = 0; i < spectrumSize; i++) { float x = start + i * increment; float y = 3 * windowHeight / 4.f - 200.f * ::pow(25 * cmp_abs(spectrum[i]), 0.5); float z = 0.f; mesh.addVertex(ofVec3f(x, y, z)); } return mesh; }
// run appropriate function for opcode in memory void execute_cpu(machine* mch) { uint8_t *opcode = &mch->memory[mch->pc++]; uint8_t *memory = mch->memory; fprintf(stdout, "opcode: %x\n", opcode[0]); switch(*opcode) { case 0x02: exit(123); case 0x12: exit(123); case 0x22: exit(123); case 0x32: exit(123); case 0x42: exit(123); case 0x52: exit(123); case 0x62: exit(123); case 0x72: exit(123); case 0x92: exit(123); case 0xB2: exit(123); case 0xD2: exit(123); case 0xF2: exit(123); case 0xEA: return nop(mch, 1); case 0x1A: return nop(mch, 2); // illegal instruction (nop with 2 cycles) case 0x7A: return nop(mch, 2); // same as above case 0x69: return adc_imm(opcode[1], mch); case 0x65: return adc_zp(opcode[1], mch); case 0x75: return adc_zpx(opcode[1], mch); case 0x6D: return adc_abs(opcode[2], opcode[1], mch); case 0x7D: return adc_absx(opcode[2], opcode[1], mch); case 0x79: return adc_absy(opcode[2], opcode[1], mch); case 0x61: return adc_indx(opcode[2], opcode[1], mch); case 0x71: return adc_indy(opcode[2], opcode[1], mch); case 0x29: return and_imm(opcode[1], mch); case 0x25: return and_zp(opcode[1], mch); case 0x35: return and_zpx(opcode[1], mch); case 0x2D: return and_abs(opcode[2], opcode[1], mch); case 0x3D: return and_absx(opcode[2], opcode[1], mch); case 0x39: return and_absy(opcode[2], opcode[1], mch); case 0x21: return and_indx(opcode[2], opcode[1], mch); case 0x31: return and_indy(opcode[2], opcode[1], mch); case 0x0A: return asl_acc(mch); case 0x06: return asl_zp(opcode[1], mch); case 0x16: return asl_zpx(opcode[1], mch); case 0x0E: return asl_abs(opcode[2], opcode[1], mch); case 0x1E: return asl_absx(opcode[2], opcode[1], mch); case 0x90: return branch_clear(opcode[2], opcode[1], mch, 0b00000001); case 0xB0: return branch_set(opcode[2], opcode[1], mch, 0b00000001); case 0xF0: return branch_set(opcode[2], opcode[1], mch, 0b00000010); case 0x24: return bit_zp(opcode[1], mch); case 0x2C: return bit_abs(opcode[2], opcode[1], mch); case 0x30: return branch_set(opcode[2], opcode[1], mch, 0b10000000); case 0xD0: return branch_clear(opcode[2], opcode[1], mch, 0b00000010); case 0x10: return branch_clear(opcode[2], opcode[1], mch, 0b10000000); case 0x00: return brk(mch); case 0x50: return branch_clear(opcode[2], opcode[1], mch, 0b01000000); case 0x70: return branch_set(opcode[2], opcode[1], mch, 0b01000000); case 0x18: return clc(mch); case 0x58: return cli(mch); case 0xB8: return clv(mch); case 0xC9: return cmp_imm(opcode[1], mch); case 0xC5: return cmp_zp(opcode[1], mch); case 0xD5: return cmp_zpx(opcode[1], mch); case 0xCD: return cmp_abs(opcode[2], opcode[1], mch, 0, 0); case 0xDD: return cmp_abs(opcode[2], opcode[1], mch, 1, mch->X); case 0xD9: return cmp_abs(opcode[2], opcode[1], mch, 1, mch->Y); case 0xC1: return cmp_indy(opcode[2], opcode[1], mch); case 0xD1: return cmp_indx(opcode[2], opcode[1], mch); case 0xE0: return cpx_imm(opcode[1], mch); case 0xE4: return cpx_zp(opcode[1], mch); case 0xEC: return cpx_abs(opcode[2], opcode[1], mch); case 0xC0: return cpy_imm(opcode[1], mch); case 0xC4: return cpy_zp(opcode[1], mch); case 0xCC: return cpy_abs(opcode[2], opcode[1], mch); case 0xC6: return dec_zp(opcode[1], mch); case 0xD6: return dec_zpx(opcode[1], mch); case 0xCE: return dec_abs(opcode[2], opcode[1], mch); case 0xDE: return dec_absx(opcode[2], opcode[1], mch); case 0xCA: return dex(mch); case 0x88: return dey(mch); case 0x49: return eor_imm(opcode[1], mch); case 0x45: return eor_zp(opcode[1], mch); case 0x55: return eor_zpx(opcode[1], mch); case 0x4D: return eor_abs(opcode[2], opcode[1], mch); case 0x5D: return eor_absx(opcode[2], opcode[1], mch); case 0x59: return eor_absy(opcode[2], opcode[1], mch); case 0x41: return eor_indx(opcode[2], opcode[1], mch); case 0x51: return eor_indy(opcode[2], opcode[1], mch); case 0xE6: return inc_zp(opcode[1], mch, 0, 0); case 0xF6: return inc_zp(opcode[1], mch, 1, mch->X); case 0xEE: return inc_abs(opcode[2], opcode[1], mch, 0, 0); case 0xFE: return inc_abs(opcode[2], opcode[1], mch, 1, mch->X); case 0xE8: return inx(mch); case 0xC8: return iny(mch); case 0x4C: return jmp_abs(opcode[2], opcode[1], mch); case 0x6C: return jmp_ind(opcode[2], opcode[1], mch); case 0x20: return jsr(opcode[2], opcode[1], mch); case 0xA9: return lda_imm(opcode[1], mch); case 0xA5: return lda_zp(opcode[1], mch, 0, 0); case 0xB5: return lda_zp(opcode[1], mch, 1, mch->X); case 0xAD: return lda_abs(opcode[2], opcode[1], mch, 0, 0); case 0xBD: return lda_abs(opcode[2], opcode[1], mch, 1, mch->X); case 0xB9: return lda_abs(opcode[2], opcode[1], mch, 1, mch->Y); case 0xA1: return lda_indx(opcode[2], opcode[1], mch); case 0xB1: return lda_indy(opcode[2], opcode[1], mch); case 0xA2: return ldx_imm(opcode[1], mch); case 0xA6: return ldx_zp(opcode[1], mch, 0, 0); case 0xB6: return ldx_zp(opcode[1], mch, 1, mch->X); case 0xAE: return ldx_abs(opcode[2], opcode[1], mch, 0, 0); case 0xBE: return ldx_abs(opcode[2], opcode[1], mch, 1, mch->X); case 0xA0: return ldy_imm(opcode[1], mch); case 0xA4: return ldy_zp(opcode[1], mch, 0, 0); case 0xB4: return ldy_zp(opcode[1], mch, 1, mch->X); case 0xAC: return ldy_abs(opcode[2], opcode[1], mch, 0, 0); case 0xBC: return ldy_abs(opcode[2], opcode[1], mch, 1, mch->X); case 0x4A: return lsr_acc(mch); case 0x46: return lsr_zp(opcode[1], mch); case 0x56: return lsr_zpx(opcode[1], mch); case 0x4E: return lsr_abs(opcode[2], opcode[1], mch); case 0x5E: return lsr_absx(opcode[2], opcode[1], mch); case 0x09: return or_imm(opcode[1], mch); case 0x05: return or_zp(opcode[1], mch); case 0x15: return or_zpx(opcode[1], mch); case 0x0D: return or_abs(opcode[2], opcode[1], mch); case 0x1D: return or_absx(opcode[2], opcode[1], mch); case 0x19: return or_absy(opcode[2], opcode[1], mch); case 0x01: return or_indx(opcode[2], opcode[1], mch); case 0x11: return or_indy(opcode[2], opcode[1], mch); case 0x48: return pha(mch); case 0x08: return php(mch); case 0x68: return pla(mch); case 0x28: return plp(mch); case 0x40: return rti(mch); case 0x60: return rts(mch); case 0x78: return sei(mch); case 0x38: return sec(mch); case 0xAA: return tax(mch); case 0xA8: return tay(mch); case 0x8A: return txa(mch); case 0x98: return tya(mch); default: fprintf(stdout, "unimplemented opcode!\n"); fprintf(stdout, "opcode in question: %x\n", opcode[0]); exit(1); break; } }
//----------------------------------------------------------------------------- // Name: displayFunc( ) // Desc: callback function invoked to draw the client area //----------------------------------------------------------------------------- void displayFunc( ) { static const int LP = 4; static long int count = 0; static char str[1024]; static unsigned int wf = 0; static SAMPLE buffer[LPC_BUFFER_SIZE], residue[LPC_BUFFER_SIZE], coefs[1024], coefs_dct[1024], noise[LPC_BUFFER_SIZE]; float pitch, power, fval; int i; // clear the color and depth buffers glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glPushMatrix( ); // rotate the sphere about y axis glRotatef( g_angle_y += g_inc, 0.0f, 1.0f, 0.0f ); // color waveform glColor3f( 0.4f, 0.4f, 1.0f ); // wait for data while( !g_ready ) #if !defined(__OS_WINDOWS__) usleep( 0 ); #else Sleep( 0 ); #endif // g_mutex.lock(); // get the window //memcpy( buffer, g_audio_buffer, g_buffer_size * sizeof(SAMPLE) ); //memset( g_another_buffer, 0, g_buffer_size * sizeof(SAMPLE) ); // g_mutex.unlock(); sf_readf_float( g_fin, buffer, LPC_BUFFER_SIZE ); memcpy( g_another_buffer, buffer, LPC_BUFFER_SIZE * sizeof(SAMPLE) ); //apply_window( (float*)buffer, g_window, g_buffer_size ); lpc_analyze( g_lpc, buffer, g_buffer_size, coefs, 40, &power, &pitch, residue ); if( !g_ctf ) { lpc_synthesize( g_lpc, g_another_buffer, g_buffer_size, coefs, 40, power, 0 ); } else { // inverse window // dct dct( residue, LPC_BUFFER_SIZE ); lpc_analyze( g_lpc_freq, residue, g_buffer_size, coefs_dct, 10, &power, &pitch, NULL ); for( i = 0; i < LPC_BUFFER_SIZE; i++ ) { noise[i] = 2.0f * (float)rand() / RAND_MAX - 1.0f; noise[i] *= power * 32.0f; } // dct dct( noise, LPC_BUFFER_SIZE ); lpc_synthesize( g_lpc_freq, residue, g_buffer_size, coefs_dct, 10, power, pitch, noise ); // idct idct( residue, LPC_BUFFER_SIZE ); // window? //apply_window( (float *)residue, g_window, g_buffer_size ); lpc_synthesize( g_lpc, g_another_buffer, g_buffer_size, coefs, 40, power, pitch, residue ); memset(residue,0,LPC_BUFFER_SIZE*sizeof(SAMPLE)); } g_ready = FALSE; // apply the window GLfloat x = -1.8f, inc = 3.6f / g_buffer_size, y = 1.0f; // draw the time domain waveform glBegin( GL_LINE_STRIP ); GLint ii = ( g_buffer_size - (g_buffer_size/g_time_view) ) / 2; for( i = ii; i < ii + g_buffer_size / g_time_view; i++ ) { glVertex3f( x, g_gain * g_time_scale * .75f * buffer[i] + y, 0.0f ); x += inc * g_time_view; } glEnd(); // apply the window x = -1.8f, inc = 3.6f / g_buffer_size, y = .5f; glColor3f( 0.4f, 0.8f, 1.0f ); // draw the prediction glBegin( GL_LINE_STRIP ); for( i = ii; i < ii + g_buffer_size / g_time_view; i++ ) { glVertex3f( x, g_gain * g_time_scale * .75f * (buffer[i]-residue[i]) + y, 0.0f ); x += inc * g_time_view; } glEnd(); // apply the window x = -1.8f, inc = 3.6f / g_buffer_size, y = .0f; // draw the residue glColor3f( 0.8f, 0.8f, 0.4f ); glBegin( GL_LINE_STRIP ); for( i = ii; i < ii + g_buffer_size / g_time_view; i++ ) { glVertex3f( x, g_gain * g_time_scale * 5.0f * residue[i] + y, 0.0f ); x += inc * g_time_view; } glEnd(); // apply the window x = -1.8f, inc = 0.3f/g_order, y = -0.5f; // draw the coefficients if( pitch == 0 ) glColor3f( 1.0f, .4f, .4f ); else glColor3f( 1.0f, 1.2f - pitch/g_buffer_size*4.0f, .4f ); glBegin( GL_LINE_STRIP ); for( i = 0; i < g_order; i++ ) { glVertex3f( x, coefs[i] + y, 0.0f ); x += inc * g_time_view; } glEnd(); // fft memcpy( residue, g_another_buffer, LPC_BUFFER_SIZE * sizeof(SAMPLE) ); rfft( (float *)residue, g_buffer_size/2, FFT_FORWARD ); memcpy( buffer, residue, LPC_BUFFER_SIZE * sizeof(SAMPLE) ); x = -1.8f; y = -1.2f; inc = 3.6f / g_buffer_size; complex * cbuf = (complex *)buffer; // color the spectrum glColor3f( 0.4f, 1.0f, 0.4f ); // draw the frequency domain representation glBegin( GL_LINE_STRIP ); for( i = 0; i < g_buffer_size/g_freq_view; i++ ) { g_spectrums[wf][i].x = x; if( !g_usedb ) g_spectrums[wf][i].y = g_gain * g_freq_scale * .7f * ::pow( 25 * cmp_abs( cbuf[i] ), .5 ) + y; else g_spectrums[wf][i].y = g_gain * g_freq_scale * .8f * ( 20.0f * log10( cmp_abs(cbuf[i])/8.0 ) + 80.0f ) / 80.0f + y + .73f; x += inc * g_freq_view; } glEnd(); g_draw[wf] = true; for( i = 0; i < g_depth; i++ ) { if( g_draw[(wf+i)%g_depth] ) { Pt2D * pt = g_spectrums[(wf+i)%g_depth]; fval = (g_depth-i)/(float)g_depth; glColor3f( .4f * fval, 1.0f * fval, .4f * fval ); x = -1.8f; glBegin( GL_LINE_STRIP ); for( int j = 0; j < g_buffer_size/g_freq_view; j++, pt++ ) glVertex3f( x + j*(inc*g_freq_view), pt->y, -i * g_space + g_z ); glEnd(); } } if( !g_wutrfall ) g_draw[wf] = false; wf--; wf %= g_depth; /* for( int i = 0; i < 9; i++ ) fprintf( stderr, "%.4f ", coefs[i] ); fprintf( stderr, "power: %.8f pitch: %.4f\n", power, pitch ); for( int i = 0; i < 9; i++ ) fprintf( stderr, "%.4f ", lpc(i) ); fprintf( stderr, "power: %.8f pitch: %.4f\n", lpc(10), lpc(9) ); fprintf( stderr, "\n" ); */ draw_string( 0.4f, 0.8f, 0.0f, "original", .5f ); draw_string( 0.4f, 0.3f, 0.0f, "predicted", .5f ); draw_string( 0.4f, -.2f, 0.0f, "residue (error)", .5f ); draw_string( -1.8f, -.7f, 0.0f, "coefficients", .5f ); sprintf( str, "pitch factor: %.4f", g_speed ); glColor3f( 0.8f, .4f, .4f ); draw_string( 1.2f, -.25f, 0.0f, str, .35f ); sprintf( str, "LPC order: %i", g_order ); draw_string( 1.2f, -.35f, 0.0f, str, .35f ); SAMPLE sum = 0.0f; for( i = 0; i < g_buffer_size; i++ ) sum += fabs(buffer[i]); glPushMatrix(); if( pitch == 0 ) { glColor3f( 1.0f, .4f, .4f ); glTranslatef( 1.28f, -.45f, 0.0f ); } else { glColor3f( 1.0f, 1.2f - pitch/g_buffer_size*4.0f, .4f ); glTranslatef( 1.55f, -.45f, 0.0f ); } glutSolidSphere( .001f + sum/g_buffer_size * 120.0f, 10, 10 ); glPopMatrix(); draw_string( 1.2f, -.55f, 0.0f, "non-pitch | pitched", .35f ); draw_string( 1.2f, -.65f, 0.0f, g_ctf ? "both" : "time-only", .35f ); glPopMatrix( ); // swap the buffers glFlush( ); glutSwapBuffers( ); g_buffer_count_b++; }
//----------------------------------------------------------------------------- // Name: displayFunc( ) // Desc: callback function invoked to draw the client area //----------------------------------------------------------------------------- void displayFunc( ) { static const int LP = 4; static long int count = 0; static char str[1024]; static unsigned int wf = 0; static SAMPLE buffer[PVC_BUFFER_SIZE]; static SAMPLE buffer2[PVC_BUFFER_SIZE]; static polar_window * win[2] = { NULL, NULL }; static int which = 0; static float _inc = 0.0f; int i; float pitch, power, fval; if( g_freeze ) return; // clear the color and depth buffers glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glPushMatrix( ); // rotate the sphere about y axis glRotatef( g_angle_y += g_inc, 0.0f, 1.0f, 0.0f ); // color waveform glColor3f( 0.4f, 0.4f, 1.0f ); // wait for data while( !g_ready ) #if !defined(__OS_WINDOWS__) usleep( 0 ); #else Sleep( 0 ); #endif // g_mutex.lock(); // get the window memcpy( buffer, g_audio_buffer, g_buffer_size * sizeof(SAMPLE) ); memset( g_another_buffer, 0, g_buffer_size * sizeof(SAMPLE) ); // g_mutex.unlock(); g_ready = FALSE; // analyze buffer pv_analyze( g_pvc, buffer, g_hop_size ); // get phase windows out of queue while( win[which] = pv_deque( g_pvc ) ) { // unwrap phase pv_unwrap_phase( win[which] ); // fix phase using last window and expected hop_size if( g_phase_fix && win[!which] ) pv_phase_fix( win[!which], win[which], g_factor ); // freq shift pv_freq_shift( g_pvc, win[which], g_factor2 ); // ifft pv_unwrap_phase( win[which] ); // overlap/add pv_overlap_add( g_pvc, win[which], (int)(g_hop_size * g_factor + .5f) ); which = !which; // reclaim the window pv_reclaim( g_pvc, win[which] ); } // get buffer pv_synthesize( g_pvc, g_another_buffer ); // apply the window GLfloat x = -1.8f, inc = 3.6f / g_buffer_size, y = 1.0f; //apply_window( (float*)buffer, g_window, g_buffer_size ); // draw the time domain waveform glBegin( GL_LINE_STRIP ); GLint ii = ( g_buffer_size - (g_buffer_size/g_time_view) ) / 2; for( i = ii; i < ii + g_buffer_size / g_time_view; i++ ) { glVertex3f( x, g_gain * g_time_scale * .75f * g_another_buffer[i] + y, 0.0f ); x += inc * g_time_view; } glEnd(); // apply the window x = -1.8f, inc = 3.6f / g_buffer_size, y = .5f; // fft memcpy( buffer, g_another_buffer, g_buffer_size * sizeof(SAMPLE) ); rfft( (float *)buffer, g_buffer_size/2, FFT_FORWARD ); x = -1.8f; y = -1.2f; complex * cbuf = (complex *)buffer; // color the spectrum glColor3f( 0.4f, 1.0f, 0.4f ); // draw the frequency domain representation glBegin( GL_LINE_STRIP ); for( i = 0; i < g_buffer_size/g_freq_view; i++ ) { g_spectrums[wf][i].x = x; if( !g_usedb ) g_spectrums[wf][i].y = g_gain * g_freq_scale * .7f * ::pow( 25 * cmp_abs( cbuf[i] ), .5 ) + y; else g_spectrums[wf][i].y = g_gain * g_freq_scale * .8f * ( 20.0f * log10( cmp_abs(cbuf[i])/8.0 ) + 80.0f ) / 80.0f + y + .73f; x += inc * g_freq_view; } glEnd(); g_draw[wf] = true; for( i = 0; i < g_depth; i++ ) { if( g_draw[(wf+i)%g_depth] ) { Pt2D * pt = g_spectrums[(wf+i)%g_depth]; fval = (g_depth-i)/(float)g_depth; glColor3f( .4f * fval, 1.0f * fval, .4f * fval ); x = -1.8f; glBegin( GL_LINE_STRIP ); for( int j = 0; j < g_buffer_size/g_freq_view; j++, pt++ ) glVertex3f( x + j*(inc*g_freq_view), pt->y, -i * g_space + g_z ); glEnd(); } } if( !g_wutrfall ) g_draw[wf] = false; wf--; wf %= g_depth; // factor sprintf( str, "time-expansion factor: %.2f", g_factor ); draw_string( .5f, 0.2f, 0.0f, str, .45f ); sprintf( str, "frequency-expansion factor: %.2f", g_factor2 ); draw_string( .5f, 0.1f, 0.0f, str, .45f ); sprintf( str, "analysis window: %i", g_window_size ); draw_string( .5f, 0.0f, 0.0f, str, .45f ); sprintf( str, "hop size: %i", g_hop_size ); draw_string( .5f, -0.1f, 0.0f, str, .45f ); sprintf( str, "phase adjustment: %s", g_phase_fix ? "ON" : "OFF" ); draw_string( .5f, -0.2f, 0.0f, str, .45f ); glPushMatrix(); glTranslatef( 1.25f, -0.175f, 0.0f ); if( g_phase_fix ) glColor3f( 1.0f, .7f, .3f ); else glColor3f( .6f, .6f, 1.0f ); glutSolidSphere( g_phase_fix ? .05f + .005f * fabs(sin(_inc)) : .01f, 10, 10 ); glPopMatrix(); sprintf( str, "# delay: %i buffers (%.0f ms)", pv_get_ready_len( g_pvc ), pv_get_ready_len( g_pvc ) * g_buffer_size / 44100.0f * 1000.0f ); draw_string( .5f, -0.4f, 0.0f, str, .45f ); glPopMatrix( ); // swap the buffers glFlush( ); glutSwapBuffers( ); g_buffer_count_b++; _inc += .1f; }
//----------------------------------------------------------------------------- // name: render() // desc: ... //----------------------------------------------------------------------------- t_CKUINT AudicleFaceVMSpace::render( void * data ) { static const int LP = 4; static long int count = 0; static char str[1024]; static unsigned wf = 0; float fval; GLint i; // rotate the sphere about y axis glRotatef( 0.0f, 0.0f, 1.0f, 0.0f ); // color waveform glColor3f( 0.4f, 0.4f, 1.0f ); // wait for data //while( !g_ready ) // usleep( 0 ); // get the window memcpy( g_buffer, g_out_buffer, g_buffer_size * sizeof(SAMPLE) * g_num_channels ); //g_ready = FALSE; SAMPLE * p = g_buffer + g_buffer_size; SAMPLE * p2 = g_buffer + g_num_channels - 1; SAMPLE * a = g_buffer; while( a != p) { *a = *p2; a++; p2 += g_num_channels; } // apply the window GLfloat x = -1.8f, inc = 3.6f / g_buffer_size, y = .7f; if( g_window ) apply_window( g_buffer, g_window, g_buffer_size ); // draw the time domain waveform glBegin( GL_LINE_STRIP ); GLint ii = ( g_buffer_size - (g_buffer_size/g_time_view) ) / 2; for( i = ii; i < ii + g_buffer_size / g_time_view; i++ ) { glVertex3f( x, g_gain * g_time_scale * 1.6 * g_buffer[i] + y, 0.0f ); x += inc * g_time_view; } glEnd(); if( g_changed ) { glColor3f( 1.0 * g_changedf, .5 * g_changedf, .5 * g_changedf ); GLfloat x = -1.8f, inc = 3.6f / g_buffer_size, y = .7f; // draw the time domain waveform glBegin( GL_LINE_STRIP ); GLint ii = ( g_buffer_size - (g_buffer_size/g_time_view) ) / 2; for( i = ii; i < ii + g_buffer_size / g_time_view; i++ ) { glVertex3f( x, g_gain * g_time_scale * .8 * (g_window ? g_window[i] : 1.0 ) + y, 0.0f ); x += inc * g_time_view; } glEnd(); g_changedf -= g_rate; if( g_changedf < 0.0 ) g_changed = FALSE; } static t_CKFLOAT r = 0.0; glPushMatrix(); glPushName( g_id ); glTranslatef( 1.7, 0.0, 0.0 ); glColor3f( 1.0, .8, .5 ); glRotatef( r, 0.0, 0.0, 1.0 ); glutWireSphere( sphere_down ? .06 : .08, 15, 15 ); glPopName(); glPopMatrix(); glPushMatrix(); glPushName( g_id2 ); glTranslatef( 1.45, 0.0, 0.0 ); glColor3f( 1.0, .5, .5 ); glRotatef( r, 0.0, 0.0, 1.0 ); glutWireSphere( sphere_down2 ? .06 : .08, 15, 15 ); glPopName(); glPopMatrix(); r += 1; // fft rfft( g_buffer, g_buffer_size/2, FFT_FORWARD ); x = -1.8f; y = -1.0f; complex * cbuf = (complex *)g_buffer; // draw the frequency domain representation for( i = 0; i < g_buffer_size/2; i++ ) { g_spectrums[wf][i].x = x; if( !g_usedb ) g_spectrums[wf][i].y = g_gain * g_freq_scale * ::pow( (double) 25 * cmp_abs( cbuf[i] ), 0.5 ) + y; else g_spectrums[wf][i].y = g_gain * g_freq_scale * ( 20.0f * log10( cmp_abs(cbuf[i])/8.0 ) + 80.0f ) / 80.0f + y + .5f; x += inc * g_freq_view; } g_draw[wf] = true; glPushMatrix(); glTranslatef( fp[0], fp[1], fp[2] ); for( i = 0; i < g_depth; i++ ) { if( g_draw[(wf+i)%g_depth] ) { Pt2D * pt = g_spectrums[(wf+i)%g_depth]; fval = (g_depth-i)/(float)g_depth; glColor3f( .4f * fval, 1.0f * fval, .4f * fval ); x = -1.8f; glBegin( GL_LINE_STRIP ); for( int j = 0; j < g_buffer_size/g_freq_view; j++, pt++ ) glVertex3f( x + j*(inc*g_freq_view), pt->y, -i * g_space + g_z ); glEnd(); } } glPopMatrix(); if( !g_wutrfall ) g_draw[wf] = false; wf--; wf %= g_depth; return 0; }