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); } }
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()); }
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; } }
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)) {} }