int lpc_encoder (uint16_t idx, u_char *state, sample *in, coded_unit *out) { assert(idx < LPC_NUM_FORMATS); assert(in); assert(out); UNUSED(idx); UNUSED(state); out->state = NULL; out->state_len = 0; out->data = (u_char*)block_alloc(LPCTXSIZE); out->data_len = LPCTXSIZE; lpc_analyze((const short*)in, (lpc_encstate_t*)state, (lpc_txstate_t*)out->data); return out->data_len; }
//----------------------------------------------------------------------------- // 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++; }