Contraz / demosys-py

A light high performance modern OpenGL 3.3+ Python Framework https://demosys-py.readthedocs.io/
ISC License
64 stars 5 forks source link

Effect template including rocket / music timers #20

Open helgrima opened 6 years ago

helgrima commented 6 years ago

I am interested to figure out how pyrocket and pygame.mixer can be used, as documentation is quite sparse on that matter. I will try to finish template for rocket next week and update documentation according to rocket and pygame.mixer

einarf commented 6 years ago

An example here: https://github.com/Contraz/demosys-py-test/blob/master/testdemo/rockettest/effect.py

Just make sure to use RocketTimer or RocketMusicTimer + configure ROCKET in settings: http://demosys-py.readthedocs.io/en/latest/settings.html#timer

Sorry again for the poor state of the docs. Been pushing hard for the last month to get the moderngl branch into master because of the vast improvements to features and performance + adding gltf and wavefront support and sorting out all kinds issues in external libraries.

einarf commented 6 years ago

Just noticed: The RocketMusicTimer doesn't actually play music right now, but it works with MusicTimer. That's probably not hard to fix. It's just adding a few missing methods.

Edit: Just pushed af393f5fe257ff6280800b02daf920a30f6f9210 to fix that

Can just pull master and python setup.py develop in your virtualenv to fake install it. Then your virtualenv will keep using the the code in your local repo as the package. Just make sure to pip uninstall the actual package first.

.. and don't hesitate to nag about anything if you have questions.

helgrima commented 6 years ago

I will take a shot as soon as possible. And just came mind that if pygame is too bloat to include just for playing music, would it be against licenses or something to isolate music functionality from pygame and create stand alone module from that?

einarf commented 6 years ago

I picked pygame because it took 5 minutes to figure out how to use their mixer module. It's not really ideal for this framework because time seeking is very inaccurate causing issues when timing with rocket. Need to find something better eventually. Bloat or not doesn't really matter as long as it does the job well and works on win, linux and darwin.

You can do whatever you want with this project really. ISC License is pretty much BSD. Contribute a new timer to the project or make your own package for it, public or private.. then just load it.

TIMER = 'path.to.my.Timer'

Most important thing for music based timers: The timer class must return an accurate time position.

einarf commented 6 years ago

Sorry. I think I misread your post. pygame is LGPL, so I'm not entirely sure how that works. Maybe if you make sure the code is open and freely available. I don't think it's really worth splitting it up. Could be more interesting to look at pybass or similar solutions.

helgrima commented 6 years ago

Actually pybass was one I was also thinking. Maybe I will try to create example with that and demosys.

einarf commented 6 years ago

Could also be an idea to check out pyglet's media package: http://pyglet.readthedocs.io/en/pyglet-1.3-maintenance/programming_guide/media.html

The main requirement is lag free time skipping. I'd take that over format support or small package any day.

I tried reviving the fmod wrapper a year ago, but that one is a no go.

helgrima commented 6 years ago

Pyglet seems promising to me, as with quick look at document it seems almost trivial to play, pause, seek and get current time from song. And it even includes some functionality to generate sounds as well. That might come handy some day.

einarf commented 6 years ago

I think we can split music timers into two categories:

  1. Timers with accurate current time (position in the audio in milliseconds)
  2. Timers with accurate and efficient time seeking (so we can move in the timeline fast with the rocket editor) and current time (1)

Type 1 is not too hard to find. I think both pyglet and pygame fills that criteria. These timers can easily be used when distributing the project.

Type 2 can be used locally in development when doing timing, so it could (worst case) for example be VLCs python wrapper (requires VLC app to be installed).

Format support is still secondary here. If those timers can only load a wav file, I am fine as long as we have a solid type 2 timer in dev. Type 1 timers are probably easier to find with more flexible format support.

We also have to be sure win, linux and darwin is supported without too much hassle. There is a jungle of libraries for playback and sound generation out there. pyglet and pygame are very popular and well maintained libraries for the three main platforms, so I'm hoping they can provide. The best libraries are those with all dependencies embedded in the package for each platform. pip install and we are ready to go.

pygame does not seem to do seeking well in some quick tests, but there might ways it can do this I haven't explored. It seems to seek to a position close to the one requested and will report inaccurate positions for a couple of seconds until it recovers. The audio thread also seems to use around 200ms before audio starts after calling play again. You also get this when simply pressing space (pause) and play again (space). I tried timing with rocket, and it was a nightmare 😄

This whole area of audio is something I haven't really had much time to explore properly.

helgrima commented 6 years ago

I managed to get pybass playing song and preliminary functions of pyrocket working. I will provide you working example in few days.

einarf commented 6 years ago

Awesome! hoping that will work on the main platforms as well

helgrima commented 6 years ago

Ok, got something going, but it seems at this point this code does not work as intended, primary with seeking. It gets out of sync quite fast when working on rocket editor. So yeah, it does not fulfill requirements of category 2 timer.

But I will continue working on this matter. I have to also make sure that my "support for windows" PR on pyrocket (https://github.com/Contraz/pyrocket/commit/d9c6df884f63e66228b20ac1e1c9c2907634801d) has nothing to do with this.

Here is working example. with pybass and rocket: https://github.com/helgrima/saturday77/blob/master/music/effect.py

Or can you say if this is already completely doomed?

einarf commented 6 years ago

I have no idea what causes these delays. It's weird that even a wrapper over bass has this problem. Would anything change if you actually made a timer class for pybass instead? You can pretty much copy-paste the MusicTimer/RocketMusicTimer class and modify.

If using pybass is doomed or not, I have no idea. Maybe this is some weird artifact of using ctypes? Who knows? Can we maybe tweak on buffer sizes or other things to make seeking faster? Again, it's weird because bass never had issues with seeking speed in our C++ demosys.

When I used bass in timers I simply called ChannelPause and ChannelPlay. The timer class would just report back time using ChannelGetPosition per frame. It seems this is pretty much identical in your example, but I'm wondering if repeated calls to these functions (because they are in the actual draw function) might cause issues?

helgrima commented 6 years ago

If you have been using bass with out any problems, I think this is not yet doomed.

I will remove pybass interaction from render loop. We'll see if that makes any difference. And if that fails, I will take a look at pyglet.

For now I do not have any Linux machine running OpenGL 3.X at decent frame rate. So I cannot test this with Linux, if support for Windows is indeed affecting this.

einarf commented 6 years ago

I added a vlc timer + removed hacks from pygame.mixer timer: https://github.com/Contraz/demosys-py/tree/master/demosys/timers

you need python-vlc for that to work.

einarf commented 6 years ago

I just realized the Rocket edtitor (https://github.com/emoon/rocket) can actually load and play music. Since the editor plays the music, you don't have seeking issues.

helgrima commented 6 years ago

I never realised that either. This is great news. I will definitely try this feature, and hopefully close this issue.

einarf commented 6 years ago

Just be aware that the 2.0 branch was just merged, so things have changed pretty drastically. Docs are also very outdated. The examples are useful I guess.

einarf commented 6 years ago

Also I included your raymarching template in examples: https://github.com/Contraz/demosys-py/tree/master/examples

Feel free to scream if that shouldn't be there or simply change it 😄

einarf commented 4 years ago

It actually looks like pyglet 1.5 comes to the rescue regarding this. It plays audio on another thread and supports seeking, pause, play and time reporting. So far this has been incredibly responsive.