Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

Thread: using the eeprom for audio sample memory + Audio Library (playQueue Vs audio object)

  1. #1
    Senior Member
    Join Date
    May 2019
    Location
    Brisbane, QLD
    Posts
    104

    using the eeprom for audio sample memory + Audio Library (playQueue Vs audio object)

    I'm very new to the audio library, to help me get familiar i wanted to give myself a basic project. I wrote a small program that writes a 8-bit random number (0-255) to the onboard 4kb eeprom on startup.
    the audio is sent through the playQueue object to a mixer in the audio library then out the USB Audio port. Typing "p" into the serial monitor will read out the sample data from address 0 to address 4095.

    It works, but because i'm just playing back noise I'm not sure if i have scaled everything right. There are a lot of holes in what i understand about the playQueue object;

    1. getBuffer() is supposed to point to a int16_t char*. Does that mean that full scale integer audio should be +/- 32,768?. In my example the numbers in the eeprom only are 8-bit (0-255). Does that need to be scaled to +/- 32k?
    2. how difficult would it be to modify an audio object to avoid using the playQueue object to achieve the same result below?
    3. any mistakes i'm doing below in relation to PlayQueue?

    Thanks in advance


    Code:
    #include <EEPROM.h>
    
    #include <MIDI.h>
    #include <midi_UsbTransport.h>
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioPlayQueue           queue1;         //xy=295.1999969482422,762.4000244140625
    AudioSynthNoiseWhite     noise1;         //xy=298.1999969482422,721.4000244140625
    AudioMixer4              mixer1;         //xy=435,740
    AudioOutputUSB           usb1;           //xy=558.2000122070312,738.4000244140625
    AudioOutputAnalog        dac1;           //xy=576,658
    AudioConnection          patchCord1(queue1, 0, mixer1, 1);
    AudioConnection          patchCord2(noise1, 0, mixer1, 0);
    AudioConnection          patchCord3(mixer1, 0, usb1, 0);
    AudioConnection          patchCord4(mixer1, 0, usb1, 1);
    AudioConnection          patchCord5(mixer1, dac1);
    // GUItool: end automatically generated code
    
    
    
    
    /** the current address in the EEPROM (i.e. which byte we're going to write to next) **/
    uint16_t eeprom_length;
    uint8_t randNumber;
    uint8_t incomingByte;
    
    char pcmBuffer[128];
    
    void setup() {
    
      Serial.begin(9600);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for Leonardo only
      }
    
      AudioMemory(196);
      noise1.amplitude(1);
    
      mixer1.gain(0, 0);
      mixer1.gain(1, 1);
      mixer1.gain(2, 0);
      mixer1.gain(3, 0);
    
      eeprom_length = EEPROM.length();
      Serial.printf("length of onboard eeprom is > %d bytes\n\n", eeprom_length);
    
      // write a random number from 0 to 255 (8-bit) to eeprom
      for (int i = 0; i < eeprom_length; i++) {
        randNumber = random(256); //8-bit
    
        Serial.printf("writing value %d to eeprom address > %d\n", randNumber, i);
        delayMicroseconds(22);
      }
    
      Serial.printf("\npress <p> to playback eeprom array\n");
    
    }
    
    void loop() {
      if (Serial.available() > 0) {
        // read the incoming byte:
        incomingByte = Serial.read();
        if (incomingByte == 'p') {
    
          uint8_t bufferCount = 0;
    
          for (uint16_t i = 0; i < eeprom_length; i++) {
            pcmBuffer[bufferCount] = EEPROM.read(i);
            bufferCount++;
            if (bufferCount > 127) {
              bufferCount = 0;
              int16_t *audioBuffer = queue1.getBuffer();
              if (audioBuffer != NULL) {
                // Copy the raw PCM audio data into the audio buffer.
                memcpy(audioBuffer, pcmBuffer, 128);
                // play buffer out usb
                queue1.playBuffer();
              }
            }
          }
    
          Serial.printf("\ntype <p> & hit <enter> to playback eeprom array\ndigits 0-9 <enter> sets volume of PlayQueueBuffer\n");
        }
    
        if (isDigit(incomingByte)) {
          incomingByte = incomingByte - '0'; //convert ascii digit to int
          mixer1.gain(1, float(incomingByte * .1));
          Serial.println(incomingByte);
        }
      }
    
    }

  2. #2
    Senior Member
    Join Date
    May 2019
    Location
    Brisbane, QLD
    Posts
    104
    I figured it out, i was able to learn from the code posted here https://gitlab.cs.washington.edu/kgo...rainTeensy.ino

    I ended up loading a 4096byte 8bit clap sample (stored on SD) into the eeprom using the code below. From there it was easy to identify problems due to incorrect integer scaling Vs my previous noise sample.

    Code:
    eeprom_length = EEPROM.length();
      Serial.printf("length of onboard eeprom is > %d bytes\n\n", eeprom_length);
    
      if (!myFileIn.open("clap8.pcm", O_READ)) {
        Serial.printf("\nunable to open clap8.pcm for reading.");
        return;
      }
    
      uint8_t tmp;
      uint16_t counter = 0;
    
      while (myFileIn.available()) { // read from the file until there's nothing else in it:
        tmp = myFileIn.read();
        EEPROM.write(counter, tmp);
        counter++;
      }
    
      myFileIn.close();
    To answer a few of my own questions;

    1. Yes the integer audio needs to be scaled from "unsigned 8-bit" to "signed 16-bit". Easy enough to accomplish by multiplying the 8-bit eeprom value by * 257 and subtracting 32768. That'll give a range of +/-32767 for audio play queue.

    I'm not sure how to match the samplerate, a 22,050khz sample will play twice the speed at 44,100khz. I guess you could repeat each value when writing to the audio buffer? That would only work for prfect divisions of 44,100 thoough.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •