Teensy audio board as a soundbank organ keyboard

Status
Not open for further replies.

LERAY

Well-known member
Hi paul and all,

I'm trying to use the Teensy audio board as an organ keyboard with soundbanks, using teh 16GB SAN DISK.
Th board is running perfectly, when I'musing the waveplayer example.

But when I try to play a sound, when receiving MIDI ON from an external keyboard, there is no output sound, and no serial output.
Thanks for your help !
Source code below,

Pascal Leray

// Simple WAV file player example
//
// Requires the audio shield:
// http://www.pjrc.com/store/teensy3_audio.html
//
// Data files to put on your SD card can be downloaded here:
// http://www.pjrc.com/teensy/td_libs_AudioDataFiles.html
//
// This example code is in the public domain.
#include <MIDI.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <stdio.h>
#include <string.h>

char filenames[56][16]={"036-C.wav","037-C#.wav","038-D.wav","039-D#.wav"};

// GUItool: begin automatically generated code
AudioPlaySdWav playWav1; //xy=154,78
AudioOutputI2S i2s1; //xy=334,89
AudioConnection patchCord1(playWav1, 0, i2s1, 0);
AudioConnection patchCord2(playWav1, 1, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=240,153
// GUItool: end automatically generated code

void setup()
{
Serial.begin(9600);
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);

// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(5);

sgtl5000_1.enable();
sgtl5000_1.volume(0.5);

SPI.setMOSI(7);
SPI.setSCK(14);
Serial.print("BEGINNING");
if (!(SD.begin(10)))
{
// stop here, but print a message repetitively
while (1)
{
Serial.println("Unable to access the SD card");
delay(500);
}
}
}

void OnNoteOn(byte channel, byte note, byte velocity)
{
Serial.print("Note On, ch=");
Serial.print(note, DEC);
playFile(&filenames[note-36][0]);
}

void OnNoteOff(byte channel, byte note, byte velocity)
{

}

void playFile(const char *filename)
{
// Start playing the file. This sketch continues to
// run while the file plays.
playWav1.play(filename);

// A brief delay for the library read WAV info
delay(5);

// Simply wait for the file to finish playing.
/* while (playWav1.isPlaying())
{
// uncomment these lines if you audio shield
// has the optional volume pot soldered
//float vol = analogRead(15);
//vol = vol / 1024;
// sgtl5000_1.volume(vol);
}
*/
}


void loop()
{
usbMIDI.read();
}
 
Could you first try running one of the known-good examples, just to make sure your audio hardware works.

File > Examples > Audio > SamplePlayer would be a good place to start. Touch a wire between GND and pins 0 to 5, to trigger it to play the samples.
 
...

I'm trying to use the Teensy audio board as an organ keyboard with soundbanks, using teh 16GB SAN DISK.
Th board is running perfectly, when I'musing the waveplayer example.

...
Good to see I am not the only one who misses relevant details in such posts, so, it works fine with an example, good.

I reformatted your code to make it easier to hand parse - would you remove your micro SD card from the holder and run your sketch please? Interest being; do you see the "Unable to access SD card" line, using the terminal/monitor of your choice?

[code]Put code here and it won't lose formatting[/code]

Code:
// Simple WAV file player example
//
// Requires the audio shield:
// http://www.pjrc.com/store/teensy3_audio.html
//
// Data files to put on your SD card can be downloaded here:
// http://www.pjrc.com/teensy/td_libs_AudioDataFiles.html
//
// This example code is in the public domain.
#include <MIDI.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <stdio.h>
#include <string.h>

char filenames[56][16] = {"036-C.wav", "037-C#.wav", "038-D.wav", "039-D#.wav"};

// GUItool: begin automatically generated code
AudioPlaySdWav playWav1; //xy=154,78
AudioOutputI2S i2s1; //xy=334,89
AudioConnection patchCord1(playWav1, 0, i2s1, 0);
AudioConnection patchCord2(playWav1, 1, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=240,153
// GUItool: end automatically generated code

void setup()
{
  Serial.begin(9600);
  usbMIDI.setHandleNoteOff(OnNoteOff);
  usbMIDI.setHandleNoteOn(OnNoteOn);

  // Audio connections require memory to work. For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(5);

  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);

  SPI.setMOSI(7);
  SPI.setSCK(14);
  Serial.print("BEGINNING");
  if (!(SD.begin(10)))
  {
    // stop here, but print a message repetitively
    while (1)
    {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
}

void OnNoteOn(byte channel, byte note, byte velocity)
{
  Serial.print("Note On, ch=");
  Serial.print(note, DEC);
  playFile(&filenames[note - 36][0]);
}

void OnNoteOff(byte channel, byte note, byte velocity)
{

}

void playFile(const char *filename)
{
  // Start playing the file. This sketch continues to
  // run while the file plays.
  playWav1.play(filename);

  // A brief delay for the library read WAV info
  delay(5);

  // Simply wait for the file to finish playing.
  /* while (playWav1.isPlaying())
  {
  // uncomment these lines if you audio shield
  // has the optional volume pot soldered
  //float vol = analogRead(15);
  //vol = vol / 1024;
  // sgtl5000_1.volume(vol);
  }
  */
}


void loop()
{
  usbMIDI.read();
}
 
Soundbank organ keyboard

Could you first try running one of the known-good examples, just to make sure your audio hardware works.

File > Examples > Audio > SamplePlayer would be a good place to start. Touch a wire between GND and pins 0 to 5, to trigger it to play the samples.

Of course, dear Paul ! I checked the waveplayer, with a SANDISK 16GB as you recommend, and ot's running fine.
So the hardaware is running perfectly.
But there is no example today with a mix of WAVEPLAYER and MIDI READ and other associated functions.

It would be great to achieve with your fine TEENSY a real SoundBank organ keyboard !

Question :
Is it possible to launch Play() at a given address of the .wav file ?
It's mandatory to process the loops, which are needed when hitting a key of the organ keyboard.

Thanks and many congratulations for your outstanding work !
Best regards,

Pascal
 
Two stupid questions

Are you certain you have the routing setup correctly from the keyboard? Can you play other midi synths using the keyboard.

Now for the really stupid question, are you connecting the teensy to the computer via usb rather than an actual midi cable?

EDIT: Actually 3rd stupid question, have you changed the device type for the Teensy to MIDI?
 
Last edited:
Is it possible to launch Play() at a given address of the .wav file ?

Unfortunately, no. This is probably the most requested feature for the audio library, so it's near the top of my list to implement when I work on audio stuff again.

Of course, the code is all open source, so anyone can try adding this. There's some code on the forum where people have done so in the simpler RAW format player.
 
What I asked you to do in my previous post would establish that your Teensy is functional, executing the sketch, and still able to communicate via USB - keeping it connected to everything you currently have it connected to would make this test more relevant; adding a little to your loop instead can make it so you do not have to remove the SD card from the holder
Code:
elapsedMillis timing1;
void loop()
{
  usbMIDI.read();
  if(timing1>4999) { // 5 seconds
    timing1=0;
    Serial.println("Functional.");
  }
}
Will make it so that you get something from Serial monitor IF the sketch is executing successfully etc etc.

I think that to get the original problem you posted to this thread fixed you will need to tell how you are connecting the keyboard to Teensy and rather than just telling showing is even better - if you photograph your connections and post the picture(s) the people who really can help you will have a much better chance.

FYI: This is the original problem I thought you needed help with:
...

... when receiving MIDI ON from an external keyboard, there is no output sound, and no serial output.
...
 
Dear Paul robsoles and all !

I'm now home again, and all is perfectly running ! Hardware and software. My software on the PC was simply sending MIDI On messages at a wrong address.
But now, we are very close from the goal : Play .wav files from real pipes, using wave loops, and fundamentally mix several .wav files.
May I help you, Paul, for this task ? It would be of great interest for Teensy and your nice AUDIO module, which is running fine !
Congratulation again for all what you are doing !

Pascal
 
But now, we are very close from the goal : Play .wav files from real pipes, using wave loops, and fundamentally mix several .wav files.
May I help you, Paul, for this task ? It would be of great interest for Teensy and your nice AUDIO module, which is running fine !

I do not understand your question.
 
I think I might Paul; I suppose just my guess being that what LERAY is asking is for somebody to modify play_sd_wav.cpp/h not only enough to allow starting playback at a given time position in the file but also to be able to specify a duration with either terminate or loop to previously given starting position till terminated type flag or simile in play - betting LERAY would appreciate good example of using it multiple times simultaneously etc etc.

I'm willing to assume that using raw audio format would be easier and should easily produce a better result than trying to pursue this with audio formatted any other way.
 
@LERAY - Can you provide a collection of .WAV files for the pipe organ sound, across a range of notes and midi velocities? The sounds must be well documented as public domain or creative commons with permission for commercial use. CC non-commercial is not acceptable.

I will only put my engineering time into an example program if the sound files are available.
 
Last edited:
No problem, Paul !
You can download public domain .wav files on :
http://www.familjenpalo.se/vpo/download
There are several interesting .wav files, recorded directly from real Pipe ! Outstanding result with
PITEA CHURCH and BUREA are fine. And they are public domain.
All these files have Audio Loops.

But St Maximin Pipe Organ is better. (but cost is 500$)
If we could achieve with Teensy what is done with high end PC's, what a challenge !

EXPLANATION FOR YOUR QUESTION :
In .wav files dedicated to virtual pipe organs, there are several loop addresses :
long adrloopstart = 0x2E;
long adrloopend = 0x30;
Beginning of the .wav is at 0x2E
end of continuous tone (when one must repeat a key) is at 0x30
So one must :
Start to play at 2E;
Repeat as long as the note is hit at 0x30
When the organ key is no longer hit, play the decay, from adrloopend up to the end of the file.
A good loop editor is available at :
http://sourceforge.net/projects/loopauditioneer/
where one can set, modify loops in wave files. So one can start, continue, and decay smoothly all .wav files.

Second feature : One must have the possibility to mix several .wav files. using 1024 block samples. At 44100MHz
I think it's possible with Teensy.
A very good but too complex open source library is available : RT-AUDIO library

Pascal
 
Yes, raw audio files are lloking primarily more simple than wav files, but many Virtual Pipe Organs are using .wav format.
Which is a good, worldwide used audio format, without compressing.
As a virtual Pipe Organ need lots of .wav files, (One for each pipe ! and many organs have thousands pipes !
It would be necessary to convert .wav files in .raw audio format.
Moreover, loops would be necessarly stored in a separate file. It's possible, but less easy than .wav, which can include loops addresses inside !

Pascal
 
But now, we are very close from the goal : Play .wav files from real pipes, using wave loops, and fundamentally mix several .wav files.

I don't think you are anywhere near being able to mix multiple pipes from arbitrary points in the playing sequence.
It is going to be very difficult to play just one note with loops correctly. To do that you would not only have to be able to play a WAV file from an arbitrary point, but also be able to switch to some other arbitrary point in the file when the end of a loop is reached. At the point that the switch occurs, the software would have to be able to read and buffer a completely different uSD sector than the one it is currently in and do it in less than one audio sample time which is about 23 microseconds.


Pete
 
I don't think you are anywhere near being able to mix multiple pipes from arbitrary points in the playing sequence.
It is going to be very difficult to play just one note with loops correctly. To do that you would not only have to be able to play a WAV file from an arbitrary point, but also be able to switch to some other arbitrary point in the file when the end of a loop is reached. At the point that the switch occurs, the software would have to be able to read and buffer a completely different uSD sector than the one it is currently in and do it in less than one audio sample time which is about 23 microseconds.


Pete

OurOrgan and Hauptwerk softwares are doing this task, but, indeed, all the .wav files are loaded at the beginning in about 3GB RAM. (4GB RAM are sufficient for running very large pipe organs on PC)
Buffers for example 1024 bytes, are continously loarded from these memories. Several .wav files datas corresponding to the selected stops and keys are added in real time.
Indeed, Teensy memory size is largely less.
The main question is : Is it possible to load several 1024 bytes buffers from selected stops and added with other samples, in less than one audio sample time.
Or is it necessary to have a 2 or 3 GB RAM memory ?
 
Indeed, you originally asked to play WAV files. Then your request changed to include sample-precise looping. But this is probably only the beginning....

I downloaded PiteaMHS.rar. You did not say exactly which file to use, so I just picked that one. If you meant a different file, well, you should have been more specific!

PiteaMHS contains 33 folders, each with about 30 to 60 .WAV files. There's a couple folders with images and html about the organ, and two metadata files named piteaMHS.organ and piteaPositivOrgan.organ.

Those 2 files are in a text-only format, which is good, but it's a format I don't understand. As I read that file, I do not know how to map the WAV files to MIDI note and velocity. Even the loop points within the WAV files are unclear. For example, for "SUBBAS 16":

Code:
[Stop001]
Name=SUBBAS 16'
TextBreakWidth=0
NumberOfLogicalPipes=32
NumberOfAccessiblePipes=32
FirstAccessiblePipeLogicalPipeNumber=001
FirstAccessiblePipeLogicalKeyNumber=001
Comments=
WindchestGroup=001
Percussive=N
DefaultToEngaged=N
DisplayInInvertedState=N
StopControlMIDIKeyNumber=1
ShortcutKey=
DispDrawstopCol=1
DispDrawstopRow=5
DispLabelColour=Black
DispLabelFontSize=Normal
Displayed=Y
DispImageNum=2
ImageOn=.\ConsoleImages\SmallStops\ped-subbas16-out.png
ImageOff=.\ConsoleImages\SmallStops\ped-subbas16-in.png
PositionX=26
PositionY=207
AmplitudeLevel=100
DispKeyLabelOnLeft=N
HarmonicNumber=4
Pipe001=.\PEDSubbas16\036-C.wav
Pipe002=.\PEDSubbas16\037-C#.wav
Pipe003=.\PEDSubbas16\038-D.wav
Pipe004=.\PEDSubbas16\039-D#.wav
Pipe005=.\PEDSubbas16\040-E.wav
Pipe006=.\PEDSubbas16\041-F.wav
Pipe007=.\PEDSubbas16\042-F#.wav
Pipe008=.\PEDSubbas16\043-G.wav
Pipe009=.\PEDSubbas16\044-G#.wav
Pipe010=.\PEDSubbas16\045-A.wav
Pipe011=.\PEDSubbas16\046-A#.wav
Pipe012=.\PEDSubbas16\047-B.wav
Pipe013=.\PEDSubbas16\048-C.wav
Pipe014=.\PEDSubbas16\049-C#.wav
Pipe015=.\PEDSubbas16\050-D.wav
Pipe016=.\PEDSubbas16\051-D#.wav
Pipe016AmplitudeLevel=150
Pipe017=.\PEDSubbas16\052-E.wav
Pipe017AmplitudeLevel=140
Pipe018=.\PEDSubbas16\053-F.wav
Pipe018AmplitudeLevel=120
Pipe019=.\PEDSubbas16\054-F#.wav
Pipe019AmplitudeLevel=125
Pipe020=.\PEDSubbas16\055-G.wav
Pipe020AmplitudeLevel=140
Pipe021=.\PEDSubbas16\056-G#.wav
Pipe021AmplitudeLevel=150
Pipe022=.\PEDSubbas16\057-A.wav
Pipe022AmplitudeLevel=140
Pipe023=.\PEDSubbas16\058-A#.wav
Pipe023AmplitudeLevel=120
Pipe024=.\PEDSubbas16\059-B.wav
Pipe025=.\PEDSubbas16\060-C.wav
Pipe026=.\PEDSubbas16\061-C#.wav
Pipe027=.\PEDSubbas16\062-D.wav
Pipe028=.\PEDSubbas16\063-D#.wav
Pipe029=.\PEDSubbas16\064-E.wav
Pipe030=.\PEDSubbas16\065-F.wav
Pipe031=.\PEDSubbas16\066-F#.wav
Pipe032=.\PEDSubbas16\067-G.wav

I could write a lengthy message about the audio libraries internal capability. In fact, I've already written a page about how to create new objects in the library, and of course all the source code is published. I really do not feel like writing a LOT more when you have put forth so little effort.

My hope today was to obtain a collection of WAV files which could be used as a simple MIDI to note playing example, to demonstrate the recently added SerialFlash playing object. If you had provided a set of WAV files with clear mapping from MIDI note (and maybe velocity) to each file, and the files were simple playback, triggered only by Note-On and not requiring complex looping, then I probably would have composed a simple example program which received MIDI Note-On messages and played the files.

But you did NOT provide a ready-to-use set of WAV files with clear mapping. Instead, you pointed to a data set (actually, several and you couldn't even be specific about exactly which file to download) meant for specific organ simulation software. The mapping is in a text file specific to that software, without documentation, and all of it appears to be specific to organ construction, not MIDI messages.

My time is very limited. I only had about an hour available to look at files, and now I've spent most of that time trying to make sense of the piteaMHS data set. If you had put forth more effort, to make a set of WAV files to be simply played (no looping) with clearly defined mapping from MIDI parameters to file names, I very likely would have created an example program for them. But you did not do this.
 
Indeed, you originally asked to play WAV files. Then your request changed to include sample-precise looping. But this is probably only the beginning....

I downloaded PiteaMHS.rar. You did not say exactly which file to use, so I just picked that one. If you meant a different file, well, you should have been more specific!

PiteaMHS contains 33 folders, each with about 30 to 60 .WAV files. There's a couple folders with images and html about the organ, and two metadata files named piteaMHS.organ and piteaPositivOrgan.organ.

Those 2 files are in a text-only format, which is good, but it's a format I don't understand. As I read that file, I do not know how to map the WAV files to MIDI note and velocity. Even the loop points within the WAV files are unclear. For example, for "SUBBAS 16":

Code:
[Stop001]
Name=SUBBAS 16'
TextBreakWidth=0
NumberOfLogicalPipes=32
NumberOfAccessiblePipes=32
FirstAccessiblePipeLogicalPipeNumber=001
FirstAccessiblePipeLogicalKeyNumber=001
Comments=
WindchestGroup=001
Percussive=N
DefaultToEngaged=N
DisplayInInvertedState=N
StopControlMIDIKeyNumber=1
ShortcutKey=
DispDrawstopCol=1
DispDrawstopRow=5
DispLabelColour=Black
DispLabelFontSize=Normal
Displayed=Y
DispImageNum=2
ImageOn=.\ConsoleImages\SmallStops\ped-subbas16-out.png
ImageOff=.\ConsoleImages\SmallStops\ped-subbas16-in.png
PositionX=26
PositionY=207
AmplitudeLevel=100
DispKeyLabelOnLeft=N
HarmonicNumber=4
Pipe001=.\PEDSubbas16\036-C.wav
Pipe002=.\PEDSubbas16\037-C#.wav
Pipe003=.\PEDSubbas16\038-D.wav
Pipe004=.\PEDSubbas16\039-D#.wav
Pipe005=.\PEDSubbas16\040-E.wav
Pipe006=.\PEDSubbas16\041-F.wav
Pipe007=.\PEDSubbas16\042-F#.wav
Pipe008=.\PEDSubbas16\043-G.wav
Pipe009=.\PEDSubbas16\044-G#.wav
Pipe010=.\PEDSubbas16\045-A.wav
Pipe011=.\PEDSubbas16\046-A#.wav
Pipe012=.\PEDSubbas16\047-B.wav
Pipe013=.\PEDSubbas16\048-C.wav
Pipe014=.\PEDSubbas16\049-C#.wav
Pipe015=.\PEDSubbas16\050-D.wav
Pipe016=.\PEDSubbas16\051-D#.wav
Pipe016AmplitudeLevel=150
Pipe017=.\PEDSubbas16\052-E.wav
Pipe017AmplitudeLevel=140
Pipe018=.\PEDSubbas16\053-F.wav
Pipe018AmplitudeLevel=120
Pipe019=.\PEDSubbas16\054-F#.wav
Pipe019AmplitudeLevel=125
Pipe020=.\PEDSubbas16\055-G.wav
Pipe020AmplitudeLevel=140
Pipe021=.\PEDSubbas16\056-G#.wav
Pipe021AmplitudeLevel=150
Pipe022=.\PEDSubbas16\057-A.wav
Pipe022AmplitudeLevel=140
Pipe023=.\PEDSubbas16\058-A#.wav
Pipe023AmplitudeLevel=120
Pipe024=.\PEDSubbas16\059-B.wav
Pipe025=.\PEDSubbas16\060-C.wav
Pipe026=.\PEDSubbas16\061-C#.wav
Pipe027=.\PEDSubbas16\062-D.wav
Pipe028=.\PEDSubbas16\063-D#.wav
Pipe029=.\PEDSubbas16\064-E.wav
Pipe030=.\PEDSubbas16\065-F.wav
Pipe031=.\PEDSubbas16\066-F#.wav
Pipe032=.\PEDSubbas16\067-G.wav

I could write a lengthy message about the audio libraries internal capability. In fact, I've already written a page about how to create new objects in the library, and of course all the source code is published. I really do not feel like writing a LOT more when you have put forth so little effort.

My hope today was to obtain a collection of WAV files which could be used as a simple MIDI to note playing example, to demonstrate the recently added SerialFlash playing object. If you had provided a set of WAV files with clear mapping from MIDI note (and maybe velocity) to each file, and the files were simple playback, triggered only by Note-On and not requiring complex looping, then I probably would have composed a simple example program which received MIDI Note-On messages and played the files.

But you did NOT provide a ready-to-use set of WAV files with clear mapping. Instead, you pointed to a data set (actually, several and you couldn't even be specific about exactly which file to download) meant for specific organ simulation software. The mapping is in a text file specific to that software, without documentation, and all of it appears to be specific to organ construction, not MIDI messages.

My time is very limited. I only had about an hour available to look at files, and now I've spent most of that time trying to make sense of the piteaMHS data set. If you had put forth more effort, to make a set of WAV files to be simply played (no looping) with clearly defined mapping from MIDI parameters to file names, I very likely would have created an example program for them. But you did not do this.

036-C.wav means that the first C key on the organ keyboard must launch the 036-C.wav,
036-C#.wav for the C#, and so on.
Don't mind with the complex OurOrgan ODF (object description file). Which are only usefull for the man-machine interface : position of the drawknobs, and so on.
OurOrgan (GrandOrgue2) is available online.
You can download GO2 and run it on my webpage :
http://pascal.leray.free.fr/musique/orgue_liturgique_virtuel_en.html
which can run the Pitea or Burea other sample sets.
But of course, OurOrgan is globally a very complex software, but I think that the kernel, which is unsing RT-AUDIO is fairly simple.
 
Dear Paul,

OurOrgan open source code is available.
I upload the 1538 open source code release on my website :
http://pascal.leray.free.fr/downloads/ourorgan_src_1538.7z

Please advise me when your transfers will be finished.

RT_AUDIO is also available as open source code.

If you are interested, I can send you also my source code. Of course, it's not finished, but it achieves to play several keys and detects loop addresses.
It has been compiled by VISUAL C++ 6 on PC.

Pascal Leray
 
Status
Not open for further replies.
Back
Top