예제 #1
0
    void sndfile_read_thread(void)
    {
        nova::name_thread("sndfile reader");
        assert(input_file);

        const size_t frames_per_tick = get_audio_blocksize();
        sized_array<sample_type, aligned_allocator<sample_type> > data_to_read(input_channels * frames_per_tick, 0.f);

        for (;;) {
            if (unlikely(reader_running.load(std::memory_order_acquire) == false))
                return;

            if (read_position < (size_t)input_file.frames())
            {
                size_t frames = input_file.frames() - read_position;
                if (frames > frames_per_tick)
                    frames = frames_per_tick;

                input_file.readf(data_to_read.c_array(), frames);
                read_position += frames;

                const size_t item_to_enqueue = input_channels * frames;
                size_t remaining = item_to_enqueue;

                do {
                    remaining -= read_frames.push(data_to_read.c_array(), remaining);
                } while(remaining);
                read_semaphore.post();
            }
            else
                reader_running.store(false, std::memory_order_release);
        }
    }
예제 #2
0
void nova_server::prepare_backend(void)
{
    /* register audio backend ports */
    const int blocksize = get_audio_blocksize();
    const int input_channels = get_input_count();
    const int output_channels = get_output_count();

    std::vector<sample*> inputs, outputs;
    for (int channel = 0; channel != input_channels; ++channel)
        inputs.push_back(sc_factory->world.mAudioBus + (blocksize * (output_channels + channel)));

    audio_backend::input_mapping(inputs.begin(), inputs.end());

    for (int channel = 0; channel != output_channels; ++channel)
        outputs.push_back(sc_factory->world.mAudioBus + blocksize * channel);

    audio_backend::output_mapping(outputs.begin(), outputs.end());

#ifdef __SSE__
    /* denormal handling */
    _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
    _mm_setcsr(_mm_getcsr() | 0x40);
#endif

    time_per_tick = time_tag::from_samples(blocksize, get_samplerate());
}
예제 #3
0
    void sndfile_write_thread(void)
    {
        const size_t frames_per_tick = get_audio_blocksize();
        sized_array<sample_type, aligned_allocator<sample_type> > data_to_write(output_channels * frames_per_tick, 0.f);

        for (;;) {
            write_semaphore.wait();
            for (;;) {
                size_t dequeued = write_frames.pop(data_to_write.c_array(), data_to_write.size());

                if (dequeued == 0)
                    break;
                output_file.write(data_to_write.c_array(), dequeued);
            }
            if (unlikely(writer_running.load(boost::memory_order_acquire) == false))
                return;
        }

    }
예제 #4
0
    void sndfile_write_thread(void)
    {
        nova::name_thread("sndfile writer");

        const size_t frames_per_tick = get_audio_blocksize();
        const size_t deque_per_tick  = output_channels * frames_per_tick * 64;
        aligned_storage_ptr<sample_type> data_to_write(deque_per_tick);

        size_t pending_samples = 0;

        for (;;) {
            write_semaphore.wait();
            poll_writer_queue(data_to_write.get(), deque_per_tick, pending_samples);
            if (unlikely(writer_running.load(std::memory_order_acquire) == false))
                break;
        }

        while (poll_writer_queue(data_to_write.get(), deque_per_tick, pending_samples))
        {}
    }