Need advises for a simple player class


#1

Hi all,

I’m looking for the best way to implement a simple wav file player that do not give hand to the main thread until the end of the file… For example to play 2 wav files separated by a 500ms silence I would like to implement it like that

wavplayer.play(“sound1.wav”);

Time::waitForMillisecondCounter(Time::getMillisecondCounter()+500);

wavplayer.play(“sound2.wav”);

// sound2 ended… let’s do some other stuff…

How will you do it (or something similar) ?

Thanks in advance…
Sylvain


#2

You might get a lot of mileage out of BufferingAudioSource and WavAudioFormat


#3

Thanks for your answer…

I have never used BufferingAudioSource and I just have read the description… But I do not know how it can help me. why did you propose that ?

I may have not been very clear in my question. I have yet built several JUCE based apps in which I had to play sound files. But in these I was happy to have the sound playing without blocking the main thread.

However for my use, it would be very efficient to be abble to linearily implements a sound sequence… Play(“sound1.wav”);wait(500);Play(“sound2.wav”);

The problem when “soun1.wav” was launched is to detect the end of the sound to continue with the “wait” and then sound2… That’s why I would like to implement such a player that I can use in several apps.

Thanks in advance for any help.

Sylvain


#4

I was under the impression you did NOT want to block the gui thread.

Have a thread whose job it is to play an AudioSource until its done. Keep a list of AudioSource, when the current one is finished, start the next one. You might need to subclass your AudioSource so you know when its finished.


#5

[quote=“TheVinn”][quote=“wphantom”]
Have a thread whose job it is to play an AudioSource until its done. Keep a list of AudioSource, when the current one is finished, start the next one. You might need to subclass your AudioSource so you know when its finished.[/quote][/quote]

That’s the problem… knowing when it’s finished. I was planning to subclass my source so that when creating the source I can specify a callback function that will be trigered by the source when it’s finished. Is there any example of how to implement a callback system ?

Sylvain


#6

No example, but you might have a look at ChangeBroadcaster/ChangeListener or ActionBroadcaster/ActionListener.

Chris


#7

There are a ton of ways this could be done. What I’ve done in the past is to use some enhanced MixerAudioSource where each source has a start position so you can effectively set them in time. Not sure this is right for your needs though, how accurate do you need the 500ms to be?

For this I would probably do as Vinn says and keep an OwnedArray of AudioTransportSources that you want to play and a pointer for the currently playing one. You should also inherit from ChangeListener and Timer. When you add a new AudioTransportSource register yourself as a listener to it. Once the source has finished your changeListenerCallback will be called and you can check if the source has stopped using AudioTransportSource::isPlaying(). If this returns false find the index of the one just finished using OwnedArray::indexOf() and set the currently playing pointer to the next element. Then call startTimer (500) and in your timerCallback() method start the transport source.

Obviously you’ll need to pay some attention to thread safety with the pointers etc. or you could use an indexing variable as the ‘currently playing’ and find the correct source with the OwnedArray::[] operator.

You could build this up and have another array with your wait times and use the array as a stack so once an item has finished it is removed. Then you could do as you originally intended and have some interface similar to Player::add (File newFile); Player::wait (500); Player::add (File newFile2); etc.

Just my 2 cents.


#8

This is exactly the info I was looking for. I didn’t that a message was send automatically at the end of the source. it does not appears explicitely in the API documentation. That was my main problem. I will try this.

it was far more than 2 cents :smiley:

Thanks all for the help. I will try to implement all this tomorrow.

Sylvain


#9

just a return: it works perfectly with the approach of Vinn & Dave…

Thanks guy

Sylvain


#10

Have you considered contributing your app as a demo in AppletJUCE?

[size=120]https://github.com/vinniefalco/AppletJUCE[/size]

I’m sure other people would love to learn from your example! Put your name in the about box of course.