Thank you for the kind support. I am here again with few more doubts.
The alternative way provided by Henrik contains more of assembly code which I am not that good at. I will stick to 'C' based solution.
The below is the MP3 player code that I have written for our application.
Code: Select all
#include <vo_stdio.h>
#include <stdlib.h>
#include <codec.h>
#include <sysmemory.h>
#include <vsos.h>
#include <apploader.h>
#include <libaudiodec.h>
#include <aucommon.h>
#include <vsostasks.h>
#include <clockspeed.h>
#include "MP3_Drv.h"
//#include "hw_config.h"
//#include "GPIO_Drv.h"
#define SET 1
#define RESET 0
volatile PlayerFlagStructure PlayerFlags;
FILE *PlayFile;
void *decoderLibrary = NULL;
AUDIO_DECODER *audioDecoder = NULL;
char *errorString = "";
int eCode = 0;
volatile int fileNum = 0;
int running = 1;
auto ioresult Load(char *filespec);
auto ioresult Play(void);
auto ioresult Pause(void);
auto ioresult NextTrack(void);
auto ioresult PreviousTrack(void);
auto ioresult FastForward(void);
auto ioresult Rewind(void);
auto ioresult VolumePlus(void);
auto ioresult VolumeMinus(void);
auto ioresult Stop(void);
auto ioresult Source(void);
void PlayerThread(void) {
eCode = DecodeAudio(decoderLibrary, audioDecoder, &errorString);
}
// this is the MP3 start file from where the MP3 processing is done.
// this function takes MP3 file path i.e. directory as argument and process according to it
// the below code is extracted from the various MP3 player examples available in the forum.
auto ioresult Load(char *filespec)
{
volatile u_int16 FileNumber=0;
static char fnumMode[MAX_FILENAME_LENGTH];
PlayFile = NULL;
decoderLibrary = LoadLibrary("audiodec");
if (!decoderLibrary) {
return S_ERROR;
}
PlayerFlags.PlayPause = RESET;
PlayerFlags.PlayPause = RESET; // 1 = Play, 0 = Pause
PlayerFlags.NextTrack = RESET;
PlayerFlags.PreviousTrack = RESET;
PlayerFlags.FastForward = RESET;
PlayerFlags.Rewind = RESET;
PlayerFlags.VolumePlus = RESET;
PlayerFlags.VolumeMinus = RESET;
PlayerFlags.Stop = RESET;
running=1;
FileNumber=0;
while(running)
{
if(PlayerFlags.Stop!=RESET)
{
break;
}
printf("Open file %d...\n",FileNumber);
sprintf(fnumMode,"rb#%d",FileNumber);
PlayFile = fopen(filespec,fnumMode); // e.g. fopen("N:MUSIC\*","rb#123");
if (PlayFile)
{
printf("Playing '%s' ",PlayFile->Identify(PlayFile,NULL,0)); //this Identify is good to be right after the fopen
printf("from device %s...\n",PlayFile->dev->Identify(PlayFile->dev,NULL,0));
RunLibraryFunction("METADATA",ENTRY_2,(int)PlayFile);
//PlayFile(PlayFile);
audioDecoder = CreateAudioDecoder(decoderLibrary, PlayFile, stdaudioout, NULL, auDecFGuess);
if (!audioDecoder)
{
printf("Couldn't create audio decoder\n");
return S_ERROR;
}
StartTask(TASK_DECODER, PlayerThread);
while (pSysTasks[TASK_DECODER].task.tc_State && pSysTasks[TASK_DECODER].task.tc_State != TS_REMOVED)
{
DelayMicroSec(100000);
if (PlayerFlags.Stop == SET) {
audioDecoder->cs.cancel = 1;
running = RESET;
PlayerFlags.Stop=RESET;
}
if (PlayerFlags.NextTrack == SET) { // > Next
audioDecoder->cs.cancel = 1;
PlayerFlags.NextTrack = RESET;
}
if (PlayerFlags.PreviousTrack == SET) { // < Previous
audioDecoder->cs.cancel = 1;
FileNumber -= 2;
PlayerFlags.PreviousTrack = RESET;
}
if(PlayerFlags.VolumePlus == SET)
{
s_int16 t = ioctl(stdaudioout, IOCTL_AUDIO_GET_VOLUME, NULL)-256;
if (t >= -256)
{
if (t > 0)
{
t--;
}
#if 0
if (t < 100)
{
t++;
}
#endif
}
ioctl(stdaudioout, IOCTL_AUDIO_SET_VOLUME, (void *)(t+256));
printf("Vol=%d\n",t);
PlayerFlags.VolumePlus = RESET;
}
if(PlayerFlags.VolumeMinus == SET)
{
s_int16 t = ioctl(stdaudioout, IOCTL_AUDIO_GET_VOLUME, NULL)-256;
if (t >= -256)
{
#if 0
if (t > 0)
{
t--;
}
#endif
if (t < 100)
{
t++;
}
}
ioctl(stdaudioout, IOCTL_AUDIO_SET_VOLUME, (void *)(t+256));
printf("Vol=%d\n",t);
PlayerFlags.VolumeMinus = RESET;
}
if(PlayerFlags.FastForward == SET)
{
PlayerFlags.FastForward = RESET;
}
if(PlayerFlags.Rewind == SET)
{
PlayerFlags.Rewind = RESET;
}
}
DeleteAudioDecoder(decoderLibrary, audioDecoder);
fclose(PlayFile);
FileNumber++;
}
else {
printf("File %d not found, finished playing.\n",fileNum+1);
FileNumber=0; //Restart from first file
break; //end of files, end playing
}
}
DropLibrary(decoderLibrary);
return S_OK; //End of files, ok exit
}
auto ioresult Play(void){
PlayerFlags.PlayPause = 1;
return S_OK;
}
auto ioresult Pause(void){
PlayerFlags.PlayPause = 0;
return S_OK;
}
auto ioresult NextTrack(void){
PlayerFlags.NextTrack = 1;
return S_OK;
}
auto ioresult PreviousTrack(void){
PlayerFlags.PreviousTrack = 1;
return S_OK;
}
auto ioresult FastForward(void){
PlayerFlags.FastForward = 1;
return S_OK;
}
auto ioresult Rewind(void){
PlayerFlags.Rewind = 1;
return S_OK;
}
auto ioresult VolumePlus(void){
PlayerFlags.VolumePlus = 1;
return S_OK;
}
auto ioresult VolumeMinus(void){
PlayerFlags.VolumeMinus = 1;
return S_OK;
}
auto ioresult Stop(void){
PlayerFlags.Stop = 1;
return S_OK;
}
auto ioresult Source(void){
// not yet implemented
return S_OK;
}
1) PlayFile = fopen(filespec,fnumMode); // e.g. fopen("N:MUSIC\*","rb#123");
in example code it says like "rb#123" I assume it as file number but I don't know how it is numbered or is it the right way of picking file or do we have to name the complete file name. Will the above line automatically searches for the file in the path specified and fetches the data from it. if it searches then will it be index based or filename based.If indexbased, how does the indexing of files done in the filesystem. i.e. automatically by the filesystem or we have to name the files with numbers as filename.
2) RunLibraryFunction("METADATA",ENTRY_2,(int)PlayFile);
may I know what "METADATA" does here and what does "ENTRY_2" does and what does "(int)PlayFile" returns, as PlayFile is of type FILE
3) StartTask(TASK_DECODER, PlayerThread);
is the "StartTask" function predefined and is that TASK_DECODER is predefined for audio decode or just a #define mentioned in one of the header file.
4) while (pSysTasks[TASK_DECODER].task.tc_State && pSysTasks[TASK_DECODER].task.tc_State != TS_REMOVED)
I don't know what the above line do. All I did was copy paste the example line. I assume it as the current state of the thread
5) How does the FILE fetches the next MP3 frame to play continuously. as I am not calling anywhere to read the file again.
6) eCode = DecodeAudio(decoderLibrary, audioDecoder, &errorString);
what does the above line do. I am still confused how would this VS1005 manage to pick the next mp3 frame and play continuously.
I am afraid VS1005 has less documented details of API used by VSOS. If we have one, please do share the API apart from the one searching from header files. Header files only give the declaration of a particular variable or function but it does not explain the properties of what actually the function do.
I have a lot of doubts about USB interfacing as Host .. but will add it once I am clear with the MP3 part.
Its my request to VLSI team to excuse me on my typical doubts which may be silly to experts.