Adding sound clips to NLA track via Python script

Assuming that I already have a speaker object, how do I add an NLA track to the speaker object of type ‘SOUND’ and then add multiple sound clips to that NLA track?

I am already able to use “bpy.context.active_object.animation_data.nla_tracks.new()”, etc., to add a new NLA track, and
bpy.context.active_object.animation_data.nla_tracks[“Track_Name”].strips.new(“Strip_Name”,start=20,action=bpy.data.actions[“Action_Name”])" to add a new action strip, but I cannot yet add a new sound track or sound strip.
…strips.new() can only add action strips, and attempting to use bpy.ops.nla.soundclip_add()" just produces “RuntimeError: operator bpy.ops.nla.soundclip_add.poll() failed, context is incorrect”

How might I go about adding a sound-type NLA track to a speaker object and then sound clips to that track using a script?

Hi Solvent,

Last time I looked there was no direct API methods like the ones you mentioned. Here is some code I have used to get around this.


import bpy
context = bpy.context


def get_context_area(context, context_dict,area_type='GRAPH_EDITOR'):
    
    for screen in bpy.data.screens:
        print(screen.name)
        for area_index, area in screen.areas.items():
            print(area.type)
            if area.type == area_type:
                context_dict["area"] = area
                context_dict["screen"] = screen
                context_dict["scene"] = context.scene
                context_dict["window"] = context.window
                context_dict["region"] = area.regions[0]
                print(context_dict)
                return True
    return False
override = context.copy()


get_context_area(context, override, area_type="NLA_EDITOR")


# quick commented hacks 
#assume speaker is selected
speaker = context.object


# unselect tracks already there else you get a soundclip for each
for t in speaker.animation_data.nla_tracks:
    t.select = False
    
# add a track the usual way
t = speaker.animation_data.nla_tracks.new()
t.name = "TEST ADDING SOUNDCLIP"


# move frame to 0 and add a strip.
context.scene.frame_set(0)
bpy.ops.nla.soundclip_add(override)


# move frame to 7000 and add another strip.
# if the soundstrip is longer than 7000 it will add a new track.
context.scene.frame_set(7000)
bpy.ops.nla.soundclip_add(override)
    
    

PS… you can just flip an area to the area type too. with C.area.type = ‘NLA_EDITOR’.

PPS… when you say multiple sounds? I think you are limited to just the one attached to the sound o f the speaker data.

Out of interest what are you doing with the speaker objects?

1 Like

Ah, excellent! I can’t test that yet, but I will try to soon.
By “multiple sounds” I just meant multiple sound clips on the same NLA track.

As for what I’m trying to do, I am trying to automate sound animation, really. I have a robotic character whose arms and legs (and ideally, every joint) are supposed to whirr when they bend. More than that, the sounds are supposed to be synchronized with the motion, so a slow bend of the elbow would result in a long, low-pitched whirr, while a fast bend would produce a higher-pitched (maybe lounder) sound. I already have a script that can calculate the pitch distribution using a bone’s rotation as input (if it works properly,) and now what remains is to be able to automatically add the sound clips to the speaker associated with that bone whenever the bone starts to rotate, as well as to be able to use this script to do this for maybe hundreds of speakers at once in a computationally efficient way. I’m trying to make simple sound effects something that can be baked, really.