Main Site Documentation

Driver - Music module driver accepting streams


#1

[title]Music module driver accepting streams[/title]
http://code.tinyclr.com/project/431/music-module-driver-accepting-streams/
[line]
Added functionality to the .NET Gadgeteer Music Module driver to play from Streams.

Original source from:


#2

Playing a 192kbps MP3 was no propblem, but a 320kbps MP3 file was a no-go.

I needed this functionality for my internet radio streamer.


#3

Have a look here: http://tinyclr.com/forum/20/5378/#/2/msg53389
I’ve managed to play 800Kbps flacs. 320Kbps works with (pretty) fluid UI.


#4

@ godFather89 I already found that thread, but I’ve just outgrown my “newbie” status and this is a little bit to complex for me to understand and implement.

But nevertheless, thanks for the link.


#5

This is a very cool project. It deserves a video :slight_smile:


#6

New link is at http://www.tinyclr.com/codeshare/entry/368


#7

Hi
I’m using the code from the last link and it works fine until you try to play a second mp3 file.
So it says that it is playing, then stopping then playing again then nothing.
Not even an error message…
It looks like it isn’t resetting correctly?
Andy


#8

@ peony3000 - Welcome.
I am using a slightly modified version of that code to load mp3’s from SD card and it works fine for me.
I have a global FileStream that i load the mp3 into and all good.


#9

Thanks Justin,

It was enough of a clue to get me to look in a different place…
http://pastebin.com/HFgz9DqZ

Andy


#10

Did GHI ever thinking including code to the source on codeplex?


#11

Hi,

I’m trying to do a music streaming project in 4.2 and it #### Message: Failed to initialize MP3 Decoder.

I have rebuilt the driver with the latest 4.2.

Does Mischa Boender need to update this?
http://www.tinyclr.com/codeshare/entry/368

Or I agree with Makla! “Did GHI ever think [to] include [the] code to the source on codeplex?”

Sounds like a good idea.

Andy


#12

I have used it in a 4.2 project just by changing a few lines…


#13

Can you give me a clue?


#14

@ peony3000 - sorry I should have mentioned…

I am using it on a G120HDR with vanilla NetMf not Gadgeteer so I just changed the sockets to CPU pins.

That’s about it. I think from memory it worked as is on a Bee for me reading from sd card.


#15

I downloaded source code, recompiled it and it works with my Spider.


#16

@ peony3000 - Take a look at this codeshare:

http://www.tinyclr.com/codeshare/entry/269

It is essentially same hardware just in a different form factor (shield). That driver is pure NetMF non-Gadgeteer code.


#17

Hi Makla,

I also did that but it doesn’t seem to know when the music has stopped

It reports that wrongly

If you have a second audio file waiting for music finished it plays too soon

Any ideas?

Andy


#18

I forgot but this seems to be the solution (but it doesn’t make sense to me) and " // You can’t call music.StopPlaying or set volume with this loop running. "

while (music.IsBusy)
{
Thread.Sleep(10);
}

Thanks to Mike (again!)


#19

When I try to answer peony3000, I found some strange code.
I try to write this:


        FileStream stream;
        private void Play()
        {
            stream = new FileStream(@ "\SD\Sounds\Cesarica.mp3", FileMode.Open);
            matjazMusic.MusicFinished += new MatjazMusic.MusicFinishedPlayingEventHandler(matjazMusic_MusicFinished);
            matjazMusic.Play(stream);
        }

        void matjazMusic_MusicFinished(MatjazMusic sender)
        {
            matjazMusic.Play(stream);
        }

Of course it is not working, because drivers after calling finished dispose stream.
So i try:


        private void Play()
        {
            matjazMusic.MusicFinished += new MatjazMusic.MusicFinishedPlayingEventHandler(matjazMusic_MusicFinished);
            matjazMusic.Play(new FileStream(@ "\SD\Sounds\CesaricaCut.mp3", FileMode.Open));
        }

        void matjazMusic_MusicFinished(MatjazMusic sender)
        {
            matjazMusic.Play(new FileStream(@ "\SD\Sounds\Cesarica.mp3", FileMode.Open));
        }

Two different files. But i get null exception. After reading the code, that sounds logic.
First MusicFinished is raised. Here you call new play. In Play method, the m_playblackStream is set to new stream. And then new thread is started. After that the MusicFinished event is finished, and the code continue in drivers where it dispose the new stream and raise null exception.


        private void PlayBackStreamThreadFunction()
        {
            byte[] block = new byte[32];
            m_SPI.Config = m_dataConfig;
            while (m_playblackStream.Read(block, 0, 32) > 0)
            {
                if (_stopPlayingRequested)
                    break;
                while (m_dreq.Read() == false)
                    Thread.Sleep(1); // wait till done
                m_SPI.Write(block);
            }

            this.OnMusicFinished(this);   //!!! here new play is called, so the m_playblackStream is set to new value.

            if (m_playblackStream != null)
            {
                m_playblackStream.Close();
                m_playblackStream = null;
            }
            Reset();
            _isPlaying = false;
        }

If you can wait wait a week and i will fix this. Probably by starting one thread and add some ResetEvent.
Something like this:


        private void PlayBackStreamThreadFunction()
        {
            while (true)
            {
                resetevent.WaitOne();

                byte[] block = new byte[32];
                m_SPI.Config = m_dataConfig;
                while (m_playblackStream.Read(block, 0, 32) > 0)
                {
                    if (_stopPlayingRequested)
                        break;
                    while (m_dreq.Read() == false)
                        Thread.Sleep(1); // wait till done
                    m_SPI.Write(block);
                }

                if (m_playblackStream != null)
                {
                    m_playblackStream.Close();
                    m_playblackStream = null;
                }

                Reset();
                _isPlaying = false;

                this.OnMusicFinished(this);   ///maybe add event parameter to reply or AutoCloseStream (true/false)
            }
        }

Meanwhile you can fix the drivers by putting this.OnMusicFinished(this); after closing the stream, and use my second example with 2 different FileStreams.


#20

Hello,

can someone post a working music class, which is workling correctly with the spider?

I’ve tried the code on the previous page, but i cannot stop the playback.