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;
}
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.