3
$\begingroup$

What I wanna do is bake sound with different frequency ranges to different objects. It is done pretty simply using Python scripts. However, I am seeking for a way to speed this process up by utilizing multiple CPU cores. As far as I understand, it is done with multiprocessing module in Python. Here's what I tried:

import bpy
from multiprocessing import Process

FREQS=[(1000,2000),
(2000,5000),
(5000,20000)
]

def soundBake(lo,hi):
    pass
    print("soundBake started")#debug
    bpy.context.area.type = 'GRAPH_EDITOR'
    bpy.ops.graph.sound_bake(filepath="/tmp/001.mp3",low=lo,high=hi)
    print("soundBake completed")#debug

scene = bpy.context.scene
objects= scene.objects

processes=[]

bpy.context.area.type = 'GRAPH_EDITOR'


for i, obj in enumerate(objects):
    pass
    bpy.ops.object.select_all(action='DESELECT')
    print("i ", str(i))#debug        
    obj.select = True



    lo=FREQS[i][0]
    hi=FREQS[i][1]
    print("lo",str(lo),"hi",str(hi))

    p=Process(target=soundBake,args=(lo,hi,))
    processes+=[p]
    p.start()

    obj.select = False

    break#debug

for proc in processes:
    proc.join()

bpy.context.area.type = 'TEXT_EDITOR'

bpy.ops.object.select_all(action='DESELECT')

print("\n")

And I get this error:

i  0
lo 1000 hi 2000
soundBake started
Process Process-37:
Traceback (most recent call last):
  File "/home/highstaker/blender-2.73-linux-glibc211-i686/2.73/python/lib/python3.4/multiprocessing/process.py", line 254, in _bootstrap
    self.run()
  File "/home/highstaker/blender-2.73-linux-glibc211-i686/2.73/python/lib/python3.4/multiprocessing/process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "/home/highstaker/Dropbox/3d/blender_projects/!Tests/bakingSOundsMultiprocessing.blend/Text", line 13, in soundBake
  File "/home/highstaker/blender-2.73-linux-glibc211-i686/2.73/scripts/modules/bpy/ops.py", line 189, in __call__
    ret = op_call(self.idname_py(), None, kw)
RuntimeError: Operator bpy.ops.graph.sound_bake.poll() failed, context is incorrect

So, I presume that setting a context using bpy.context.area.type doesn't help.

Is there a way to make the operator run in a subprocess so I could split them to several CPU cores? And how do I set this context for the subprocess?

I'm using Blender version 2.72.

$\endgroup$
  • $\begingroup$ You are setting the context right, but just area.type is probably not enough. Some other context is incorrect too.. $\endgroup$ – Jaroslav Jerryno Novotny Apr 9 '15 at 18:43
  • $\begingroup$ @Jerryno are there other context-setting operations I could try? $\endgroup$ – Highstaker Apr 9 '15 at 19:03
  • $\begingroup$ I wonder If you might be more efficient to spawn several simultaneous blender instances using command-line options and feed them scripts to generate F-curves with different parameters, then let them process on separate cores, and once they're all done, use a final import script to append the F-Curves into a final Blend. $\endgroup$ – zeffii Apr 9 '15 at 20:09
  • $\begingroup$ @zeffii could be used as a workaround, but I'm looking for a way to do it without such excessive things, cause this is way too tedious $\endgroup$ – Highstaker Apr 10 '15 at 8:32
  • $\begingroup$ You need to specify an active fcurve, this is what is giving you the context error. A copy of the context can also be passed to the operator as argument one eg bpy.ops.blah,bla(c, x=1) where c = bpy.context.copy(). This however only irons out the poll / context bug, unfortunately. $\endgroup$ – batFINGER Aug 29 '15 at 18:43
1
$\begingroup$

I'm sure someone will school me if I'm wrong (please do!):

The Python multiprocessing module allows one to run concurrent python code, this makes sense for processes that don't rely on each other to reach a conclusion. What you want to do is get Blender to concurrently perform the sound bake function (C code). As far as I'm aware calls to that function are blocking Blender from doing anything else until the function ends and control is returned to python.

If that's right, then A solution could be the one I offered in the comment s:

  • use Popen or subprocess and instantiate multiple Blender threads with scripts, and append the F-curves from each resulting .blend into a final .blend.
| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.