Browse Source

Update the PlaySynthMusic example to use a floating point table of note frequencies (not divided by 2)

dds
Pete (El Supremo) 11 years ago
parent
commit
7b68746d03
2 changed files with 55 additions and 23 deletions
  1. +24
    -1
      examples/PlaySynthMusic/PlaySynthMusic.h
  2. +31
    -22
      examples/PlaySynthMusic/PlaySynthMusic.ino

+ 24
- 1
examples/PlaySynthMusic/PlaySynthMusic.h View File

// Generated from Excel by =ROUND(2*440/32*(2^((x-9)/12)),0) for 0<x<128 // Generated from Excel by =ROUND(2*440/32*(2^((x-9)/12)),0) for 0<x<128
// The lowest notes might not work, depending on the Arduino clock frequency // The lowest notes might not work, depending on the Arduino clock frequency


#ifdef ORIGINAL_TABLE
const unsigned int tune_frequencies2_PGM[128] = const unsigned int tune_frequencies2_PGM[128] =
{ {
16,17,18,19,21,22,23,24,26,28,29,31,33,35,37,39,41, 16,17,18,19,21,22,23,24,26,28,29,31,33,35,37,39,41,
13290,14080,14917,15804,16744,17740,18795,19912,21096, 13290,14080,14917,15804,16744,17740,18795,19912,21096,
22351,23680,25088 22351,23680,25088
}; };

#else
// This is for the Teensy Audio library which specifies
// frequencies as floating point. See make_notetab.xlsx
const float tune_frequencies2_PGM[128] =
{
8.1758, 8.6620, 9.1770, 9.7227, 10.3009, 10.9134, 11.5623, 12.2499,
12.9783, 13.7500, 14.5676, 15.4339, 16.3516, 17.3239, 18.3540, 19.4454,
20.6017, 21.8268, 23.1247, 24.4997, 25.9565, 27.5000, 29.1352, 30.8677,
32.7032, 34.6478, 36.7081, 38.8909, 41.2034, 43.6535, 46.2493, 48.9994,
51.9131, 55.0000, 58.2705, 61.7354, 65.4064, 69.2957, 73.4162, 77.7817,
82.4069, 87.3071, 92.4986, 97.9989, 103.8262, 110.0000, 116.5409, 123.4708,
130.8128, 138.5913, 146.8324, 155.5635, 164.8138, 174.6141, 184.9972, 195.9977,
207.6523, 220.0000, 233.0819, 246.9417, 261.6256, 277.1826, 293.6648, 311.1270,
329.6276, 349.2282, 369.9944, 391.9954, 415.3047, 440.0000, 466.1638, 493.8833,
523.2511, 554.3653, 587.3295, 622.2540, 659.2551, 698.4565, 739.9888, 783.9909,
830.6094, 880.0000, 932.3275, 987.7666, 1046.5023, 1108.7305, 1174.6591, 1244.5079,
1318.5102, 1396.9129, 1479.9777, 1567.9817, 1661.2188, 1760.0000, 1864.6550, 1975.5332,
2093.0045, 2217.4610, 2349.3181, 2489.0159, 2637.0205, 2793.8259, 2959.9554, 3135.9635,
3322.4376, 3520.0000, 3729.3101, 3951.0664, 4186.0090, 4434.9221, 4698.6363, 4978.0317,
5274.0409, 5587.6517, 5919.9108, 6271.9270, 6644.8752, 7040.0000, 7458.6202, 7902.1328,
8372.0181, 8869.8442, 9397.2726, 9956.0635, 10548.0818, 11175.3034, 11839.8215, 12543.8540
};
#endif


#define CMD_PLAYNOTE 0x90 /* play a note: low nibble is generator #, note is next byte */ #define CMD_PLAYNOTE 0x90 /* play a note: low nibble is generator #, note is next byte */
#define CMD_STOPNOTE 0x80 /* stop a note: low nibble is generator # */ #define CMD_STOPNOTE 0x80 /* stop a note: low nibble is generator # */

+ 31
- 22
examples/PlaySynthMusic/PlaySynthMusic.ino View File

// Implement the midi player inside the Audio library. // Implement the midi player inside the Audio library.
// This uses the new version of the waveform generator code // This uses the new version of the waveform generator code
// See PlayMidiTones for code which uses the old version // See PlayMidiTones for code which uses the old version

#include <Audio.h> #include <Audio.h>
#include <Wire.h> #include <Wire.h>
&sine7, &sine7,
}; };


// allocate a wave type to each channel.
// The types used and their order is purely arbitrary.
short wave_type[8] = {
TONE_TYPE_SINE,
TONE_TYPE_SQUARE,
TONE_TYPE_SAWTOOTH,
TONE_TYPE_TRIANGLE,
TONE_TYPE_SINE,
TONE_TYPE_SQUARE,
TONE_TYPE_SAWTOOTH,
TONE_TYPE_TRIANGLE,
};

// Two mixers are needed to handle the 8 channels of music
AudioMixer4 mixer1; AudioMixer4 mixer1;
AudioMixer4 mixer2; AudioMixer4 mixer2;
AudioOutputI2S audioOut; AudioOutputI2S audioOut;


// Mix the first four channels into mixer1
AudioConnection c0(sine0, 0, mixer1, 0); AudioConnection c0(sine0, 0, mixer1, 0);
AudioConnection c1(sine1, 0, mixer1, 1); AudioConnection c1(sine1, 0, mixer1, 1);
AudioConnection c2(sine2, 0, mixer1, 2); AudioConnection c2(sine2, 0, mixer1, 2);
AudioConnection c3(sine3, 0, mixer1, 3); AudioConnection c3(sine3, 0, mixer1, 3);


// and the last 4 channels into mixer2
AudioConnection c4(sine4, 0, mixer2, 0); AudioConnection c4(sine4, 0, mixer2, 0);
AudioConnection c5(sine5, 0, mixer2, 1); AudioConnection c5(sine5, 0, mixer2, 1);
AudioConnection c6(sine6, 0, mixer2, 2); AudioConnection c6(sine6, 0, mixer2, 2);
AudioConnection c7(sine7, 0, mixer2, 3); AudioConnection c7(sine7, 0, mixer2, 3);

// Output mixre1 to the left channel and mixer2 to the right
AudioConnection c11(mixer1, 0, audioOut, 0); AudioConnection c11(mixer1, 0, audioOut, 0);
AudioConnection c12(mixer2, 0, audioOut, 1); AudioConnection c12(mixer2, 0, audioOut, 1);


//AudioControl_WM8731 codec; //AudioControl_WM8731 codec;
AudioControlSGTL5000 codec; AudioControlSGTL5000 codec;


// Initial value of the volume control
int volume = 50; int volume = 50;


// allocate a wave type to each channel.
// The types used and their order is purely arbitrary.
short wave_type[8] = {
TONE_TYPE_SINE,
TONE_TYPE_SQUARE,
TONE_TYPE_SAWTOOTH,
TONE_TYPE_TRIANGLE,
TONE_TYPE_SINE,
TONE_TYPE_SQUARE,
TONE_TYPE_SAWTOOTH,
TONE_TYPE_TRIANGLE,
};

void setup() void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
while (!Serial) ; while (!Serial) ;
delay(3000);

delay(2000);
// http://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html
Serial.print("Begin ");
Serial.println(__FILE__);
// Proc = 12 (13), Mem = 2 (8)
// Audio connections require memory to work. // Audio connections require memory to work.
// The memory usage code indicates that 8 is the maximum // The memory usage code indicates that 8 is the maximum
// so give it 10 just to be sure. // so give it 10 just to be sure.
// Comment this if you don't it // Comment this if you don't it
codec.unmuteLineout(); codec.unmuteLineout();


// Set the ramp time for each wave object // Set the ramp time for each wave object
for(int i = 0; i < 8;i++) { for(int i = 0; i < 8;i++) {
waves[i]->set_ramp_length(88); waves[i]->set_ramp_length(88);
} }


Serial.println("Begin PlayMidiTones");

Serial.println("setup done"); Serial.println("setup done");
// Initialize processor and memory measurements // Initialize processor and memory measurements
unsigned char c,opcode,chan; unsigned char c,opcode,chan;
unsigned long d_time; unsigned long d_time;
// Change this to if(1) for measurement output
if(0) {
// Change this to if(1) for measurement output every 5 seconds
if(1) {
/* /*
For PlaySynthMusic this produces: For PlaySynthMusic this produces:
Proc = 20 (21), Mem = 2 (8) Proc = 20 (21), Mem = 2 (8)
codec.volume((float)n / 10.23); codec.volume((float)n / 10.23);
} }
// read the next note from the table
c = *sp++; c = *sp++;
opcode = c & 0xf0; opcode = c & 0xf0;
// was 0x0f but I'm only handling 8 channels // was 0x0f but I'm only handling 8 channels
return; return;
} }
// Play the note on 'chan'
// Play the note on 'chan' - divide the frequency by two because the
// table of frequencies has been doubled.
if(opcode == CMD_PLAYNOTE) { if(opcode == CMD_PLAYNOTE) {
waves[chan]->begin(AMPLITUDE,tune_frequencies2_PGM[*sp++], waves[chan]->begin(AMPLITUDE,tune_frequencies2_PGM[*sp++],
wave_type[chan]); wave_type[chan]);

Loading…
Cancel
Save