VS1010 3 Button Player

Designing hardware and software for systems that use the VS1010 MP3 Audio DSP Microcontroller.
Post Reply
Mikael
User
Posts: 2
Joined: Fri 2022-12-02 11:16

VS1010 3 Button Player

Post by Mikael »

The purpose of this program is to play MP3 files from user describable target folder on application specific VS1010D board. The program plays any MP3 file placed in the target folder and user is able to use 3 buttons on the board to control the playback.

Code: Select all

#include <vo_stdio.h>
#include <volink.h>
#include <apploader.h>
#include <vs1010dRom.h>
#include <vo_gpio.h>
#include <vs1010c.h>
#include <playerinfo.h>
#include <string.h>
#include <protocol.h>
#include <audio.h>
#include <ctype.h>

#define btn0 0x1c
#define btn2 0x1d
#define led 0x00

#define DEFAULTVOLUME 90

void CountFiles(const char *fileSpec){ //Counts the number of MP3 files in the target folder
	FILE *f;
	char mode[9];
	while(1){
		sprintf(mode, "rb#%u", player.totalFiles);
		f = fopen(fileSpec, mode);
		if(f){
			player.totalFiles++;
			fclose(f);
		}else{
			break;
		}
	}
	return;
}

void MyPlayerCallback(AUDIO_DECODER *auDec, u_int16 samples){ // Checks for user inputs
	static u_int16 btn0Press = 0;
	static u_int16 btn1Press = 0;
	static u_int16 btn2Press = 0;
	static u_int16 btn0Hold = 0;
	static u_int16 btn2Hold = 0;
	static u_int16 ledValue = 0;
	static u_int32 currentTime = 0;
	static u_int32 triggerTime = 0;
	static u_int16 volumePercent = 50;
	
	currentTime = ReadTimeCount();
	if(currentTime - triggerTime  >= 100){ // Check for user inputs every 50 ms
		triggerTime = currentTime;
		
		// Volume up/down button
		if(!GpioReadPin(btn2) && !btn2Press){ // If button 2 was pressed
			btn2Press = 1;
		}else if(!GpioReadPin(btn2) && btn2Press){ //If button 2 is being held
			if(btn2Hold % 5 == 0 && btn2Hold >= 10){ // If button 2 is held for more than a 500 ms
				if(volumePercent > 0){ // If volume isn't at 0%
					// Lower the volume 5%
					player.volume += 9;
					volumePercent -= 5;
					printf("\nVolume lowered\nCurrent volume: %d%%", volumePercent);
				}
			}
			btn2Hold++;
		}else if(GpioReadPin(btn2) && btn2Press){ // If button 2 was released
			if(btn2Hold < 10){ // If button 2 wasn't held
				if(volumePercent < 100){ // If volume isn't at 100%
					// Raise the volume 5%
					player.volume -= 9;
					volumePercent += 5;
					printf("\nVolume raised\nCurrent volume: %d%%", volumePercent);
				}
			}
			btn2Hold = 0;
			btn2Press = 0;
		}
		
		// Next/Previous song button
		if(GpioReadPin(btn0) && !btn0Press){ // If button 0 was pressed
			btn0Press = 1;
		}else if(GpioReadPin(btn0) && btn0Press){ // If button 0 is being held
			btn0Hold++;
			if(btn0Hold == 10){ // If button 2 is held for more than a 500 ms
				// Skip to previous song
				printf("\nSkipping to the previous song...");
				player.nextStep = -1;
				player.auDec.cs.cancel = 1;
			}
		}else if(!GpioReadPin(btn0) && btn0Press){ // If button 0 was released
			if(btn0Hold < 10){  // If button 0 wasn't held
				// Skip to next song
				printf("\nSkipping to the next song...");
				player.nextStep = 1;
				player.auDec.cs.cancel = 1;
			}
			btn0Hold = 0;
			btn0Press = 0;
		}
		
		// Play/Pause button
		if((PERIP(ANA_CF1) & ANA_CF1_PWRBTN) && !btn1Press){ // If button 1 was pressed
			if(player.auDec.pause){ // If current song is paused
				printf("\nUnpaused...");
			}else{ // If current song is playing
				printf("\nPaused...");
			}
			player.auDec.pause ^= 1; // Play/Pause
			GpioSetPin(led, ledValue); // Turn led on/off
			ledValue ^= 1;
			btn1Press = 1;
		}else if(!(PERIP(ANA_CF1) & ANA_CF1_PWRBTN) && btn1Press){ // If button 1 was released
			btn1Press = 0;
		}
	}
}

ioresult main (char *params) {
	ioresult errCode = S_ERROR;
	GpioSetAsInput(btn0);
	GpioSetAsInput(btn2);
	GpioSetPin(led, 1);
	strcpy(player.fileSpec, "F:/music/*.mp3");
	player.totalFiles = 0;
	player.nextStep = 1;
	player.volume = DEFAULTVOLUME;
	player.currentFile = 1;
	
	// If user has specified the target drive
	if(isalpha(params[0]) && params[1] == ':'){
		player.fileSpec[0] = toupper(params[0]);
	}else if(params[0]){
		printf("E: Invalid parameters.\nUsage: 3btnplayer [D:]\nD:\tDrive name\n");
		goto finally;
	}
	
	printf("Starting MP3 player from drive %c:...\n", player.fileSpec[0]);
	CountFiles(player.fileSpec);
	printf("Total files: %d\n", player.totalFiles);
	
	if(player.totalFiles > 0){ //If there was any mp3 files in target folder
		player.currentFile = 1;
		SetJmpiHookFunction(PlayerCallback, MyPlayerCallback);
		while(PlayerPlayFile() == S_OK){
			if(player.currentFile > player.totalFiles){
				player.currentFile = 1;
			}else if(player.currentFile < 1){
				player.currentFile = player.totalFiles;
			}
			player.nextStep = 1;
		}
	}else{
		printf("E: No MP3 files in %s\n", player.fileSpec);
		goto finally;
	}
	
	errCode = S_OK;
	
finally:
	SetJmpiHookFunction(PlayerCallback, DefaultPlayerCallback);
	printf("\n\nProgram stopped\n\n");
	return errCode;
}
There's a decent amount of comments in the code, but here's a short summary of it.

The first function CountFiles is called by the main function every time the program starts, and it counts all MP3 files in target folder, and saves that amount to the player.totalFiles.

The second function MyPlayerCallback replaces the DefaulPlayerCallback, and it checks if the user has pressed any of the three buttons while the track is playing. With the 3 buttons you are able to skip to the next or previous track, turn the volume up or down, and also you can play or pause the track.

The main function checks if user has specified different target drive, calls the functions and checks that the file is playable.

Remember this program is designed to run on a application specific VS1010D board which will be available soon, but with small modifications (e.g. changing the definitions and the target folder) this program can be run on different VS1010D boards, such as VS1010D developer board.

3 Button Player and a small pdf document are available to download below.
Attachments
vs1010_3btnplayer.pdf
(69.38 KiB) Downloaded 263 times
3btnplayer.zip
(72.62 KiB) Downloaded 256 times
Post Reply