#include namespace audio { std::map streams; float registerMonoStream(dsp::stream* stream, std::string name, std::string vfoName, int (*sampleRateChangeHandler)(void* ctx, float sampleRate), void* ctx) { AudioStream_t* astr = new AudioStream_t; astr->type = STREAM_TYPE_MONO; astr->ctx = ctx; astr->audio = new io::AudioSink; astr->audio->init(1); astr->deviceId = astr->audio->getDeviceId(); float sampleRate = astr->audio->devices[astr->deviceId].sampleRates[0]; int blockSize = sampleRate / 200; // default block size astr->monoAudioStream = new dsp::stream(blockSize * 2); astr->audio->setBlockSize(blockSize); astr->audio->setStreamType(io::AudioSink::MONO); astr->audio->setMonoInput(astr->monoAudioStream); astr->audio->setSampleRate(sampleRate); astr->blockSize = blockSize; astr->sampleRate = sampleRate; astr->monoStream = stream; astr->sampleRateChangeHandler = sampleRateChangeHandler; astr->monoDynSplit = new dsp::DynamicSplitter(stream, blockSize); astr->monoDynSplit->bind(astr->monoAudioStream); astr->running = false; astr->volume = 1.0f; astr->sampleRateId = 0; astr->vfoName = vfoName; streams[name] = astr; return sampleRate; } float registerStereoStream(dsp::stream* stream, std::string name, std::string vfoName, int (*sampleRateChangeHandler)(void* ctx, float sampleRate), void* ctx) { AudioStream_t* astr = new AudioStream_t; astr->type = STREAM_TYPE_STEREO; astr->ctx = ctx; astr->audio = new io::AudioSink; astr->audio->init(1); float sampleRate = astr->audio->devices[astr->audio->getDeviceId()].sampleRates[0]; int blockSize = sampleRate / 200; // default block size astr->stereoAudioStream = new dsp::stream(blockSize * 2); astr->audio->setBlockSize(blockSize); astr->audio->setStreamType(io::AudioSink::STEREO); astr->audio->setStereoInput(astr->stereoAudioStream); astr->audio->setSampleRate(sampleRate); astr->blockSize = blockSize; astr->sampleRate = sampleRate; astr->stereoStream = stream; astr->sampleRateChangeHandler = sampleRateChangeHandler; astr->stereoDynSplit = new dsp::DynamicSplitter(stream, blockSize); astr->stereoDynSplit->bind(astr->stereoAudioStream); astr->running = false; streams[name] = astr; astr->vfoName = vfoName; return sampleRate; } void startStream(std::string name) { AudioStream_t* astr = streams[name]; if (astr->running) { return; } if (astr->type == STREAM_TYPE_MONO) { astr->monoDynSplit->start(); } else { astr->stereoDynSplit->start(); } astr->audio->start(); astr->running = true; } void stopStream(std::string name) { AudioStream_t* astr = streams[name]; if (!astr->running) { return; } if (astr->type == STREAM_TYPE_MONO) { astr->monoDynSplit->stop(); } else { astr->stereoDynSplit->stop(); } astr->audio->stop(); astr->running = false; } void removeStream(std::string name) { AudioStream_t* astr = streams[name]; stopStream(name); for (int i = 0; i < astr->boundStreams.size(); i++) { astr->boundStreams[i].streamRemovedHandler(astr->ctx); } delete astr->monoDynSplit; } dsp::stream* bindToStreamMono(std::string name, void (*streamRemovedHandler)(void* ctx), void (*sampleRateChangeHandler)(void* ctx, float sampleRate, int blockSize), void* ctx) { AudioStream_t* astr = streams[name]; BoundStream_t bstr; bstr.type = STREAM_TYPE_MONO; bstr.ctx = ctx; bstr.streamRemovedHandler = streamRemovedHandler; bstr.sampleRateChangeHandler = sampleRateChangeHandler; if (astr->type == STREAM_TYPE_MONO) { bstr.monoStream = new dsp::stream(astr->blockSize * 2); astr->monoDynSplit->stop(); astr->monoDynSplit->bind(bstr.monoStream); if (astr->running) { astr->monoDynSplit->start(); } astr->boundStreams.push_back(bstr); return bstr.monoStream; } bstr.stereoStream = new dsp::stream(astr->blockSize * 2); bstr.s2m = new dsp::StereoToMono(bstr.stereoStream, astr->blockSize * 2); bstr.monoStream = &bstr.s2m->output; astr->stereoDynSplit->stop(); astr->stereoDynSplit->bind(bstr.stereoStream); if (astr->running) { astr->stereoDynSplit->start(); } bstr.s2m->start(); astr->boundStreams.push_back(bstr); return bstr.monoStream; } dsp::stream* bindToStreamStereo(std::string name, void (*streamRemovedHandler)(void* ctx), void (*sampleRateChangeHandler)(void* ctx, float sampleRate, int blockSize), void* ctx) { AudioStream_t* astr = streams[name]; BoundStream_t bstr; bstr.type = STREAM_TYPE_STEREO; bstr.ctx = ctx; bstr.streamRemovedHandler = streamRemovedHandler; bstr.sampleRateChangeHandler = sampleRateChangeHandler; if (astr->type == STREAM_TYPE_STEREO) { bstr.stereoStream = new dsp::stream(astr->blockSize * 2); astr->stereoDynSplit->stop(); astr->stereoDynSplit->bind(bstr.stereoStream); if (astr->running) { astr->stereoDynSplit->start(); } astr->boundStreams.push_back(bstr); return bstr.stereoStream; } bstr.monoStream = new dsp::stream(astr->blockSize * 2); bstr.m2s = new dsp::MonoToStereo(bstr.monoStream, astr->blockSize * 2); bstr.stereoStream = &bstr.m2s->output; astr->monoDynSplit->stop(); astr->monoDynSplit->bind(bstr.monoStream); if (astr->running) { astr->monoDynSplit->start(); } bstr.m2s->start(); astr->boundStreams.push_back(bstr); return bstr.stereoStream; } void setBlockSize(std::string name, int blockSize) { AudioStream_t* astr = streams[name]; if (astr->running) { return; } if (astr->type == STREAM_TYPE_MONO) { astr->monoDynSplit->setBlockSize(blockSize); for (int i = 0; i < astr->boundStreams.size(); i++) { BoundStream_t bstr = astr->boundStreams[i]; bstr.monoStream->setMaxLatency(blockSize * 2); if (bstr.type == STREAM_TYPE_STEREO) { bstr.m2s->stop(); bstr.m2s->setBlockSize(blockSize); bstr.m2s->start(); } } astr->blockSize = blockSize; return; } astr->monoDynSplit->setBlockSize(blockSize); for (int i = 0; i < astr->boundStreams.size(); i++) { BoundStream_t bstr = astr->boundStreams[i]; bstr.stereoStream->setMaxLatency(blockSize * 2); if (bstr.type == STREAM_TYPE_MONO) { bstr.s2m->stop(); bstr.s2m->setBlockSize(blockSize); bstr.s2m->start(); } } astr->blockSize = blockSize; } void unbindFromStreamMono(std::string name, dsp::stream* stream) { AudioStream_t* astr = streams[name]; for (int i = 0; i < astr->boundStreams.size(); i++) { BoundStream_t bstr = astr->boundStreams[i]; if (bstr.monoStream != stream) { continue; } if (astr->type == STREAM_TYPE_STEREO) { astr->stereoDynSplit->stop(); astr->stereoDynSplit->unbind(bstr.stereoStream); if (astr->running) { astr->stereoDynSplit->start(); } bstr.s2m->stop(); delete bstr.s2m; return; } astr->monoDynSplit->stop(); astr->monoDynSplit->unbind(bstr.monoStream); if (astr->running) { astr->monoDynSplit->start(); } delete stream; return; } } void unbindFromStreamStereo(std::string name, dsp::stream* stream) { AudioStream_t* astr = streams[name]; for (int i = 0; i < astr->boundStreams.size(); i++) { BoundStream_t bstr = astr->boundStreams[i]; if (bstr.stereoStream != stream) { continue; } if (astr->type == STREAM_TYPE_MONO) { astr->monoDynSplit->stop(); astr->monoDynSplit->unbind(bstr.monoStream); if (astr->running) { astr->monoDynSplit->start(); } bstr.m2s->stop(); delete bstr.m2s; return; } astr->stereoDynSplit->stop(); astr->stereoDynSplit->unbind(bstr.stereoStream); if (astr->running) { astr->stereoDynSplit->start(); } delete stream; return; } } std::string getNameFromVFO(std::string vfoName) { for (auto const& [name, stream] : streams) { if (stream->vfoName == vfoName) { return name; } } return ""; } void setSampleRate(std::string name, float sampleRate) { AudioStream_t* astr = streams[name]; if (astr->running) { return; } int blockSize = astr->sampleRateChangeHandler(astr->ctx, sampleRate); astr->audio->setSampleRate(sampleRate); astr->audio->setBlockSize(blockSize); if (astr->type == STREAM_TYPE_MONO) { astr->monoDynSplit->setBlockSize(blockSize); for (int i = 0; i < astr->boundStreams.size(); i++) { BoundStream_t bstr = astr->boundStreams[i]; if (bstr.type == STREAM_TYPE_STEREO) { bstr.m2s->stop(); bstr.m2s->setBlockSize(blockSize); bstr.sampleRateChangeHandler(bstr.ctx, sampleRate, blockSize); bstr.m2s->start(); continue; } bstr.sampleRateChangeHandler(bstr.ctx, sampleRate, blockSize); } } else { astr->stereoDynSplit->setBlockSize(blockSize); for (int i = 0; i < astr->boundStreams.size(); i++) { BoundStream_t bstr = astr->boundStreams[i]; if (bstr.type == STREAM_TYPE_MONO) { bstr.s2m->stop(); bstr.s2m->setBlockSize(blockSize); bstr.sampleRateChangeHandler(bstr.ctx, sampleRate, blockSize); bstr.s2m->start(); continue; } bstr.sampleRateChangeHandler(bstr.ctx, sampleRate, blockSize); } } } void setAudioDevice(std::string name, int deviceId, float sampleRate) { AudioStream_t* astr = streams[name]; if (astr->running) { return; } astr->deviceId = deviceId; astr->audio->setDevice(deviceId); setSampleRate(name, sampleRate); } std::vector getStreamNameList() { std::vector list; for (auto [name, stream] : streams) { list.push_back(name); } return list; } };