Beispiel #1
0
vector<vector<double> > compute(vector<double> sound)
{
    FFT fft;
    vector<vector<double> > res;
    vector<complex<double> > tmp;
    while(sound.size()%SMPLS_PR_BLCK)
        sound.push_back(0);
    for(int i=0;i<sound.size();i+=SMPLS_PR_BLCK)
    {
        vector<complex<double> > t;
        for(int j=0;j<SMPLS_PR_BLCK;j++)
            t.push_back(complex<double>(sound[i+j],0));
        tmp = fft.compute(t);
        vector<double> tmp2;
        for(int i=0;i<tmp.size();i++)
            tmp2.push_back(tmp[i].real());
        res.push_back(transform(tmp2));
    }
    return res;
}
void process(int input_fd, int output_fd) {
    off_t current_offset = 0;
    std::complex<float> *frame_data = NULL;
    std::complex<float> *last_frame_data = NULL;

    size_t count = 0;
    size_t frame_count = 0, hop_factor = 8;

    FFT<float> *ifft = NULL;
    std::complex<float> *ifft_result = NULL;
    int16_t *samples = NULL;
    float scale_factor = 1.0;

    for (;;) {
        BlockSet blkset;
        try {
            blkset.begin_read(input_fd, current_offset);
            delete [] last_frame_data;
            last_frame_data = frame_data;
            frame_data = blkset.load_alloc_block<std::complex<float> >(REPLAY_PVOC_BLOCK, count);

            if (ifft == NULL) {
                ifft = new FFT<float>(count, FFT<float>::INVERSE);
                ifft_result = new std::complex<float>[count];
                samples = new int16_t[count];
                scale_factor = float(count) * float(hop_factor);
            }

        } catch (...) {
            /* 
             * if it bombs out we are probably past end of file but who knows
             * so we just close the output_fd and rethrow. This is really ugly
             * but will make sure that any really bad errors get printed
             * rather than ignored.
             */
            close(input_fd);
            close(output_fd);
            throw;
        }

        /* 
         * phase information is stored as a delta from last_frame_data.
         * If last_frame_data is not NULL, we add the phase values into
         * those in frame_data.
         */
        if (last_frame_data != NULL) {
            for (size_t i = 0; i < count; i++) {
                frame_data[i] = std::polar(
                    std::abs(frame_data[i]),
                    std::arg(frame_data[i]) + std::arg(last_frame_data[i])
                );
            }
        }

        /* 
         * now if frame_count % hop_factor == 0, take the IFFT.
         * This should yield a block of (approximately) original
         * audio data.
         */
        if (frame_count % hop_factor == 0) {
            ifft->compute(ifft_result, frame_data); 

            /* take real part and scale as needed */
            for (size_t i = 0; i < count; i++) {
                samples[i] = std::real(ifft_result[i]) / scale_factor;
            }

            write_all(output_fd, samples, count * sizeof(*samples));
        }

        frame_count++;
        current_offset = blkset.end_offset( );
    }
}