This sample will play a ".wav" file of the USB root folder. Only RIFF format, 48kHz, 16bit, 2ch.

Dependencies:   USBHostDac USBHost_custom_Addiso

Fork of USBHostDac_example by GR-PEACH_producer_meeting

Isochronous transfer sample for GR-PEACH. This sample will play a ".wav" file of the USB root folder. Only RIFF format, 48kHz, 16bit, 2ch.

/media/uploads/dkato/usbdacsample.png
The default setting of serial communication (baud rate etc.) in mbed is shown the following link.
Please refer to the link and change the settings of your PC terminal software.
The default value of baud rate in mbed is 9600, and this application uses baud rate 9600.
https://developer.mbed.org/teams/Renesas/wiki/GR-PEACH-Getting-Started#install-the-usb-serial-communication

main.cpp

Committer:
dkato
Date:
2015-04-01
Revision:
0:39320363f99f
Child:
1:82fe51d45902

File content as of revision 0:39320363f99f:

#include "mbed.h"
#include "USBHostDac.h"
#include "USBHostMSD.h"

DigitalOut led(LED1);
DigitalIn  button(USER_BUTTON0);

#define READ_BUFF_SIZE         (4096)
#define READ_BUFF_NUM          (3)
#define MAIL_QUEUE_SIZE        (READ_BUFF_NUM - 1)
#define FILE_NAME_LEN          (64)

typedef struct {
    uint8_t * p_data;
    uint32_t  data_size;
    bool      flush;
} mail_t;
Mail<mail_t, MAIL_QUEUE_SIZE> mail_box;

static uint8_t read_buff[READ_BUFF_NUM][READ_BUFF_SIZE];
static uint32_t read_buff_no = 0;

void usbdac_task(void const*) {
    USBHostDac usbdac;

    while(1) {

        // try to connect a usbdac device
        while(!usbdac.connect()) {
            Thread::wait(500);
        }

        // in a loop, print all characters received
        // if the device is disconnected, we try to connect it again
        while (1) {
            // if device disconnected, try to connect it again
            if (!usbdac.connected()) {
                break;
            }

            osEvent evt = mail_box.get();
            if (evt.status == osEventMail) {
                mail_t *mail = (mail_t *)evt.value.p;
                usbdac.send(mail->p_data, mail->data_size, mail->flush);
                mail_box.free(mail);
            }
        }
    }
}

static bool analyze_wav_heder(FILE * fp) {
    bool result = false;
    size_t read_size;
    uint8_t wk_read_buff[36];
    uint32_t fmt_size;
    uint16_t ch;
    uint32_t sampling_rate;
    uint16_t block_size;

    read_size = fread(&wk_read_buff[0], sizeof(char), sizeof(wk_read_buff), fp);
    if (read_size < sizeof(wk_read_buff)) {
        // do nothing
    } else if (memcmp(&wk_read_buff[0], "RIFF", 4) != 0) {
        // do nothing
    } else if (memcmp(&wk_read_buff[8], "WAVE", 4) != 0) {
        // do nothing
    } else if (memcmp(&wk_read_buff[12], "fmt ", 4) != 0) {
        // do nothing
    } else {
        result = true;
        fmt_size = ((uint32_t)wk_read_buff[16] << 0)
                 + ((uint32_t)wk_read_buff[17] << 8)
                 + ((uint32_t)wk_read_buff[18] << 16)
                 + ((uint32_t)wk_read_buff[19] << 24);
        ch = ((uint32_t)wk_read_buff[22] << 0) + ((uint32_t)wk_read_buff[23] << 8);
        sampling_rate = ((uint32_t)wk_read_buff[24] << 0)
                      + ((uint32_t)wk_read_buff[25] << 8)
                      + ((uint32_t)wk_read_buff[26] << 16)
                      + ((uint32_t)wk_read_buff[27] << 24);
        block_size = ((uint32_t)wk_read_buff[34] << 0) + ((uint32_t)wk_read_buff[35] << 8);

        if ((ch == 2) && (block_size == 16) && (sampling_rate == 48000)) {
            fseek(fp, 28 + fmt_size, SEEK_SET);
        } else {
            result = false;
        }
    }

    return result;
}

void msd_task(void const *) {
    FILE * fp = NULL;
    DIR  * d = NULL;
    char file_path[sizeof("/usb/") + FILE_NAME_LEN];

    USBHostMSD msd("usb");

    while(1) {
        // try to connect a MSD device
        while(!msd.connect()) {
            Thread::wait(500);
        }

        // in a loop, append a file
        // if the device is disconnected, we try to connect it again
        while(1) {
            // if device disconnected, try to connect again
            if (!msd.connected()) {
                break;
            }

            if (fp == NULL) {
                // file search
                if (d == NULL) {
                    d = opendir("/usb/");
                }
                struct dirent * p;
                while ((p = readdir(d)) != NULL) {
                    size_t len = strlen(p->d_name);
                    if ((len > 4) && (len <= FILE_NAME_LEN) && (memcmp(&p->d_name[len - 4], ".wav", 4) == 0)) {
                        strcpy(file_path, "/usb/");
                        strcat(file_path, p->d_name);
                        fp = fopen(file_path, "r");
                        if (analyze_wav_heder(fp) == false) {
                            fclose(fp);
                            fp = NULL;
                        } else {
                            printf("%s\n", p->d_name);
                            break;
                        }
                    }
                }
                if (p == NULL) {
                    closedir(d);
                    d = NULL;
                }
            } else {
                // file read
                size_t read_size = fread(&read_buff[read_buff_no][0], sizeof(char), READ_BUFF_SIZE, fp);
                if (read_size > 0) {
                    mail_t *mail = mail_box.alloc(osWaitForever);
                    if (mail != NULL) {
                        mail->p_data = &read_buff[read_buff_no][0];
                        mail->data_size = read_size;
                        if (read_size < READ_BUFF_SIZE) {
                            mail->flush = true;    // last data
                        } else {
                            mail->flush = false;
                        }
                        mail_box.put(mail);
                        read_buff_no++;
                        if (read_buff_no >= READ_BUFF_NUM) {
                            read_buff_no = 0;
                        }
                    }
                }

                // file close
                if ((read_size < READ_BUFF_SIZE) || (button == 0)) {
                    fclose(fp);
                    fp = NULL;
                    Thread::wait(500);
                }
            }
        }

        // close check
        if (fp != NULL) {
            fclose(fp);
            fp = NULL;
        }
        if (d != NULL) {
            closedir(d);
            d = NULL;
        }
    }
}

int main() {
    Thread usbdaclTask(usbdac_task, NULL, osPriorityNormal, 1024 * 4);
    Thread msdTask(msd_task, NULL, osPriorityNormal, 1024 * 4);
    while(1) {
        led=!led;
        Thread::wait(500);
    }
}