Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get MemoryError when rendering multiple file #117

Open
Centauria opened this issue Sep 6, 2022 · 4 comments
Open

Get MemoryError when rendering multiple file #117

Centauria opened this issue Sep 6, 2022 · 4 comments
Assignees
Labels
bug Something isn't working

Comments

@Centauria
Copy link

Centauria commented Sep 6, 2022

My code structure is:

class Player:
    ......
    def render(self, midi):
        engine = dawdreamer.RenderEngine(44100, 128)
        for track in midi:
            plugin = engine.make_plugin_processor(get_name(track), get_vst(track))
            for note in track.notes:
                plugin.add_note(*get_note_info(note))
        mix = engine.make_add_processor('mix', [1] * len(midi))
        engine.load_graph(get_graph(midi))
        engine.render(midi.get_end_time())
        return engine.get_audio()

for midi in midi_list:
    wav = player.render(midi)
    save(wav, wav_file)

When I run this code, it will run normally first. After an hour or two, It will get a MemoryError: bad allocation.

I wonder how can I avoid this.

My computer have 24GB memory, and usually have 14GB available for my code.

@DBraun DBraun self-assigned this Sep 6, 2022
@DBraun DBraun added the bug Something isn't working label Sep 6, 2022
@DBraun
Copy link
Owner

DBraun commented Sep 6, 2022

Darn, that could be a tough one. It could be an issue with any of the VSTs, or it could be a DawDreamer issue. I'll revisit the relevant code when I get a chance. In the meantime, I hope you aren't blocked by this. You could possibly split the midi list into multiple BIG parts (each one taking ~30 min) and execute each part with python's subprocess.

@Centauria
Copy link
Author

Centauria commented Sep 7, 2022

Further test shown as follows:

After rendering total 4226 seconds of audio, program exited with error 0xC0000409 when (loading preset of) Ample Guitar L.
Then I removed all usage of Ample guitar & bass plugins, and run it again.
After rendering 2507 sec, program exited with error 0xC0000005 when (loading preset of) Roland JUNO-106.
After rendering 3828 sec, raised MemoryError when making plugin of JUNO-106.
After rendering 2853 sec, raised MemoryError when making plugin of TR808.
After rendering 3093 sec, program exited with error 0xC0000005 when (loading preset of) Serum.

I will update latest test result here. Hope it's helpful.

@DBraun
Copy link
Owner

DBraun commented Sep 8, 2022

Thanks, then it seems like a problem with DawDreamer.

@DBraun
Copy link
Owner

DBraun commented Feb 20, 2023

I don't have a full solution yet. Here's a script I was using. I was looking at the Task Manager in Windows and watching the memory usage for a Windows Command Prompt slowly rise. I was noticing the peak value go up by 0.1 MB every 15 seconds or so. It varies per plugin.

import dawdreamer as daw

plugin_path = "C:/VSTPlugins/Serum_x64.dll"


class Player:

    def render(self):

        engine = daw.RenderEngine(44100, 128)

        plugin = engine.make_plugin_processor("plugin", plugin_path)

        # # eventually want to make sure these don't leak either
        # plugin.add_midi_note(60, 60, 0.0, .25)
        # plugin.add_midi_note(64, 80, 0.5, .5)
        # plugin.add_midi_note(67, 127, 0.75, .5)

        # engine.load_graph([(plugin, []),])

        # engine.render(.01)
        # return engine.get_audio()


player = Player()
i = 0
while True:

    player.render()
    if i % 100 == 0:
        print('i', i//100)
    i += 1

The issue must be related to the Plugin Processor specifically because replacing the plugin creation line with

plugin = engine.make_add_processor("plugin", [0., 1.])

results in no leak.

The Sampler Processor has a lot in common with the Plugin Processor such as midi buffers, and yet it doesn't leak in the setup above.

import numpy as np
plugin = engine.make_sampler_processor("plugin", np.zeros((2,128)))

I haven't figured out what's wrong with the plugin processor class... I tried myPlugin.get()->releaseResources(); before each call to myPlugin.reset(); in the C++ source but that didn't fix it either.

If anyone is running a large render batch with DawDreamer, I'd recommend writing your code so that plugins aren't repeatedly created and deleted. Create an engine, create the plugins you need, and reload the graphs as necessary however many times you want. I don't think that style of code is leaking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants