My first attempt of Thread based mp3 player with mbed RTOS *player thread *volume control thread

Dependencies:   mbed VS1053b

Thread_mp3/main_mp3.cpp

Committer:
takashikojo
Date:
2012-03-19
Revision:
0:82078eeba8ba
Child:
1:4d5a54104bbb

File content as of revision 0:82078eeba8ba:

/* mbed MP3 Shield Player - Testapplication for VLSI VS1053b Lib
 * Copyright (c) 2010 Christian Schmiljun
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */


#include "mbed.h"
#include "rtos.h"

#include "defines.h"
#include "VS1053.h"


// Volume [ 0x0000 (loud) .. 0xFEFE (quiet) ]
#define VOLUME -22.0f
// Switch for local filesystem or SDCard
// #define USE_SDCARD

// ----------------------------------------------------------------------------
//
// Pin Assigenment for SDCard on Cool Components Workshop Board
//
// SDCard             |  mbed Side
// ---------------------------------------
//  mosi-----------------5
//  miso-----------------6
//  sclk-----------------7
//  cs-------------------8
//
// ----------------------------------------------------------------------------
#ifdef USE_SDCARD
#include "SDFileSystem.h"
SDFileSystem sd(p5, p6, p7, p8, "sd");
#define DIR_NAME "/sd/Musik"
#endif

#ifdef LOCAL_FILE
LocalFileSystem sd("local");
#define DIR_NAME "/local"
#endif

#define MSC_FILE
#ifdef MSC_FILE
#include "MSCFileSystem.h"
MSCFileSystem sd("msc");
#define DIR_NAME "/msc"
#endif



// ----------------------------------------------------------------------------
//
// Pin Assigenment for Arduino MP3 Shield
// (VS1053 employed, issued by sparkfun.com)
//
// MP3 Sheild Side   |  mbed Side
// ---------------------------------------
//  RX-------------------10 (optional)
//  TX-------------------09 (optional)
//  D2(BSYNC)------------11
//  D3(DREQ)-------------10
//
//  D9(CS)---------------8
//
//  D11(MOSI)------------5
//  D12(MISO)------------6
//  D13(SCK)-------------7
//
//  GND------------------GND(1)
//  5V-------------------VU(39)
//  RESET----------------9
//
// ----------------------------------------------------------------------------
const int VS1053B_BUFFER_SIZE = (8 * 1024 + 1);
char VS1053_BUFFER[VS1053B_BUFFER_SIZE];
char* VS1053B_BUFFER_POINTER  = VS1053_BUFFER;
VS1053 mp3( p5, p6, p7, p8, p9, p10, p11, VS1053_BUFFER, VS1053B_BUFFER_SIZE);

// Serial for Debug
Serial pc(USBTX, USBRX);

Ticker timer;
Ticker timer2;

DigitalIn _DREQ(p11);
bool next = false;

void statisticsOutput();

void setVolume(void const *) {
    while (1) {
        if (pc.readable()) {
            unsigned char c = pc.getc();
// scanf ("%x",&i);
            switch (c) {
                case '1':
                case '2':
                case '3':
                case '4':
                    mp3.setPlaySpeed(c - 48);
                    break;
                case '+':
                    mp3.setVolume(mp3.getVolume() + 0.5);
                    break;
                case '-':
                    mp3.setVolume(mp3.getVolume() - 0.5);
                    break;
                case 'k':
                    mp3.setVolume(mp3.getBalance() + 0.5);
                    break;
                case 'l':
                    mp3.setVolume(mp3.getBalance() - 0.5);
                    break;
                case 'a':
                    mp3.setTrebleFrequency(mp3.getTrebleFrequency() + 1000);
                    break;
                case 'y':
                    mp3.setTrebleFrequency(mp3.getTrebleFrequency() - 1000);
                    break;
                case 's':
                    mp3.setTrebleAmplitude(mp3.getTrebleAmplitude() - 1);
                    break;
                case 'x':
                    mp3.setTrebleAmplitude(mp3.getTrebleAmplitude() + 1);
                    break;
                case 'd':
                    mp3.setBassFrequency(mp3.getBassFrequency() + 10);
                    break;
                case 'c':
                    mp3.setBassFrequency(mp3.getBassFrequency() - 10);
                    break;
                case 'f':
                    mp3.setBassAmplitude(mp3.getBassAmplitude() - 1);
                    break;
                case 'v':
                    mp3.setBassAmplitude(mp3.getBassAmplitude() + 1);
                    break;
                case 'z':
                    timer.attach(&statisticsOutput, 1);
                    break;
                case 'u':
                    timer.detach();
                    break;
                case 'i':
                    statisticsOutput();
                    break;
                case 'h':
                    mp3.play();
                    break;
                case 'j':
                    mp3.pause();
                    break;
                case 'n':
                    next = true;
                    break;
                default:
                    break;
            }
        }
        Thread::wait(100) ;
    }
}



void statisticsOutput() {
    printf("Statistics\r\n");
    printf("Buffer - Size: %i, Free: %i, Loaded: %i\r\n", mp3.bufferLength(), mp3.bufferFree(), mp3.bufferCount());
    printf("DREQ: %#x\r\n", _DREQ.read());
}

DigitalOut led2(LED2); // Ticker for mp3

void main_mp3 (void const *argument) {

    // ------------------------------------------------------------------------
    //  MP3 Initialising
    // ------------------------------------------------------------------------
    printf("Initialize mp3 Codec...\r\n");
    mp3.initialize();
    printf("mp3 Codec is initialized\r\n");


    mp3.setVolume(VOLUME);
    // pc.attach(&setVolume);
    Thread t(setVolume , NULL, osPriorityNormal, (DEFAULT_STACK_SIZE));

    // ------------------------------------------------------------------------
    //  Play mp3 file
    // ------------------------------------------------------------------------

    //while (1)
    {
        DIR *d;
        struct dirent *p;
        d = opendir(DIR_NAME);
        if (d != NULL) {
            while ((p = readdir(d)) != NULL) {
                static char str[160] = DIR_NAME;

                //check extension
                char * extension =strrchr( p->d_name,'.') + 1;
                bool isAudioFile = false;
                if (strcmp(extension, "mp3") == 0)
                    isAudioFile = true;
                else if (strcmp(extension, "MP3") == 0)
                    isAudioFile = true;
                else if (strcmp(extension, "mp4") == 0)
                    isAudioFile = true;
                else if (strcmp(extension, "MP4") == 0)
                    isAudioFile = true;
                if (isAudioFile ) {
                    printf("Now Playing: %s\r\n", p->d_name);

                    sprintf(str, "%s/%s", DIR_NAME, p->d_name);
                    printf("Path %s\r\n", str);

                    FILE *song;

                    static char array[2048];

                    song = fopen(str, "rb");
                    //song = fopen("/sd/Musik/01.mp3", "rb");

                    if (!song) {
                        printf("Couldn't open %s\r\n", str);
                        continue;
                        //exit(1);
                    }

                    int count = 0;
                    bool test = true;

                    while (!feof(song) && !next) {
                        int n=fread(&array, 1, sizeof(array), song);
                        while (mp3.bufferFree() < n) {
                            led2 = 1 ;
                            Thread::wait(100) ;
                            led2 = 0 ;
                        }
                        mp3.bufferPutStream(array,n);
                        if (count > 2 && test) {
                            test = false;
                            mp3.play();
                        }
                        count++;
                    }
                    if (next) {
                        mp3.stop();
                        next = false;
                    } else {
                        mp3.terminateStream();
                    }
                    fclose(song);  //close the file

                    printf("End of song.\r\n");
                    wait(1.0);
                } else {
                    printf("File ignored. Extension: %s\r\n", extension);
                }

            }
            closedir(d);
        } else {
            error("Could not open directory!");
            //        break;
        }

    }
    printf("Done.\r\n");

}