Example #1
0
/*
 * Apply the MDCT to input samples to generate frequency coefficients.
 * This applies the KBD window and normalizes the input to reduce precision
 * loss due to fixed-point calculations.
 */
static void apply_mdct(AC3EncodeContext *s)
{
    int blk, ch;

    for (ch = 0; ch < s->channels; ch++) {
        for (blk = 0; blk < s->num_blocks; blk++) {
            AC3Block *block = &s->blocks[blk];
            const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE];

#if CONFIG_AC3ENC_FLOAT
            apply_window(&s->fdsp, s->windowed_samples, input_samples,
                         s->mdct_window, AC3_WINDOW_SIZE);
#else
            apply_window(&s->dsp, s->windowed_samples, input_samples,
                         s->mdct_window, AC3_WINDOW_SIZE);
#endif

            if (s->fixed_point)
                block->coeff_shift[ch+1] = normalize_samples(s);

            s->mdct.mdct_calcw(&s->mdct, block->mdct_coef[ch+1],
                               s->windowed_samples);
        }
    }
}
Example #2
0
/**
 * Hybrid window filtering, see blocks 36 and 49 of the G.728 specification.
 *
 * @param order   filter order
 * @param n       input length
 * @param non_rec number of non-recursive samples
 * @param out     filter output
 * @param hist    pointer to the input history of the filter
 * @param out     pointer to the non-recursive part of the output
 * @param out2    pointer to the recursive part of the output
 * @param window  pointer to the windowing function table
 */
static void do_hybrid_window(int order, int n, int non_rec, float *out,
                             float *hist, float *out2, const float *window)
{
    int i;
#ifndef _MSC_VER
    float buffer1[order + 1];
    float buffer2[order + 1];
    float work[order + n + non_rec];
#else
    float *buffer1 = av_malloc_items(order + 1, float);
    float *buffer2 = av_malloc_items(order + 1, float);
    float *work = av_malloc_items(order + n + non_rec, float);
#endif

    apply_window(work, window, hist, order + n + non_rec);

    convolve(buffer1, work + order    , n      , order);
    convolve(buffer2, work + order + n, non_rec, order);

    for (i=0; i <= order; i++) {
        out2[i] = out2[i] * 0.5625 + buffer1[i];
        out [i] = out2[i]          + buffer2[i];
    }

    /* Multiply by the white noise correcting factor (WNCF). */
    *out *= 257./256.;

#ifdef _MSC_VER
	av_free(buffer1);
	av_free(buffer2);
	av_free(work);
#endif
}
Example #3
0
/**
 * Hybrid window filtering, see blocks 36 and 49 of the G.728 specification.
 *
 * @param order   filter order
 * @param n       input length
 * @param non_rec number of non-recursive samples
 * @param out     filter output
 * @param hist    pointer to the input history of the filter
 * @param out     pointer to the non-recursive part of the output
 * @param out2    pointer to the recursive part of the output
 * @param window  pointer to the windowing function table
 */
static void do_hybrid_window(int order, int n, int non_rec, float *out,
                             float *hist, float *out2, const float *window)
{
    int i;
    #if __STDC_VERSION__ >= 199901L
    float buffer1[order + 1];
    float buffer2[order + 1];
    float work[order + n + non_rec];
    #else
    float *buffer1=(float *)alloca((order + 1)*sizeof(float));
    float *buffer2=(float *)alloca((order + 1)*sizeof(float));
    float *work=(float *)alloca((order + n + non_rec)*sizeof(float));
    #endif

    apply_window(work, window, hist, order + n + non_rec);

    convolve(buffer1, work + order    , n      , order);
    convolve(buffer2, work + order + n, non_rec, order);

    for (i=0; i <= order; i++) {
        out2[i] = out2[i] * 0.5625 + buffer1[i];
        out [i] = out2[i]          + buffer2[i];
    }

    /* Multiply by the white noise correcting factor (WNCF). */
    *out *= 257./256.;
}
Example #4
0
/**
 * Backward synthesis filter, find the LPC coefficients from past speech data.
 */
static void backward_filter(float *hist, float *rec, const float *window,
                            float *lpc, const float *tab,
                            int order, int n, int non_rec, int move_size)
{
    float temp[order+1];

    do_hybrid_window(order, n, non_rec, temp, hist, rec, window);

    if (!compute_lpc_coefs(temp, order, lpc, 0, 1, 1))
        apply_window(lpc, lpc, tab, order);

    memmove(hist, hist + n, move_size*sizeof(*hist));
}
static void apply_window_mp3(float *in, float *win, int *unused, float *out,
                             int incr)
{
	LOCAL_ALIGNED_16(float, suma, [17]);
	LOCAL_ALIGNED_16(float, sumb, [17]);
	LOCAL_ALIGNED_16(float, sumc, [17]);
	LOCAL_ALIGNED_16(float, sumd, [17]);

	float sum;
	int j;
	float *out2 = out + 32 * incr;

	/* copy to avoid wrap */
	memcpy(in + 512, in, 32 * sizeof(*in));

	apply_window(in + 16, win     , win + 512, suma, sumc, 16);
	apply_window(in + 32, win + 48, win + 640, sumb, sumd, 16);

	SUM8(MLSS, suma[0], win + 32, in + 48);

	sumc[ 0] = 0;
	sumb[16] = 0;
	sumd[16] = 0;

	out[0  ]  = suma[   0];
	out += incr;
	out2 -= incr;
	for(j=1; j<16; j++)
	{
		*out  =  suma[   j] - sumd[16-j];
		*out2 = -sumb[16-j] - sumc[   j];
		out  += incr;
		out2 -= incr;
	}

	sum = 0;
	SUM8(MLSS, sum, win + 16 + 32, in + 32);
	*out = sum;
}
Example #6
0
/**
 * Backward synthesis filter, find the LPC coefficients from past speech data.
 */
static void backward_filter(float *hist, float *rec, const float *window,
                            float *lpc, const float *tab,
                            int order, int n, int non_rec, int move_size)
{
    #if __STDC_VERSION__ >= 199901L
    float temp[order+1];
    #else
    float *temp = _alloca((order + 1) * sizeof(float));
    #endif

    do_hybrid_window(order, n, non_rec, temp, hist, rec, window);

    if (!compute_lpc_coefs(temp, order, lpc, 0, 1, 1))
        apply_window(lpc, lpc, tab, order);

    memmove(hist, hist + n, move_size*sizeof(*hist));
}
Example #7
0
/**
 * Backward synthesis filter, find the LPC coefficients from past speech data.
 */
static void backward_filter(float *hist, float *rec, const float *window,
                            float *lpc, const float *tab,
                            int order, int n, int non_rec, int move_size)
{
#ifndef _MSC_VER
    float temp[order+1];
#else
	float *temp = av_malloc_items(order + 1, float);
#endif

    do_hybrid_window(order, n, non_rec, temp, hist, rec, window);

    if (!compute_lpc_coefs(temp, order, lpc, 0, 1, 1))
        apply_window(lpc, lpc, tab, order);

    memmove(hist, hist + n, move_size*sizeof(*hist));
#ifdef _MSC_VER
	av_free(temp);
#endif
}
Example #8
0
/**
 * Hybrid window filtering, see blocks 36 and 49 of the G.728 specification.
 *
 * @param order   filter order
 * @param n       input length
 * @param non_rec number of non-recursive samples
 * @param out     filter output
 * @param hist    pointer to the input history of the filter
 * @param out     pointer to the non-recursive part of the output
 * @param out2    pointer to the recursive part of the output
 * @param window  pointer to the windowing function table
 */
static void do_hybrid_window(int order, int n, int non_rec, float *out,
                             float *hist, float *out2, const float *window)
{
    int i;
    float buffer1[order + 1];
    float buffer2[order + 1];
    float work[order + n + non_rec];

    apply_window(work, window, hist, order + n + non_rec);

    convolve(buffer1, work + order    , n      , order);
    convolve(buffer2, work + order + n, non_rec, order);

    for (i=0; i <= order; i++) {
        out2[i] = out2[i] * 0.5625 + buffer1[i];
        out [i] = out2[i]          + buffer2[i];
    }

    /* Multiply by the white noise correcting factor (WNCF). */
    *out *= 257./256.;
}
void Visualizer::Update()
{
    static float input_wave[512];
	float fft_tmp[512];

    unsigned int buffer_pos = 0;

	for (int i = 0; i < 256; i++)
	{
		//Clear the buffers
		fft_tmp[i] = 0;

		//Decay previous values
		fft[i] = fft[i] * (((float)decay) / 100.0f);
	}

    unsigned int nextPacketSize = 1;
    unsigned int flags;

    while(nextPacketSize > 0 )
    {
        float *buf;
        pAudioCaptureClient->GetBuffer((BYTE**)&buf, &nextPacketSize, (DWORD *)&flags, NULL, NULL);
        
        for (int i = 0; i < nextPacketSize; i+=4)
        {
            for (int j = 0; j < 255; j++)
            {
                input_wave[2 * j] = input_wave[2 * (j + 1)];
                input_wave[(2 * j) + 1] = input_wave[2 * j];
            }
            input_wave[510] = buf[i] * 2.0f * amplitude;
            input_wave[511] = input_wave[510];
        }

        buffer_pos += nextPacketSize/4;
        pAudioCaptureClient->ReleaseBuffer(nextPacketSize);
    }

    memcpy(fft_tmp, input_wave, sizeof(input_wave));

	//Apply selected window
	switch (window_mode)
	{
	case 0:
		break;

	case 1:
		apply_window(fft_tmp, win_hanning, 256);
		break;

	case 2:
		apply_window(fft_tmp, win_hamming, 256);
		break;

	case 3:
		apply_window(fft_tmp, win_blackman, 256);
		break;

	default:
		break;
	}

	//Run the FFT calculation
	rfft(fft_tmp, 256, 1);

	fft_tmp[0] = fft_tmp[2];

	apply_window(fft_tmp, fft_nrml, 256);

	//Compute FFT magnitude
	for (int i = 0; i < 128; i += 2)
	{
		float fftmag;

		//Compute magnitude from real and imaginary components of FFT and apply simple LPF
		fftmag = (float)sqrt((fft_tmp[i] * fft_tmp[i]) + (fft_tmp[i + 1] * fft_tmp[i + 1]));

        //Apply a slight logarithmic filter to minimize noise from very low amplitude frequencies
        fftmag = ( 0.5f * log10(1.1f * fftmag) ) + ( 0.9f * fftmag );

		//Limit FFT magnitude to 1.0
		if (fftmag > 1.0f)
		{
			fftmag = 1.0f;
		}

		//Update to new values only if greater than previous values
		if (fftmag > fft[i*2])
		{
			fft[i*2] = fftmag;;
		}

		//Prevent from going negative
		if (fft[i*2] < 0.0f)
		{
			fft[i*2] = 0.0f;
		}

		//Set odd indexes to match their corresponding even index, as the FFT input array uses two indices for one value (real+imaginary)
		fft[(i * 2) + 1] = fft[i * 2];
        fft[(i * 2) + 2] = fft[i * 2];
        fft[(i * 2) + 3] = fft[i * 2];
	}

    if (avg_mode == 0)
    {
        //Apply averaging over given number of values
        int k;
        float sum1 = 0;
        float sum2 = 0;
        for (k = 0; k < avg_size; k++)
        {
            sum1 += fft[k];
            sum2 += fft[255 - k];
        }
        //Compute averages for end bars
        sum1 = sum1 / k;
        sum2 = sum2 / k;
        for (k = 0; k < avg_size; k++)
        {
            fft[k] = sum1;
            fft[255 - k] = sum2;
        }
        for (int i = 0; i < (256 - avg_size); i += avg_size)
        {
        	float sum = 0;
        	for (int j = 0; j < avg_size; j += 1)
        	{
        		sum += fft[i + j];
        	}

        	float avg = sum / avg_size;

        	for (int j = 0; j < avg_size; j += 1)
        	{
        		fft[i + j] = avg;
        	}
        }
    }
    else if(avg_mode == 1)
    {
        for (int i = 0; i < avg_size; i++)
        {
            float sum1 = 0;
            float sum2 = 0;
            int j;
            for (j = 0; j <= i + avg_size; j++)
            {
                sum1 += fft[j];
                sum2 += fft[255 - j];
            }
            fft[i] = sum1 / j;
            fft[255 - i] = sum2 / j;
        }
        for (int i = avg_size; i < 256 - avg_size; i++)
        {
            float sum = 0;
            for (int j = 1; j <= avg_size; j++)
            {
                sum += fft[i - j];
                sum += fft[i + j];
            }
            sum += fft[i];

            fft[i] = sum / (2 * avg_size + 1);
        }
    }
}
Example #10
0
//-----------------------------------------------------------------------------
// name: fft_bandpass()
// desc: bandpass filter the samples x - pass through frequencies between
//       bandStart * nyquist and bandEnd * nyquist unharmed, smoothly sloping down
//       the amplitudes of frequencies outside the passband to 0 over
//       rolloff * nyquist hz.
//-----------------------------------------------------------------------------
void fft_bandpass( Frame * x, float bandStart, float bandEnd, float rolloff )
{
    float *window = 0;
    int winsize = -1;

    int i;

    // not sure why we have at least 4 "pi" variables floating around
    // (#define PIE, #define PI, float PI earlier in this file, double pi local to functions)
    // got to combine them all some time. 
    // double pi = 4.*atan(1.0); 
    
    // make and apply hanning window
    if( winsize != x->wlen ){
        winsize = x->wlen;
        if(window)
            delete[] window;
  
        window = new float[winsize];
        hanning( window, winsize );
    }
    
    apply_window( x->waveform, window, x->wlen );

    // fft
    rfft( x->waveform, x->len, FFT_FORWARD );
    BirdBrain::scale_fft( x->waveform, x->wlen, x->wlen, x->wsize );
    x->cmp2pol();

    // the core
    int rollWidth = (int)(rolloff * (float)x->len);
    int startIndex = (int)(bandStart * (float)x->len);
    int endIndex = (int)(bandEnd * (float)x->len);
    int lTail = startIndex - rollWidth;
    int rTail = endIndex + rollWidth;
    for(i = 0; i < lTail; i++){
        x->pol[i].mag = 0;
    }
    for(i = lTail > 0 ? lTail : 0; i < startIndex; i++){
        x->pol[i].mag *= 0.5 *
            (1 + cos(((float)(startIndex - i)) * PIE / (float)rollWidth));
    }
    for(i = endIndex; (i < rTail) && (i < x->len); i++){
        x->pol[i].mag *= 0.5 *
            (1 + cos(((float)(i - endIndex)) * PIE / (float)rollWidth));
    } 
    for(i = rTail; i < x->len; i++){
        x->pol[i].mag = 0;
    }
  
    x->pol2cmp();
    
    // inverse fft
    rfft( x->waveform, x->len, FFT_INVERSE);
   
    // inverse window!
    hanning( window, winsize );
    for(i = 0; i < winsize; i++){
        if(window[i] < 0.15)
            window[i] = 0.15f;
            window[i] = 1 / window[i];
    }
    apply_window( x->waveform, window, x->wlen );
    if( window )
        delete[] window;
}
Example #11
0
File: Ola.cpp Project: alltom/taps
int OlaRandom::WriteSoundFile( char filename[], float * data, int datasize )
{
	if( m_winsize != datasize )
	{
		hanna( m_window, datasize );
		m_winsize = datasize;
	}
	apply_window( data, m_window, datasize );
	/*int hopsize = segsize / 2; //m_last_buffer_size / 2; //m_last_buffer_size - datasize / 2;
	if( hopsize < 0 )
		hopsize = 0;

	BirdBrain::ola( m_ola_buffer, data, hopsize, datasize );
	m_last_buffer_size = datasize;
	
	// reset data and datasize for writing
	memcpy( data, m_ola_buffer, sizeof(float) * hopsize );
	datasize = hopsize;	*/

	if( !m_top )
		m_hopsize = m_last_buffer_size / 2;
	//fprintf( stderr, "hop: %d\n", m_hopsize );
	m_top = !m_top;
	memcpy( m_swap_buffer, m_ola_buffer, sizeof(float) * m_hopsize );	
	BirdBrain::ola( m_ola_buffer, data, m_hopsize, OLAR_BIG_BUFFER_SIZE, datasize );
	m_last_buffer_size = datasize;
	memcpy( data, m_swap_buffer, sizeof(float) * m_hopsize ); 
	datasize = m_hopsize; 

    // data will always fit in one buffer because buffer size = max tree size (CUTOFF)
    if( this->write_to_buffer )
    {
        while( m_data_count >= m_max_data_count ) {
			BB_log( BB_LOG_FINE, "Background: waiting for empty buffer" );
			usleep( 2000 );
		}
		// used to be if ... return 0;

        // set #samples for the write buffer
        if( m_buffer_samples[m_write_index] != 0 )
		{
			BB_log( BB_LOG_WARNING, "Background: overwriting!" );
		}
		m_buffer_samples[m_write_index] = datasize;

		// set the buffer to write
		float * next_buffer = m_big_buffer[m_write_index++];
        m_write_index %= m_max_data_count;

        // copy the data
        memcpy( next_buffer, data, datasize * sizeof(float) );

        // increment data count
        m_data_count++;

/*		fprintf( stderr, "+ " );
		for( int i = 0; i < m_max_data_count; i++ )
			fprintf( stderr, "%d	", m_buffer_samples[i] );
		fprintf( stderr, "(%d)\n", datasize );
*/	}
    
    // if it's also writing to buffer, it doesn't get here until after the write succeeds
    // so the same data should not be written more than once to the file
	int itemswritten = 0;
    if( this->write_to_file )
    {
        if( !sfwrite ) {
            writeinfo = readinfo;
			sfwrite = sf_open( filename, SFM_RDWR, &writeinfo );

			if( !sfwrite )
			{
				std::cerr << "OlaRandom::WriteSoundFile : cannot open file '" << filename << "', quitting" << std::endl;
				//char x[256];
				//std::cin.getline( x, 256 );
				//exit(1);
                return 2;
			}
		}
		sf_seek( sfwrite, writeinfo.frames, SEEK_SET );
		itemswritten = sf_write_float( sfwrite, data, datasize );
		if( itemswritten <= 0 ) {
			std::cerr << "OlaRandom::WriteSoundFile : cannot write to file '" << filename << "'" << std::endl;
			std::cerr << "needed to write " << datasize << " samples" << std::endl;

            //char x[256];
			//std::cin.getline( x, 256 );
			//exit(3);
            return 2;
        }
		sf_close( sfwrite );
		sfwrite = NULL;
    }
    
    // wrote something
	if( this->write_to_file )
		return itemswritten;
	else
		return datasize;
}
Example #12
0
//-----------------------------------------------------------------------------
// 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;
}