tyrylu / pyfmodex Goto Github PK
View Code? Open in Web Editor NEWPython bindings for fmod ex sound library.
License: MIT License
Python bindings for fmod ex sound library.
License: MIT License
Hi, this is a great resource, so first of all: thank you!
I don't know if this is because the project is still being developed, a bug or me being dense, but with this piece of code:
soundpath = 'path/to/my/banks/'
studio = pyfmodex.studio.StudioSystem()
studio.initialize()
studio.load_bank_file(soundpath + "Master.bank")
studio.load_bank_file(soundpath + "Master.strings.bank")
studio.load_bank_file(soundpath + "sfx.bank")
evt = studio.get_event('event:/Waves').create_instance()
evt.start()
I think I should be able to get a sound playing, but evt.playback_state
always returns STARTING
and no sound is playing, I get no error messages either
Don't worry, I execute the above code once, then in a loop I check the state
Any idea what I'm doing wrong?
when I try to import pyfmodex I get the error :
Traceback (most recent call last):
File "C:\Users\idime\AppData\Local\Programs\Python\Python37\lib\site-packages\pyfmodex\__init__.py", line 2, in <module>
from .fmodex import (
File "C:\Users\idime\AppData\Local\Programs\Python\Python37\lib\site-packages\pyfmodex\fmodex.py", line 6, in <module>
_dll = windll.fmod
File "C:\Users\idime\AppData\Local\Programs\Python\Python37\lib\ctypes\__init__.py", line 434, in __getattr__
dll = self._dlltype(name)
File "C:\Users\idime\AppData\Local\Programs\Python\Python37\lib\ctypes\__init__.py", line 364, in __init__
self._handle = _dlopen(self._name, mode)
OSError: [WinError 126] The specified module could not be found
I tried to add fmod to my path, and I also tried to change the line :
_dll = windll.fmod
to
_dll = windll.fmodex64
but it did not works... can someone help me ?
Hi,
thanks for this great library; it is proving useful in a project over here.
I was wondering, can we call this project an active one? I see that the latest PYPI package release doesn't contain the latest changes in the code.
Basically, would the current maintainers consider any pull requests that I might provide?
Currently, it's a bit tricky to use pyfmodex due to the time and way it loads fmod.
As pyfmodex expects the fmod lib to be in the current work dir specified at the start of python, it's not easily possible to set the fmod lib that pyfmodex is supposed to use.
To make matters worse, this is even more so the case for cross-platform projects.
On Windows, one has to preload fmod via ctypes.WinDLL(path),
on Linux, one has to add the dir containing fmod to LD_LIBRARY_PATH,
and on Mac to DYLD_LIBRARY_PATH.
Therefore I propose to implement a way to let the user pass the fmod lib path to pyfmodex.
e.g., by using os.environ
user:
import os
os.environ["PYMODEX_FMOD_LIB"] = "path"
import pyfmodex
pyfmodex/pyfmodex/fmodex.py
...
if "PYFMODEX_FMOD_LIB" in os.environ:
_dll = CDLL(os.environ["PYFMODEX_FMOD_LIB"])
else:
arch = platform.architecture()[0]
if platform.system() == "Windows":
try:
_dll = windll.fmod
except Exception as exc:
current_directory = os.path.dirname(os.path.realpath(sys.argv[0]))
try:
_dll = CDLL(os.path.join(current_directory, "fmod"))
except:
raise RuntimeError("Pyfmodex could not find the fmod library") from exc
elif platform.system() == "Linux":
_dll = CDLL("libfmod.so")
elif platform.system() == "Darwin":
if arch == "32bit":
raise RuntimeError("No 32-bit fmod library for Mac Os exists")
_dll = CDLL("libfmod.dylib")
I think that implementing it as shown above would be the easiest and least intrusive option.
If you like the idea,
I can take care of making a PR with any changes you would like.
Hi,
First all, congratulations for the wonderful project!
Well I'm using this lib to get spetrum of a sound with 3D DSP effects applied. From I read, first I must create a DSP FFT, add it to channels group, and then use the DSP get_parameter
method with DSP_FFT_SPECTRUM_DATA
param to get the actual 3D sound (the transformed sound already with effects of panning). However when I try create DSP I get the FMOD_ERR_PLUGIN_INSTANCES
error. This is the code:
import pyfmodex
from pyfmodex.constants import *
FMOD_DSP_TYPE_FFT = 29 ## Missing constant
## Initialize FMOD
system = pyfmodex.System()
system.init(maxchannels=32, flags=FMOD_INIT_NORMAL)
## Play the sound
sound1 = system.create_sound("MySong.mp3", mode=FMOD_3D)
sound1.mode = FMOD_LOOP_NORMAL
channel = system.play_sound(sound1, paused=True, channelid=FMOD_CHANNEL_FREE)
## Create the DSP effect.
fft_dsp = system.create_dsp_by_type(FMOD_DSP_TYPE_FFT) ## Throws FMOD_ERR_PLUGIN_INSTANCES error
##fft_dsp.bypass = True
fft_dsp.active = True
system.mastergroup.add_dsp(fft_dsp)
I noted that the pyfmodex.constants
doesn't contain some constants related to FFT which include FMOD_DSP_TYPE_FFT
and FMOD_DSP_FFT_WINDOW_*
constants. When I try create a DSP with any ``FMOD_DSP_TYPE_*constant present in
pyfmodex.constants`, I get success. I'm newbie to CTypes so I don't know how far the constant name must be required to call the DLL function once I pass `29` which is the equivalent in C++ enum and it emmits error. Furthermoew, my FMODEX DLL version seems be quite new, so I don't think that is a DLL version problem. So any idea??
(In either case, I'm glad to pull the code updating the repo with these and any other missing constants. )
Hi.
Is this library still being maintained. Also do this library support the latest 2.x branch of fmod?
Technical question: why are some structures defined completely in structures.py
and others partially in structure_declarations.py
?
Just asking as it makes importing them more of a hassle, since one needs to remember where the required structure comes from.
The fmodex api has a function to read data from a sound object (e.g., to calculate RMS, or otherwise process it). But this doesn't seem to be mapped in pyfmodex. Any chance of it getting included?
(pyfmodex is awesome, by the way!)
FMOD_Sound_GetMusiChannelVolume->FMOD_Sound_GetMusicChannelVolume in sound.py:
def get_music_channel_volume(self, channel):
v = c_int()
ckresult(_dll.FMOD_Sound_GetMusicChannelVolume(self._ptr, channel, byref(v)))
return v.value
def set_music_channel_volume(self, id, vol):
ckresult(_dll.FMOD_Sound_SetMusicChannelVolume(self._ptr, id, c_float(vol)))
So, as an overview, here's the current state of the sample code in the documentation with regards to the upstream samples:
pyfmodex
userdata
seems to be None instead of a pointer to a c_int
; I'm actually sure this worked perfectly fine before, so it seems this was introduced in one of the 10th May 2021 commitsDespite their shortcomings, these three are still included in the documentation for the moment.
dsp_custom is not included at all, due to a problem related to adding two parameters to a user defined DSP (see #34 - early comments).
(I can use help in getting these issues above fixed/tested.)
@tyrylu what about the load of the dll in windows? It does not works for me without adding the real path.
if platform.system() == "Windows":
path = os.path.dirname(os.path.realpath(sys.argv[0]))
_dll = CDLL(os.path.join(path, 'fmod'))
Hi, I'm a user with windows 10.
Currently i am using python 3.10.
I've tried installing many versions of FMOD, but all of the 2.0.2.xxx versions show the following error when calling the dll again
pyfmodex.exceptions.FmodError: HEADER MISMATCH
I put fmod.dll inside C:\windows\system32.
Because I don't know how to load this DLL in the py file, it seems that manually adding environment variables to the system doesn't work.
Please tell me how to fix this error so that I can use FMOD version 2.0.2 or above.
Thank you!
It seem they have removed the download links and you have to email them to get the binaries. Not sure if that works for non-commercial use..
Hello, I would like to ask a question about playback.
I've searched a lot of documents about it, but I couldn't find an answer.
Currently, I'm using play_sound in my python code, but after calling him 64 times repeatedly, on the 65th time, he fails to produce sound, but no error is generated.
Must be used
sound.release()
Re-call after
sound = system.create_sound(file_path)
and then re-call play_sound to get the sound to play out properly.
I would like to know how I can play sound effects with play_sound over and over again without releasing him.
thanks
The latest addition to studio_object is causing a bug:
self.function_prefix = '' # to be overridden in subclasses
This is the trace, not sure why this was introduced:
File "C:\Users\marce\PycharmProjects\srsapp\backend\controllers\shaker_helpers.py", line 97, in reinit_studio
studio_low_level_system = studio_system.core_system
File "C:\Users\marce\PycharmProjects\srsapp\venv\lib\site-packages\pyfmodex\studio\system.py", line 195, in core_system
self._call("GetCoreSystem", byref(system_ptr))
File "C:\Users\marce\PycharmProjects\srsapp\venv\lib\site-packages\pyfmodex\studio\studio_object.py", line 21, in _call
result = getattr(self.lib, func_name)(self.ptr, *args)
File "C:\Users\marce\AppData\Local\Programs\Python\Python38\lib\ctypes_init.py", line 386, in getattr
func = self.getitem(name)
File "C:\Users\marce\AppData\Local\Programs\Python\Python38\lib\ctypes_init.py", line 391, in getitem
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function '_GetCoreSystem' not found
I installed pyfmodex via pip install on a raspberry pi where fmod is installed. When I did the import of pyfmodex in the python REPL it crashed with the error:
from ctypes import CDLL, windll
ImportError: cannot import name 'windll' from 'ctypes' (/usr/lib/python3.9/ctypes/__init__.py)
I looked throught the code and did not find where this error occured, more debugging showed that i got a differtent version on my raspberry.
Then i compared the file on github and the file on pip and they are different. The line in question is this one:
Line 15 in c9e9fa6
it doesn't import the windll of ctypes there, which the pip version does. Which obviously doesnt work on linux. The bug is already fixed, but not comitted to pip i guess.
So, with the libfmod 2.01 libraries on a 64bit Linux system, the following tests fail when running pytest -k 'not geometry and not distance'
(the -k
is there to skip segfaulting tests, see #22):
assert [2.7185190207...432476251e+37] == [1.0, 2.0, 3.0]
assert 0.0 == 5.0
TypeError: '>' not supported between instances of 'NoneType' and 'int'
and then a few pyfmodex.exceptions.FmodError: PLUGIN RESOURCE
instances whenever the midi_sound fixture is loaded.
After completing the API documentation in #33 , I'd like to add some more user friendly documentation like how to get started
, installation
, etc...
Now, I'm a fairly new an inexperienced user of FMOD myself, so I was wondering if others might perhaps want to share some (simple or advanced) example code using the library here that I can incorporate in the documentation?
That would be great. :-)
Running pytest
on my system (Linux 64bit) with the latest libfmod libraries (version 2.1) results in some failed tests:
but, most notably, in a consistent segfault on
The exact line where it segfaults is
Line 99 in f813ae9
I suspect this is a problem with FMOD and not with pyfmodex, but I'm wondering if others are facing the same issue?
The "forward" and "up" vectors must be perpendicular, so setting them one after another can cause an error: "pyfmodex.exceptions.FmodError: INVALID VECTOR".
listener.up = (0, 0, 1) # not compatible with the default forward
listener.forward = (0, -1, 0)
Proposal for testing:
We need to test for various platforms, various Python versions and various FMOD releases. I can set up something like tox to take care of some of it, but I think we'll also have to look into the CI infrastructure github is providing.
Proposal:
Python 3.7, 3.8 and 3.9
Windows, Mac OS and Posix
FMOD API 2.0 and 2.1
Possible simplification could be to only support (read: test) the latest release of the FMOD API.
One possible problem @tyrylu came up with is that it might be hard (or legally prohibited at least) to host libfmod libraries on the CI system.
What do you think?
When upgrading the library of FMOD to libfmod.so.13.8
The call:
system = pyfmodex.System()
gets the error
pyfmodex.exceptions.FmodError: HEADER MISMATCH
(Working on Linux with Python3.10)
Thanks
Why is TIMEUNIT modelled as a flag and not as an enum? I wonder as it doesn't seem to me to make much sense to be able to specify multiple time units at once somewhere.
Hi,
I'm trying get the spectrum data of a sound but I got this:
Traceback (most recent call last):
File "C:/Users/David Ragazzi/PycharmProjects/fmod/teste.py", line 110, in <module>
spectrum = dsp_fft.get_parameter_data(DSP_FFT.SPECTRUMDATA)
File "C:\Program Files\Python37\lib\site-packages\pyfmodex\dsp.py", line 162, in get_parameter_data
self._call_fmod("FMOD_DSP_GetParameterData", index, byref(value), byref(value_len), value_str, len(value_str))
File "C:\Program Files\Python37\lib\site-packages\pyfmodex\fmodobject.py", line 16, in _call_fmod
ckresult(result)
File "C:\Program Files\Python37\lib\site-packages\pyfmodex\utils.py", line 9, in ckresult
raise FmodError(result)
pyfmodex.exceptions.FmodError: INVALID PARAM
The code:
import pyfmodex
from pyfmodex.enums import DSP_TYPE, DSP_FFT
system = pyfmodex.System()
system.init(32)
dsp_fft = system.create_dsp_by_type(DSP_TYPE.FFT)
file = "C:\\Program Files (x86)\\FMOD SoundSystem\\FMOD Studio API Windows\\api\\core\\examples\\media\\drumloop.wav"
sound = system.create_sound(file)
channel = system.play_sound(sound, 0, False)
channel.add_dsp(0, dsp_fft)
spectrum = dsp_fft.get_parameter_data(DSP_FFT.SPECTRUMDATA)
When I try other parameter like dsp_fft.get_parameter_float(DSP_FFT.DOMINANT_FREQ)
it works well.
Hello,
I have the piece of the code below that I am trying to figure out why the sound is not being played in the LFE (Subwoofer) Channel.
Using set_mix_levels_output, I can control which channel to play the sounds, but the sound never played in the LFE, in the example below the Center plays fine, but the Subwoofer nothing.
I double checked pretty much everything, sound card, windows configuration (test on the windows works), and even pyfmodex code (everything looks good).
I also went to to sample files of fmodex and tweaked the multiple speaker cpp sample to play the same file as I'm trying to play in fmodex and over there everything works fine, on the LFE channel.
I'm using fmod64 1.10.3
If someone has any idea, or suggestion, I invested the about 6 hours, and have no clue why is not working.
Please note that I tried this in multiple computers (different soundcards) and same behavior.
I also debuged the code below going all the way to the dll, and could not find anything unusual.
`import pyfmodex
import time
mixer1 = pyfmodex.System()
mixer1.driver = 0
mixer1.init(32)
try:
test_mixer = mixer1.create_sound('C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\lowlevel\examples\media\stereo.ogg')
except Exception as e:
print('test', e)
pass
channels = mixer1.create_channel_group('marcelo')
channels.set_mix_levels_output(0, 0, 0, 1, 0, 0, 0, 0)
try:
mixer1.play_sound(test_mixer, channels)
except Exception as e:
print('test mixer', e)
pass
mixer1.update()
time.sleep(5)`
Hi,
I am trying to make a simple sound play to test this module. Here is the code, taken from your example in the readme:
import pyfmodex
system = pyfmodex.System()
system.init()
sound = system.create_sound("./pze_20110530.mp3") #./4ykpVd_samples/30-4ykpVd.ogg
sound.play()
When I run it, the script just finishes without any error messages. I think the extension loads fine, as I get an error if the fmod dll is not present, and also when I run it the program briefly appears in the Windows audio mixer. I also think the audio file path is valid, because if I change it I get an error.
However, no audio is actually played. How can I debug what the problem is? It doesn't look like the functions return any error codes either.
I've installed the fmod Ex Api and installed pyfmodex fine. I also added the the fmod ex api directory to my system path (i.e., where fmodex.dll is located) but when I import, I get:
import pyfmodex
Traceback (most recent call last):
File "", line 1, in
File "C:\Python27\lib\site-packages\pyfmodex__init__.py", line 2, in
from .fmodex import get_debug_level, set_debug_level, get_disk_busy, set_disk_busy, get_memory_stats
File "C:\Python27\lib\site-packages\pyfmodex\fmodex.py", line 4, in
dll = windll.fmodex
File "C:\Python27\lib\ctypes__init_.py", line 435, in getattr
dll = self.dlltype(name)
File "C:\Python27\lib\ctypes__init_.py", line 365, in init
self._handle = _dlopen(self._name, mode)
WindowsError: [Error 126] The specified module could not be found
Thanking you for your project, I would like to ask if you can give me an example using the seek method, to forward or reverse playback. The request is motivated by the fact that the examples you provided need to be updated, because timeunits is in flagh and not in enums as you indicated.
This is the class I'm building, but I can't do the seek method, because doesn't work
import pyfmodex
from pyfmodex.enums import DSP_MULTIBAND_EQ, DSP_MULTIBAND_EQ_FILTER_TYPE, DSP_TYPE
from pyfmodex.flags import TIMEUNIT
class SoundPlayer:
def init(self, sound_file):
# Initialize FMOD System
self.system = pyfmodex.System()
self.system.init(maxchannels=1)
# Create the master channel group
self.mastergroup = self.system.master_channel_group
# Load sound file
self.sound = self.system.create_sound(sound_file)
self.channel = None
#...
def seek(self, time_ms):
# Imposta la posizione di riproduzione del suono in base al tempo fornito in millisecondi
if self.channel and self.sound:
sound_length_ms = self.sound.get_length(TIMEUNIT.MS)
if sound_length_ms > 0:
sound_length_samples = self.sound.get_length(TIMEUNIT.PCM)
time_ms = max(0, min(time_ms, sound_length_ms))
position_samples = int(time_ms / 1000 * self.sound.default_frequency)
position_samples = max(0, min(position_samples, sound_length_samples))
self.channel.set_position(position_samples, TIMEUNIT.PCM)
self.system.update() # Update the FMOD system to apply the new position
Hi Guys,
I'm trying to convert the recorder.cpp to the python, and I'm getting the error below while using the CREATESOUNDEXINFO.
...
exinfo = pyfmodex.structures.CREATESOUNDEXINFO
exinfo.numchannels = native_channels
exinfo.format = SOUND_FORMAT.PCM16
exinfo.defaultfrequency = native_rate
exinfo.length = native_rate * ctypes.sizeof(ctypes.c_short) * native_channels # 1 second delay
game_sound = mixer1.create_sound(0, mode=MODE.LOOP_NORMAL | MODE.OPENUSER, exinfo=exinfo)
Traceback (most recent call last):
File "C:/Users/marce/PycharmProjects/srsapp/recorder.py", line 51, in
game_sound = mixer1.create_sound(0, mode=MODE.LOOP_NORMAL | MODE.OPENUSER, exinfo=exinfo)
File "C:\Users\marce\PycharmProjects\srsapp\venv\lib\site-packages\pyfmodex\system.py", line 272, in create_sound
exinfo = byref(exinfo)
TypeError: byref() argument must be a ctypes instance, not '_ctypes.PyCStructType'
This is the place where the current progress of the wrapping of the Studio API can be seen.
Note that the getById methods which take a GUID will not be generally implemented, because support for fmod GUIDs is not great overall and you can usually get the object differently (GUID as string, name etc.)
After downloading the latest FMOD Engine (v 2.02, early access at the time of writing), pyfmodex
doesn't seem to work any longer: whenever a System object is created (for core or for studio), the C-call returns a HEADER_MISMATCH return code.
I'm very confused by this, as what is the mismatch with, exactly?
Strangely enough, the packaged C++ example code compiles and runs just fine with the new libraries.
I'm getting the same problem with the x86_64
and the arm
libraries, both on Linux.
This looks to be something like discussed on https://qa.fmod.com/t/unity-2019-3-0f6-err-header-mismatch/15427.
So, this leaves me wondering: is this something we ought to solve, or be passed on to upstream?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.