Beispiel #1
0
void ReplayBuffer::read_blockset(timecode_t frame, BlockSet &blkset) {
    off_t base_offset;
    base_offset = index->get_frame_location(frame);
    blkset.begin_read(fd, base_offset);
}
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( );
    }
}