Audio Library

Status
Not open for further replies.
Sorry, I don't know.

I just copied the copy you provided onto a SD card and copied your code into an Arduino window, uploaded, and it started playing that clip with the woman talking about deciding what to do with your life.

There's nothing wrong with the file or the code. Maybe try again with another SD card?

I just don't know what else I can do to help here. At least this can keep you from going farther down the path of fiddling with the code and the WAV file. They're both perfectly fine. Whatever's wrong, it's not the files.

I see. I'll just keep trying. Thanks for the great and quick response. You guys are doing an awesome job!
 
Sorry, I don't know.

I just copied the copy you provided onto a SD card and copied your code into an Arduino window, uploaded, and it started playing that clip with the woman talking about deciding what to do with your life.

There's nothing wrong with the file or the code. Maybe try again with another SD card?

I just don't know what else I can do to help here. At least this can keep you from going farther down the path of fiddling with the code and the WAV file. They're both perfectly fine. Whatever's wrong, it's not the files.

I think dBCap may be in the same situation as I: I have spent a day trying to work out what the audio design tool actually gives you. For days I have assumed that, as stated in the notes for "AudioPlayMemory" (or am I misled?), I first have to use the wav2sketch program to convert my files from WAV to numerical. Impossible; I have no working C compiler, nor is the *.exe file operable. So now I am assuming that the example "SamplePlayer" shows how to do the job but how? The example bears little relation to the notes. I can't find any description of the AudioConnection's four parameters and none of my guesses have worked. Nor can I get the example's method of playing the sounds to work for my much simpler job, just inexplicable knuckle wrapping from the "verify" function. The code is high level but surely there is a simple description of the functions and their parameters somewhere. Neither the note nor the examples do this job. I am thinking of the "libraries" referred to in the Arduino language reference pages as an example.
 
I first have to use the wav2sketch program to convert my files from WAV to numerical. Impossible; ... nor is the *.exe file operable.

Really? It works when I run it here. Odds are you're just not running it the right way.

Maybe you could post a screenshot of the exact command you typed, and what it actually printed?
 
Really? It works when I run it here. Odds are you're just not running it the right way.

Maybe you could post a screenshot of the exact command you typed, and what it actually printed?

Paul
Sure: here is the code I have been trying to get working:

// Controller2.pde draft, written on 25/1/2016 based on pjrc examples "sample player"
// and "recorder"

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioRecordQueue queue1;
AudioPlayMemory playMem1;
AudioPlayMemory sound0;
AudioOutputI2S headphones;
AudioOutputI2S i2s1;
AudioConnection patchCord1(i2s1, 0, queue1, 0);
AudioConnection c1(sound0, 0, headphones, 0);

AudioControlSGTL5000 sgtl5000_1;

File frec; //file for recording chirp in memory

void setup() {
// Audio connections require memory, and the record queue
// uses this memory to buffer incoming audio.
AudioMemory(60);
// Create an object to control the audio shield.
AudioControlSGTL5000 audioShield;
//and turn on output
audioShield.enable();
audioShield.volume(0.5);

//Initialise SD card The (x) numbers are the board pins
SPI.setMOSI(7);
SPI.setSCK(14);
if (!(SD.begin(10))) {
// stop here if SD card not available, but print a message repetitively
while (1) {
Serial.println("Unable to access the SD card");
delay(500);
}
}
// start recording to memory
frec = SD.open("2H2K1024.WAV", FILE_READ);
if (frec) {
queue1.begin();
}
if (queue1.available() >= 2) {
byte buffer[512];
// Fetch 2 blocks from the audio library and copy
// into a 512 byte buffer. The Arduino SD library
// is most efficient when full 512 byte sector size
// writes are used.
memcpy(buffer, queue1.readBuffer(), 256);
queue1.freeBuffer();
memcpy(buffer+256, queue1.readBuffer(), 256);
queue1.freeBuffer();
// write all 512 bytes to the SD card
// elapsedMicros usec = 0; // this line is unused and generates a warniing
frec.write(buffer, 512);
}
}
void loop() {
sound0.play(frec);
delay(1000);
}

It is the line "sound0.play(frec);" that gives an error, as follows:

C:\Users\Dick\Documents\Arduino\Controller2\Controller2.ino: In function 'void loop()':
Controller2:64: error: no matching function for call to 'AudioPlayMemory::play(File&)'
sound0.play(frec);
^
C:\Users\Dick\Documents\Arduino\Controller2\Controller2.ino:64:19: note: candidate is:
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:87:0,
from C:\Users\Dick\Documents\Arduino\Controller2\Controller2.ino:5:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_memory.h:36:7: note: void AudioPlayMemory::play(const unsigned int*)
void play(const unsigned int *data);
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_memory.h:36:7: note: no known conversion for argument 1 from 'File' to 'const unsigned int*'
exit status 1
no matching function for call to 'AudioPlayMemory::play(File&)'

It seems I should be using pointers (eg *data) as in some examples but I don't see their use in the examples referred to. I just guessed what to put in the AudioConnection parameter braces. I would appreciate your advice. Richard
 
Looks like you're trying to use the memory player, which plays short clips from arrays in Teensy's flash memory, to play a WAV file from your SD card.
 
Looking at this code again (now that I have more time)... where to begin?

First, there's the high-level question of what you're really trying to accomplish here. From the comments and code, it seems you're trying to record a small audio clip to your SD card, and then play it over and over in a loop once per second. I'm going to write the rest of this message based on that assumption....

The first major problem is "sound0" is a AudioPlayMemory object, which plays a sound clip from the internal Teensy memory. Your code isn't even compiling, because you're trying to get an internal memory player to play from the SD card. AudioPlayMemory can't do that. Instead, you need to use AudioPlaySdRaw.

Again from a high-level perspective, a huge problem is you're not using the design tool. You really should. That's where all the documentation exists. With the design tool, you can see the various players and what capabilities each one offers.

The design tool automatically generates the connection objects for you. Even if you understand them, getting all 4 parameters correct is an error prone process for humans. Even I get them messed up sometimes, and I ought to know since I designed all this stuff. Use the design tool. It will save you from mistakes like the connections you've defined with inputs where outputs should be, and vise-versa. I'm not going to write more about manually creating connections. Use the design tool!!!

Your collection of objects is also illogical. The design tool won't always save you from making something senseless, but at least it will make the incoherence visually apparent. In this system, you've got two I2S output objects. Perhaps "i2s1" was meant to be an input? You've got that connected to the record queue, which is trying to connect 2 objects that take input together. The design tool won't let you draw such connections, and because the visual arrangement makes things clear, you probably won't even try to do such things. Without the design tool, you have no cues in the code to detect these sorts of problems.

Use the design tool. I put a tremendous amount of work into adapting the Node-Red code for exactly these reasons. Even I make syntactic mistakes without the design tool... and I'm the guy who created this syntax!

Back in the code specifics, another problem is you're opening the file in read only mode. You can't write any data that way! If you change this, please be aware the Arduino SD library defaults to appending data when you open in write mode. If you want to overwrite the file, you need to also seek to the beginning after opening in write mode.

After opening, your code checks if the file was able to be opened, which is good. But then your check only does queue1.begin(). After the check, your code does a bunch of other stuff with the file and the queue, regardless of whether the file was properly opened.

Again, looking at this from a higher-level perspective, my guess is you're probably not indenting your code well, which leads to mis-reading it and misunderstanding which things it will conditionally do. And again, there's automated tools to help. In Arduino, click the Tools > Auto Format menu. This will automatically indent your code properly. These types of errors will become very easy to see with proper indenting.

Back in the small but critical details, there's a conditional test for (queue1.available() >= 2). This test is done only once, right after the queue has started collecting audio data. At that point, odds are pretty much zero that 2 blocks of audio will be available in the queue. For this to work, you need to structure your code to wait and repeat the check until it becomes true.

After trying to write the data, which of course will fail since the file is read-only, and can't happen anyway because of the single too-soon check for queued data, your code isn't calling queue.end(). That's a huge problem, on top of that conditional code never running. These queue objects give you great power to access the high speed audio data. They automatically queue up data, so if your code has high latency (like waiting for the SD card), you don't lose data. But the queues will rapidly fill with audio and exhaust all the memory you allocated with AudioMemory(60). If you're going to ignore the queue, you *MUST* use queue1.end() to stop it from trying to store up more arriving audio data. Once it quickly consumes all the memory, you can't do anything. Even the play object won't be able to play, because the library won't be able to get any memory to move data to the I2S output.

Stepping back once again from these low-level details, one final high-level issue is the extremely short time from of only 512 bytes. That's only 5.8 ms of sound. I probably shouldn't even use the word "sound" for such a short clip, since it's well under the time frame for human cognition of much more than a click or pop. Even if you resolve all these other technical problems, only 5.8 ms is going to be terribly frustrating to hear any results. Ordinary speech and even composed music regularly contain segments where several milliseconds are meaningless, so many attempts will capture "nothing" even when a signal is present. Even detecting a pitch is unlikely with such a short clip. You probably need about 10 times longer just to capture enough for recognition of a tone or a recognizable syllable or fragment of a spoken word.
 
On top of all those issues, a minor stylistic issue is the filename. You're using a ".WAV" extension. While this could work if you fix all the other issues, you really should use an extension like ".RAW" or ".BIN".

WAV files have a 44 byte (or longer) header which documents the data format, and optionally other non-audio sections for metadata like song & artist names. If you ever remove the SD card and use it on a PC or Mac, most software will expect to find that header. Odds are slim the raw audio data will match any legal WAV header, so most software will reject it as a corrupted WAV file. Maybe you'll never remove the SD card and try to use the file elsewhere, but still it's not good practice to create files with well known extensions but store data in different formats in them.
 
*Edited*

This mega-thread is being moved to the Audio Projects forum.

I'm leaving this thread open for a few more days to allow some discussions to wrap up. Please start a new thread for new discussions and comments on the Audio Library. I will be closing this thread from further posting within the next week.
 
Last edited:
Paul
Sorry, been away. Thanks for your extensive help.

Emboldened by the workshop I have relearnt DOS, which I last used in the 1970's. For anybody following this thread and also worried about the brilliant wav2sketch.exe program here's how to do it.
1. put your WAV file with the wav2sketch.exe file in a new C:\WAV directory
2. Open a Command prompt as administrator by clicking the correct line available after pressing the WINDOWS plus X buttons
3. Change directory in the DOS window by typing: CD C:\WAV
4. Run the program by typing: wav2sketch. It then converts all WAV files in the directory to C arrays available through *.h files and these can then be accessed by the Teensy3.1/2
 
Last edited:
The WAV to cpp file conversion seems to work OK (see image) cpp.JPG and I have made an apparently error-free version of the workshop "Samples" program to play it (it works well with the GONG cpp file). However, the compiler says my cpp file AudioSampleH2K1024w is not "declared" in the loop. I don't understand this as the files (cpp and h) are both attached to the program as in the Samples program. here is my program with error message.scope error.jpg Can anyone tell me what is incorrect here, please?
 
This thread is now closed. Please start a new thread or look at existing threads in the Audio forum.
 
Status
Not open for further replies.
Back
Top