Hardware/EIR/Vorbis Rec

From Nutwiki
Revision as of 10:10, 13 July 2017 by Harald (Talk | contribs) (Created page with "<div id="content"> = 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 enc...")

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, 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.