#include namespace Emulator { #include "stream.cpp" Audio audio; auto Audio::reset(maybe channels_, maybe frequency_) -> void { if(channels_) channels = channels_(); if(frequency_) frequency = frequency_(); streams.reset(); reverb.reset(); reverb.resize(channels); for(auto c : range(channels)) { reverb[c].resize(7); reverb[c][0].resize(1229); reverb[c][1].resize(1559); reverb[c][2].resize(1907); reverb[c][3].resize(4057); reverb[c][4].resize(8117); reverb[c][5].resize(8311); reverb[c][6].resize(9931); } } auto Audio::setInterface(Interface* interface) -> void { this->interface = interface; } auto Audio::setVolume(double volume) -> void { this->volume = volume; } auto Audio::setBalance(double balance) -> void { this->balance = balance; } auto Audio::setReverb(bool enabled) -> void { this->reverbEnable = enabled; } auto Audio::createStream(uint channels, double frequency) -> shared_pointer { shared_pointer stream = new Stream; stream->reset(channels, frequency, this->frequency); streams.append(stream); return stream; } auto Audio::process() -> void { while(true) { for(auto& stream : streams) { if(!stream->pending()) return; } double samples[channels] = {0}; for(auto& stream : streams) { double buffer[16]; uint length = stream->read(buffer), offset = 0; for(auto c : range(channels)) { samples[c] += buffer[offset]; if(++offset >= length) offset = 0; } } for(auto c : range(channels)) { samples[c] = max(-1.0, min(+1.0, samples[c] * volume)); if(reverbEnable) { samples[c] *= 0.125; for(auto n : range(7)) samples[c] += 0.125 * reverb[c][n].last(); for(auto n : range(7)) reverb[c][n].write(samples[c]); samples[c] *= 8.000; } } if(channels == 2) { if(balance < 0.0) samples[1] *= 1.0 + balance; if(balance > 0.0) samples[0] *= 1.0 - balance; } interface->audioSample(samples, channels); } } }