I’ve gone back to my project for UPBGE but I’m having trouble with Audaspace. I get an error about “buffer” needing two parameters which I started fixing. But then I get “File “getrotation.py”, line 38, in TypeError: The data needs to be supplied as float32 numpy array!”. I know what arrays are but need an example of using this type of array with Audaspace. Here is the code …
import bge
import aud
import bpy
import wave
import contextlib
import os, time
from bge import logic
from mathutils import Vector
import numpy as np
backwards_position = None
forwards_position = None
trap = 0
timecode_path = "c:\Serato_Control_CD.wav"
device = aud.Device()
track = aud.Sound('timecode_path')
# Find length of track
with contextlib.closing(wave.open(timecode_path,'r')) as f:
frames = f.getnframes()
rate = f.getframerate()
track_duration = frames / float(rate)
print("Duration: ")
print(track_duration)
# Setup handle to playing track.
# MUST be buffered for reverse. Where is this in documentation ?
track_buffered_reverse = track.buffer([0],44100)
track_buffered_forward = track.buffer()
track_reverse = track_buffered_reverse.reverse()
track_forward = track_buffered_forward
There is no line 38. Only 29 lines. Did you forget to post some code?
I also do not get an error similar to yours, however I do get a missing argument error:
Error: SetGlobalsAtTopofScript(Platter), Python script error
Traceback (most recent call last):
File “getrotation.py”, line 38, in
TypeError: The data needs to be supplied as float32 numpy array!
Duration:
You can see my probably naïve attempt to create the array further up in the code when “track” is defined. I’m not familiar with these type of arrays and was having trouble finding relevant examples of how to use them. Also why does Audaspace use them now when my code was valid before ? A way of simply addressing multiple sound files ?
OK, I solved the problem. I just learnt how to address a 2 dimensional numpy array, so I guess that’s win .
# DJ Turntable Physics Simulation, Michael Z Freeman, 2016
# See CHANGELOG.TXT, TODO.TXT & README.TXT in text data blog for changelog.
# Better name "Blender Game Engine DJ Turntable" ?
# This is the main Python file for the project. I decided not to pile everything into a single monolithic Python script without logic blocks. I found the logic blocks helped me think through the problems and keep things fairly simple. I also think the logic blocks make it easier for new comers to understand what is going on. So the script is arranged into "modules" that are referenced in the logic blocks. There is only one at the moment but that will probably change when, for example, file loading is added. Controls are only through the keyboard at the moment and will probably change:
#MOUSE CLICK LEFT/RIGHT: nudge/spin platter left/right.
# SPACE: start/stop.
# ALT: Deck on/off
import bge
import aud
import bpy
import wave
import contextlib
import os, time
from bge import logic
from mathutils import Vector
import numpy as np
backwards_position = None
forwards_position = None
trap = 0
timecode_path = "c:\Serato_Control_CD.wav"
device = aud.Device()
timecode = aud.Sound.file('timecode_path')
track = np.array([['timecode_path']], dtype='float32')
# Find length of track
with contextlib.closing(wave.open(timecode_path,'r')) as f:
frames = f.getnframes()
rate = f.getframerate()
track_duration = frames / float(rate)
print("Duration: ")
print(track_duration)
# Setup handle to playing track.
# MUST be buffered for reverse. Where is this in documentation ?
track_buffered_reverse = aud.Sound.buffer(track[0,0], 44100)
track_buffered_forward = track.buffer()
track_reverse = track_buffered_reverse.reverse()
track_forward = track_buffered_forward
#track_handle = device.play(track_reverse)
#track_handle.pitch = 1
# make sure its stopped because we have not moved the platter yet.
#track_handle.stop()
#def playTrack (cont):
#global track
#global track_handle
#global track_buffered
#global track_reverse
#global track_handle_forwards
#global track_handle_backwards
track_handle_forwards = device.play(track_forward)
track_handle_forwards.keep = True
track_handle_forwards.pause()
track_handle_forwards.loop_count = 0
track_handle_backwards = device.play(track_reverse)
track_handle_backwards.keep = True
track_handle_backwards.pause()
#reverse_handle.reverse
#track_handle.pitch = 1
#speed = setPitch
#print("Pitch: ")
#print(speed)
#track = track.pitch(speed)
def setPitch (cont):
global track
global track_handle
global track_buffered
global track_reverse
global track_forward
global duration
global trap
#global backwards_position
#global forwards_position
#forwards_position = track_handle_forwards.position
#backwards_position = track_handle_backwards.position
# Get object
platter = bge.logic.getCurrentScene().objects['Platter']
pitch_slider = bge.logic.getCurrentScene().objects['Pitch_control']
pitch_adj = 8 * (pitch_slider.position.y + 1.3) / 100
rot_speed = platter.worldAngularVelocity.z
# - pitch_adj
# "pitch_adj" figure has to be modified because we are returning "y" location of a non-centered model.
# "1.291654109954834" is "y" when the slider is in the middle.
# Then adjust to standard Technics 1210 8% control of total pitch range.
#print("Rotation speed: ")
#print(rot_speed);
speed = rot_speed * -1
#print("Pitch: ")
#print(speed)
if speed >= 0:
track_handle_backwards.pause()
forwards_position = track_handle_forwards.position
backwards_position = track_handle_backwards.position
#backwards_position = track_handle_backwards.position
#track_handle_forwards.position = forwards_position
while (trap == 1):
print("Forward trap triggered")
track_handle_forwards.position = track_duration - backwards_position
trap = 0
track_handle_forwards.resume()
# playing/paused/stop status only ever shows as true ?
#print("track_handle_backwards.status: ")
#print(track_handle_backwards.status)
#print(speed)
#print("Pitch adj=")
#print(pitch_adj)
#print("Silder y=")
#print(pitch_slider.position.y)
# Set pitch of audio including pitch slider modifier.
track_handle_forwards.pitch = speed
#- pitch_adj + 1.291654109954834
#print("track_handle_forwards.pitch: ")
#print(track_handle_forwards.pitch)
#print("track_handle_forwards.position: ")
#print(track_handle_forwards.position)
else:
track_handle_forwards.pause()
forwards_position = track_handle_forwards.position
backwards_position = track_handle_backwards.position
# Only set once until direction changes
while (trap == 0):
print("Backwards trap triggered")
#print("Reverse Set: ")
#print(backwards_position - track_duration + forwards_position)
track_handle_backwards.position = track_duration - forwards_position
trap = 1
#forwards_position = track_handle_forwards.position
#track_handle_backwards.position = backwards_position
track_handle_backwards.resume()
# Set pitch of audio including pitch slider modifier.
track_handle_backwards.pitch = speed * -1
#print("track_handle_backwards.pitch: ")
#print(track_handle_backwards.pitch)
#print("track_handle_backwards.position: ")
#print(track_handle_backwards.position)
#track = track.pitch(speed)
# rot_speed * -1
#track = track.pitch(rot_speed)
# Old code for Actuator
#sound.pitch = rot_speed * -1
#print("Pitch: ")
#print(track.pitch)
#return rot_speed;
def checkBrake (cont):
print("Brake was triggered.")
def applyForce (cont):
if scratch == True:
print("Mouse Left Click")
cont = logic.getCurrentController()
mouse = cont.sensors['Mouse.001']
x,y = mouse.position
platter = bge.logic.getCurrentScene().objects['Platter']
platter.applyTorque((0, 0, x/50))
def applyForceRight (cont):
print("Mouse Right Click")
cont = logic.getCurrentController()
mouse = cont.sensors['Mouse.003']
x,y = mouse.position
platter = bge.logic.getCurrentScene().objects['Platter']
platter.applyTorque((0, 0, -x/50))
However I now get …
File “getrotation.py”, line 29, in
ValueError: could not convert string to float: ‘timecode_path’
So “buffer” no longer does what it used to do. Am I supposed to read in the data in some kind of raw form ? All I need to do is buffer the sound.
A lot seems to have changed with Audaspace with very little documentation or examples that I could find.
Should I be using the stable version of UPBGE which is an older version of Audaspace. Could some of Audaspace in the UPBGE alpha be buggy ?
I assume this is supposed to be the path to the wave, rather than a literal file called “timecode_path”? Remove the apostrophes to use the variable. Also, use double backslashes (e.g. “c:\\Serato_Control_CD.wav” because a single one is for escaping characters (e.g. “\n” for linebreak).
What are you trying to do with this line? I see you’re calling “buffer” on it later on, but that implies you’re expecting it to be an AUD sound.
I’d recommend starting with a script that successfully plays sound based on the example in my link at the top. Then, add each extra bit one at a time and test things in between so you know which bits aren’t working.
Cheers. I used the example in your link for a test. I stripped out everything from the “getrotation” script and replaced with the test …
import aud
device = aud.Device()
# load sound file (it can be a video file with audio)
sound = aud.Sound('c:\\Serato_Control_CD.wav')
# play the audio, this return a handle to control play/pause
handle = device.play(sound)
# if the audio is not too big and will be used often you can buffer it
sound_buffered = aud.Sound.buffer(sound)
handle_buffered = device.play(sound_buffered)
# stop the sounds (otherwise they play until their ends)
handle.stop()
handle_buffered.stop()
When I load this blend file the sound immediately starts playing … the first “handle = device.play(sound)”, however it never gets buffered and gives the same error (this is everything reported in the console window …
Read prefs: C:\Users\tempo\AppData\Roaming\UPBGE\Blender\3.0\config\userpref.blend
Icon can not be set, using original Buttons.
Icon can not be set, using original Buttons.
register_class(...):
Warning: 'NODE_MT_category_Vector Math' doesn't have an alpha-numeric suffix
register_class(...):
Warning: 'NODE_MT_category_Armature / Rig' doesn't have an alpha-numeric suffix
register_class(...):
Warning: 'NODE_MT_category_Ray Casts' doesn't have an alpha-numeric suffix
Read blend: C:\Users\tempo\Documents\UPBGE Development\UPBGE Alpha\Aud Test Example PLAYS THE SOUND NO ARRAY NONSENSE MESSAGE.blend
Traceback (most recent call last):
File "C:\Users\tempo\Documents\UPBGE Development\UPBGE Alpha\Aud Test Example PLAYS THE SOUND NO ARRAY NONSENSE *MESSAGE.blend\getrotation.py", line 10, in <module>*
*TypeError: buffer() takes exactly 2 arguments (1 given)*
Unless this is some kind of bug it seems to be a new way of calling the buffer in a new update of Audaspace (or it was added by UPBGE devs) as defined here. I still don’t understand why it requires an array if that’s what’s going on. If I want to use multiple sounds then I’d use an array, but I only have a SINGLE sound. What happened to keep it simple, eh ?
EDIT: Got it ! I hope !
This DOES work …
import aud
device = aud.Device()
# load sound file (it can be a video file with audio)
sound = aud.Sound('c:\\Serato_Control_CD.wav')
# play the audio, this return a handle to control play/pause
#handle = device.play(sound)
# if the audio is not too big and will be used often you can buffer it
sound_buffered = aud.Sound.cache(sound)
handle_buffered = device.play(sound_buffered)
# stop the sounds (otherwise they play until their ends)
#handle.stop()
#handle_buffered.stop()
In their wisdom Audaspace or the UPBGE devs have changed what used to be “buffer” into “cache”. This is what had been confusing me all along. “buffer” now “Creates a sound from a data buffer” (the opposite of what buffer used to do, confused yet? Even worse the example is wrong at the top of the docs page.). The array it requires is created from “data” … “Retrieves the data of the sound as numpy array.”.
“cache” … “Caches a sound into RAM” which is what older version of Aud “buffer” used to do.