How to pause and resume song using Mbed code

Got any ideas?

Hi there,

Mbed community is full of ideas, but your description is insufficient.

  • What device is playing those songs?
  • How the Mbed will be connected to that device?

BR, Jan

I will share the code here later on and i want to know how to pause and resume the song using InterruptIn

use a single thread with thread::flags_set(pause or stop),

can give one example?

#include "mbed.h"

InterruptIn button(BUTTON1);

volatile bool pressed = false;

void  buttonPress()
{
    if(!pressed) pressed = true;
}

int main()
{
    button.fall(callback(&buttonPress));
    //  main thread
    while(1) 
    {
        if(pressed)
        {
            // do something magic here 
            

            // clean after job done for another intrrupt
            pressed = false;
        }
        // rest of loop
    }
}

But there are many variants how you can solve it and it depends on your requirements. Usually simple InterruptIn - API references and tutorials | Mbed OS 6 Documentation or with combination of

BR, Jan

May i know why use callback instead of using &

I am not sure, but I did it like that, because that documentation says - void fall (Callback< void()> func ).
But probably it doesn’t matter because Callbacks are implemented also inside the API in this case.

Callback - API references and tutorials | Mbed OS 6 Documentation

BR, Jan

For the example u provided , does it helps when it pause the song and then the song will continue after resume button. I just no idea how to make the song pause at the tone and resume at the tone.

If I understand your code correctly you only periodically execute the tune_player function via ticker where is also incremented variable k (probably index of array of current song), set volume and so on.
So you can just make another if statement (with a bool variable connected to pause function) in your tune_player function what will mute speaker and skip incrementation of variable k.

BR, Jan

For example the music is running then I will pause it using button3 as an interrupt pin, then resume the tone using another button, but I no idea how to code it. I thinking on how to mute the speaker also , when I put speaker = 0 then it does not work. I also want to know like any code that can pause the tone , need some help on coding part .

I do not know/have your hardware so I can not make verified code.

void tune_player(){
	if (k<allsongs[song_index].length){
		if(pause){ //a boolean what will be controlled by your buttons
			speaker = 0;
		}
		else{
			//Set the PWM duty cycle to zero, if there is a sound pause
			if(*(allsongs[song_index].note +k) == No) speaker = 0;            
			//Set the PWM period, which determines the note of the sound
			else {
				speaker.period(0.001*(*(allsongs[song_index].note + k)));   
				speaker = Volume;
			}               
			
			k++;

			//Set the time for the next ticker interrupt
			timer.attach(&tune_player,(allsongs[song_index].beat[k]/3)+(allsongs[song_index].tempo/2));
		}
    }
    else{
        //If the musical piece is finished, start again
        k = 0;                                                                  
        speaker = 0;
    }
}

BR, Jan

You just added this line of code right , then how about resume it?

Yeah. You somewere must change valeu of variable pause. Probably something like this

volatile bool pauseButtonPressFlag = false;
volatile bool pauseState = false;

void  buttonPausePress()
{
    if(!pauseButtonPressFlag){
		pauseButtonPressFlag = true; // set true for prevent another change before it will be processed
		pauseState != pauseState;	// negate last state
	} 
}

void tune_player(){
	if (k<allsongs[song_index].length){
		if(pauseState){ // if it is true, then it will skip playing next tone and also not increment the index, else it will be as normal.
			speaker = 0; // off audio
            pauseButtonPressFlag = false; // clean for another interrupt
		}
		else{
			//Set the PWM duty cycle to zero, if there is a sound pause
			if(*(allsongs[song_index].note +k) == No) speaker = 0;            
			//Set the PWM period, which determines the note of the sound
			else {
				speaker.period(0.001*(*(allsongs[song_index].note + k)));   
				speaker = Volume;
			}               
			
			k++;

			//Set the time for the next ticker interrupt
			timer.attach(&tune_player,(allsongs[song_index].beat[k]/3)+(allsongs[song_index].tempo/2));
		}
    }
    else{
        //If the musical piece is finished, start again
        k = 0;                                                                  
        speaker = 0;
    }
}

BR, Jan

may I know what is mean by this pauseState != pause, then the pause is from? or Isit pauseState, not pause

My bad, sorry. Now it is correct I hope :slight_smile:

BR, Jan

You tried to send me a private message probably.
So what is it doing now?

BR, Jan

It can’t execute the if (pauseState) loop

Sorry, but that tell me nothing :slight_smile:

Happy Birthday with Buzzer
#include "mbed.h"

#define TONE_A4      440        
#define TONE_B4b     446         
#define TONE_C4      261
#define TONE_C4_1    130 
#define TONE_C5      523      
#define TONE_D4      293   
#define TONE_D4b     277               
#define TONE_E4      329          
#define TONE_F4      349           
#define TONE_G4      392  

// Happy Birthday
float notes[] = {TONE_C4_1,TONE_C4,TONE_D4,TONE_C4,TONE_F4,TONE_E4,TONE_C4_1,TONE_C4,TONE_D4,TONE_C4,TONE_G4,
                TONE_F4,TONE_C4_1,TONE_C4,TONE_C5,TONE_A4,TONE_F4,TONE_E4,TONE_D4,TONE_B4b,TONE_B4b,TONE_A4,TONE_F4,TONE_G4,TONE_F4};
float interval[] = {4, 4, 8, 8, 8, 10, 4, 4, 8, 8, 8, 10, 4, 4, 8, 8, 8, 8, 8, 4, 4, 8, 8, 8, 12};                            
   

PwmOut buzzer(D5);
Timeout playTimeOut;
Timeout stopTimeOut;
InterruptIn bPlay(BUTTON1); //onboard button
InterruptIn bStop(D8);      // external button

volatile bool bPlayPressed = false;
volatile bool bStopPressed = false;

void playButtonTimeOut();
void buttonPlayPress();
void stopButtonTimeOut();
void buttonStopPress();

int main()
{
    printf("Buzzer melody test\n");
    printf("Press Play button for PLAY or Pause and STOP button for.... you know\n");
    bStop.mode(PullUp); // because of external button

    bPlay.fall(callback(buttonPlayPress));
    bStop.fall(callback(buttonStopPress));
    int i=0;
    printf("loop\n");
    // The main thread
    while(1) {
        if(bPlayPressed){
            printf("Play\n");
            for (;i<(sizeof(notes))/sizeof(float);i++) {
                printf("Tone %d\n", i);
                if(bStopPressed){
                    printf("Stop\n");
                    i = 0;
                    bPlayPressed = false;
                    bStopPressed = false;
                    break;
                }
                if(bPlayPressed){
                    float tempTone = 1/notes[i];
                    if(tempTone != 0) buzzer.period((1/notes[i]));      // set PWM period
                    buzzer=0.5;                                         // set duty cycle
                    thread_sleep_for((0.8*interval[i]/10)*1000);        // hold for beat period
                }else{
                    printf("Paused\n");
                    thread_sleep_for(300);
                    buzzer=0;
                    i--;
                }
            } 
            printf("Over\n");
            buzzer=0;
            i = 0;
            bPlayPressed = false;
        }
        // rest of loop
    }
}

void  buttonPlayPress()
{
    bPlayPressed =!bPlayPressed ; // revert last state
    bPlay.fall(nullptr); // interrupt OFF
    playTimeOut.attach(callback(playButtonTimeOut), 300ms); // set interrupt ON after a time
}

void playButtonTimeOut(){
    bPlay.fall(callback(buttonPlayPress)); // interrupt ON
}

void  buttonStopPress()
{
    bStopPressed = true;
    bStop.fall(nullptr);
    playTimeOut.attach(callback(playButtonTimeOut), 300ms);
}

void stopButtonTimeOut(){

    bStop.fall(callback(buttonStopPress));
}

BR, Jan

May i know what is mean by this code?