Main Site Documentation

Music Module Bug?


#1

I was playing with a music module this morning and noticed that if a MusicFinished event handler was not defined a null exception occurred in the module driver.

I suspect that the driver does not check the MusicFinished event for null before calling it.

if (MusicFinished != null)
    MusicFinished(...);
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace GadgeteerMusicModuleTest
{
    public partial class Program
    {
        private byte[] song = null;

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            button.ButtonReleased += new Button.ButtonEventHandler(button_ButtonReleased);
            song = Resources.GetBytes(Resources.BinaryResources.PhoneRingInternal);
            // null exception if the following line is commented out
            music.MusicFinished += new MusicFinishedPlayingEventHandler(music_MusicFinished);
        }

        void music_MusicFinished()
        {
            Debug.Print("Music finished");
        }

        void button_ButtonReleased(Button sender, Button.ButtonState state)
        {
            music.Play(song);  
        }
    }
}

#2

Mike,

You are correct. I have just verified it on codeplex.


        /// <summary>
        /// Playback thread function
        /// </summary>
        private void PlayBackThreadFunction()
        {
            byte[] block = new byte[32];

            int size = m_playBackData.Length - m_playBackData.Length % 32;

            m_SPI.Config = m_dataConfig;
            for (int i = 0; i < size; i += 32)
            {
                if (_stopPlayingRequested)
                    break;

                Array.Copy(m_playBackData, i, block, 0, 32);

                while (m_dreq.Read() == false)
                    Thread.Sleep(1);  // wait till done
                
                // fake spinlock is fake
                while (true)
                {
                    if (!m_bPlayLocked)
                    {
                        //someone still has the spi
                        Thread.Sleep(1);
                    }
                    else
                    {
                        // we can have the spi back
                        m_SPI.Config = m_dataConfig;
                        break;
                    }
                }

                // pause goes here
                //while(paused)
                    //sleep(1)

                m_SPI.Write(block);
            }

            // TODO: throw event here
            //_MusicFinished = new MusicFinishedPlayingEventHandler(this.MusicFinished);
            this.MusicFinished();

            Reset();

            m_playBackData = null;
            _isPlaying = false;
        }


#3

@ Valen

I just finished downloading the source from CodePlex, verified the problem, and came here to post. You beat me to it! >:(


#4

Sorry,man. Didn’t mean to hijack your thread :-[


#5

You are cool man :smiley:


#6

Fix was uploaded to Codeplex.