1
$\begingroup$

I am trying to set a Speaker's sound using a Python script and I was able to find that this should be done by assigning to the data.sound attribute of the Speaker object instance.

I also found that the appropriate value type for the attribute is Sound, however I have trouble instantiating it. From the documentation it looks like it has a constructor which takes an ID. When passing an empty string, I get a confusing error:

sound = pby.types.Sound('')

TypeError: bpy_struct.new(type): type 'Sound' is not a subtype of bpy_struct

The documentation would have you believe Sound indeed is a subtype of bpy_struct, because that's what it says in the base classes line.

However, clicking further through to bpy_struct, one finds this note:

Note that bpy.types.bpy_struct is not actually available from within Blender, it only exists for the purpose of documentation.

Blender seems to be well aware of it though as it throws an error at me for not instantiating a correct subclass of it.

What gives? How come Blender is aware of this type and how come Sound is not a proper subclass of it?

$\endgroup$

1 Answer 1

4
$\begingroup$

Blender very rarely (if at all) instances from class.

Rather than add a new object with ob = bpy.types.Object("blah") the blender way is to use the new method, or for images and sounds the load method of its data collection. eg bpy.data.objects.new("name", data) or bpy.data.sounds.load(filepath)

To load a new sound

snd = bpy.data.sounds.load("/path/to/soundfile")

python console, add a speaker and add sound.

>>> D.speakers.new(
new()
BlendDataSpeakers.new(name)
Add a new speaker to the main database
>>> D.speakers.new("xxx")
bpy.data.speakers['xxx']

>>> D.speakers['xxx'].sound = D.sounds.load(
load()
BlendDataSounds.load(filepath, check_existing=False)
Add a new sound to the main database from a file
>>> D.speakers['xxx'].sound = D.sounds.load("/tmp/xxx.mp3")
>>>  speaker_obj = bpy.data.objects.new("speaker", D.speakers['xxx'])

Link to scene in 2.79 and prior

>>> C.scene.objects.link(speaker_obj)

Alternatively with the operator, Add a new speaker object to the scene

bpy.ops.object.speaker_add(view_align=False, enter_editmode=False, location=(0, 0, 0), rotation=(0, 0, 0))
speaker_obj = context.object
$\endgroup$
1
  • $\begingroup$ In Blender 4.1 (and other version probably as well) you still need to link the object to a collection: context.collection.objects.link(speaker_obj) $\endgroup$
    – Rooster
    Commented Jul 10 at 12:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .