LabSound / LabSound

:microscope: :speaker: graph-based audio engine

Home Page:http://labsound.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How can offlinerendercontext works

imiskolee opened this issue · comments

Hi, i can not found any examples for offline render context, I want to save result to file.

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