Hardware/EIR/Vorbis Rec

From Nutwiki
Jump to navigationJump to search

EIR Ogg Vorbis Recorder

By default, the VS1053 audio codec on the EIR board offers PCM recording only. However, VLSI Solution offers an Ogg Vorbis encoder plug-in. We will use this here to record an audio source connected to the EIR audio input, encode the data to Ogg Vorbis and store the result on a memory cards.

The code presented on this page assumes, that you are familiar with Nut/OS. If not, you may look to the examples at our Nutwiki.

Using Memory Cards

The document EIR Memory Card Support explains how configure Nut/OS and the EIR board for using the card socket. The main requirements are

  • Nut/OS 5.0.5 or later
  • Shortening SSC TK and RK signals on connector K1 (pins 17 with pin 20)

Loading Plug-Ins

The following routine can be used to load a plug-in into the VS1053 chip:

int LoadPlugInImage(int dh, int ph)
{
    int got;
    uint_fast16_t i;
    uint8_t buf[5];
    int rec_type;
    VS_WRAM_DATA vswd;

    got = _read(ph, buf, 3);
    if (got != 3) {
        puts("Read error");
        return -1;
    }
    if (buf[0] != 'P' || buf[1] != '&' || buf[2] != 'H') {
        puts("Not a plug-in?");
        return -1;
    }
    /* Prepare plug-in upload. */
    putchar('(');
    if (_ioctl(dh, AUDIO_WRITE_CMEM, NULL)) {
        puts("ioctl-err");
    }
    for (;;) {
        got = _read(ph, buf, 5);
        if (got != 5) {
            break;
        }
        rec_type = buf[0];

        vswd.vswd_size = buf[1];
        vswd.vswd_size <<= 8;
        vswd.vswd_size |= buf[2];
        vswd.vswd_addr = buf[3];
        vswd.vswd_addr <<= 8;
        vswd.vswd_addr |= buf[4];
        if (rec_type == VSIMG_RECTYP_I) {
            vswd.vswd_addr += 0x8000;
        }
        else if (rec_type == VSIMG_RECTYP_Y) {
            vswd.vswd_addr += 0x4000;
        }
        else if (rec_type == VSIMG_RECTYP_E) {
            vswd.vswd_data = NULL;
            putchar(')');
            if (_ioctl(dh, AUDIO_WRITE_CMEM, &vswd)) {
                puts("ioctl-err");
            }
            return 0;
        }
        vswd.vswd_data = (uint16_t *) malloc(vswd.vswd_size);
        vswd.vswd_size >>= 1;
        for (i = 0; i < vswd.vswd_size; i++) {
            got = _read(ph, buf, 2);
            if (got != 2) {
                break;
            }
            vswd.vswd_data[i] = buf[0];
            vswd.vswd_data[i] <<= 8;
            vswd.vswd_data[i] |= buf[1];
        }
        putchar('.');
        if (_ioctl(dh, AUDIO_WRITE_CMEM, &vswd)) {
            puts("ioctl-err");
        }
        free(vswd.vswd_data);
    }
    return -1;
}

This function expects 2 arguments

  • dh Handle of the previously opened audio device
  • ph Handle of a previously opened file that contains the plug-in

This code snippet shows how to open the audio device:

int fh;

printf("Open audio device...");
dh = _open("audio0", _O_RDWR | _O_BINARY);
if (dh == -1) {
    printf("Error %d\n", errno);
} else {
    puts("OK");
}

Note, that the audio device needs to be registered first.

printf("Register audio device...");
if (NutRegisterSpiDevice(&devSpiVsCodec0, &spiBus0At91, 1)) {
    puts("failed");
} else {
    puts("OK");
}

The next code snippet shows how to open a plug-in file located on the memory card.

int fh;

fh = _open("PHAT0:/venc44k2q05.img", _O_RDWR | _O_BINARY);
if (fh == -1) {
    printf("Error %d\n", errno);
} else {
    LoadPlugInImage(dh, fh);
    _close(fh);
    puts("OK");
}

Recording is simply done by reading from the audio device and writing to a file.

static uint8_t ogg_buff[512];

fh = _open("PHAT0:/myrecording.ogg", _O_CREAT | _O_TRUNC | _O_WRONLY | _O_BINARY);
if (fh == -1) {
    printf("Error %d, can't open audio file\n", errno);
} else {
    stop_recording = 0;
    while (1) {
        got = _read(dh, ogg_buff, sizeof(ogg_buff));
        if (got <= 0 || stop_recording) {
            break;
        }
        if (_write(fh, ogg_buff, got) != got) {
            break;
        }
        _close(fh);
    }
}




Return to the EIR project page.