How can offlinerendercontext works
imiskolee opened this issue · comments
Misko Lee commented
Hi, i can not found any examples for offline render context, I want to save result to file.
Nick Porcino commented
There's an offline example in the demo program (https://github.com/LabSound/LabSoundDemo), here's the relevant part:
AudioStreamConfig offlineConfig;
offlineConfig.device_index = 0;
offlineConfig.desired_samplerate = LABSOUND_DEFAULT_SAMPLERATE;
offlineConfig.desired_channels = LABSOUND_DEFAULT_CHANNELS;
const float recording_time_ms = 1000.f;
std::unique_ptr<lab::AudioContext> context = lab::MakeOfflineAudioContext(offlineConfig, recording_time_ms);
lab::AudioContext& ac = *context.get();
std::shared_ptr<OscillatorNode> oscillator;
std::shared_ptr<AudioBus> musicClip = MakeBusFromSampleFile("samples/stereo-music-clip.wav", argc, argv);
std::shared_ptr<SampledAudioNode> musicClipNode;
std::shared_ptr<GainNode> gain;
auto recorder = std::make_shared<RecorderNode>(ac, offlineConfig);
context->addAutomaticPullNode(recorder);
recorder->startRecording();
{
ContextRenderLock r(context.get(), "ex_offline_rendering");
gain = std::make_shared<GainNode>(ac);
gain->gain()->setValue(0.125f);
// osc -> gain -> recorder
oscillator = std::make_shared<OscillatorNode>(ac);
context->connect(gain, oscillator, 0, 0);
context->connect(recorder, gain, 0, 0);
oscillator->frequency()->setValue(880.f);
oscillator->setType(OscillatorType::SINE);
oscillator->start(0.0f);
musicClipNode = std::make_shared<SampledAudioNode>(ac);
context->connect(recorder, musicClipNode, 0, 0);
musicClipNode->setBus(r, musicClip);
musicClipNode->schedule(0.0);
}
bool complete = false;
context->offlineRenderCompleteCallback = [&context, &recorder, &complete]() {
recorder->stopRecording();
printf("Recorded %f seconds of audio\n", recorder->recordedLengthInSeconds());
context->removeAutomaticPullNode(recorder);
recorder->writeRecordingToWav("ex_offline_rendering.wav", false);
complete = true;
};
// Offline rendering happens in a separate thread and blocks until complete.
// It needs to acquire the graph + render locks, so it must
// be outside the scope of where we make changes to the graph.
context->startOfflineRendering();
while (!complete)
{
Wait(std::chrono::milliseconds(100));
}