Jack Gassett

Audio Wing Examples

Recommended Posts

Hey everyone,

I'm looking at writing an Introduction to Papilio article for the Audio Wing and have been trying to brainstorm cool examples for the Audio Wing.

So far I've been thinking of:

Simple Sketches:

  • Generating simple tones
  • Trying out some of the more advanced arduino audio sketches (don't think we can get to far with these)

More advanced sketches with FPGA peripherals:

  • If I can find an existing sketch that outputs to a DAC I can show how to implement a Delta-Sigma DAC inside the FPGA so no external DAC is needed.
  • I have a DDS peripheral that can generate sine, cos, square, and saw waves in fpga hardware. I could modify the tone library to use the DDS peripheral instead of a PWM.
  • I can connect the Gateman Poly synthesizer project to the AVR8 and let sketches that send MIDI commands to the Gateman Poly play songs.

FPGA only projects:

  • I have a project that is already working that streams MP3 files from your computer to the Papilio. The Papilio runs the high speed Xilinx UART example and a Delta-Sigma DAC. There is an app on the computer that converts MP3 to the WAV format needed by the FPGA. The result is CD quality audio output.
  • Someone posted example code to get SID files to play on a virtual SID.

Does anyone have any ideas for example audio projects that can be done pretty quickly? What do you think about these ideas?

Thanks,

Jack.

Share this post


Link to post
Share on other sites

Ok, so I came across these two interesting examples of converting MIDI files to Arduino sketches that can be played on the YMZ249 and I figured since we have a YM2149 integrated into the ZPUino I'd give it a go.

http://kalshagar.wikispaces.com/MIDI%2C+CSharp+and+Yamaha+chips

http://kalshagar.wikispaces.com/Arduino+and+a+YMZ294

I got it working but there is something that seems to be off. I'm taped out for the day, if I stare at this any longer I'll have a headache. :) But I thought I'd post the sketch for anyone who wanted to try it on the Arcade MegaWing. If anyone can see what is wrong it is appreciated. It's supposed to play the final fantasy IV theme song, but it seems to high pitched and a bit screechy, like listening to nails on a chalkboard. You can hear the general song, but I wonder if I'm missing a difference between the YMZ294 and the YM2149... Actually, just thinking aloud now... I bet the speed that the YM2149 is running is faster then the 4Mhz that the chip in the example is running at. You need to load the ZPUino bit file and use the ZPUino IDE for this to work.

//YMZ294
//#include "YMZ294.h"

#define YMZ294_WR 10
#define YMZ294_CS 11
#define YMZ294_A0 12

#define ADDR_FREQ_A 0x00
#define ADDR_FREQ_B 0x02
#define ADDR_FREQ_C 0x04
#define ADDR_NOISE 0x06
#define ADDR_MIXER 0x07
#define ADDR_LEVEL_A 0x08
#define ADDR_LEVEL_B 0x09
#define ADDR_LEVEL_C 0x0A
#define ADDR_FREQ_E 0x0B
#define ADDR_SHAPE_E 0x0D

#define YM2149BASE IO_SLOT(11)
#define YM2149REG(x) REGISTER(YM2149BASE,x)

#define HAVE_YM

#define AUDIOPIN WING_A_15
//#define AUDIOPINEXTRA WING_A_13

int tp[] = {//MIDI note number
  15289, 14431, 13621, 12856, 12135, 11454, 10811, 10204,//0-7
  9631, 9091, 8581, 8099, 7645, 7215, 6810, 6428,//8-15
  6067, 5727, 5405, 5102, 4816, 4545, 4290, 4050,//16-23
  3822, 3608, 3405, 3214, 3034, 2863, 2703, 2551,//24-31
  2408, 2273, 2145, 2025, 1911, 1804, 1703, 1607,//32-39
  1517, 1432, 1351, 1276, 1204, 1136, 1073, 1012,//40-47
  956, 902, 851, 804, 758, 716, 676, 638,//48-55
  602, 568, 536, 506, 478, 451, 426, 402,//56-63
  379, 358, 338, 319, 301, 284, 268, 253,//64-71
  239, 225, 213, 201, 190, 179, 169, 159,//72-79
  150, 142, 134, 127, 119, 113, 106, 100,//80-87
  95, 89, 84, 80, 75, 71, 67, 63,//88-95
  60, 56, 53, 50, 47, 45, 42, 40,//96-103
  38, 36, 34, 32, 30, 28, 27, 25,//104-111
  24, 22, 21, 20, 19, 18, 17, 16,//112-119
  15, 14, 13, 13, 12, 11, 11, 10,//120-127
  0//off
};

void write_data(unsigned char address, unsigned char data)
{
  YM2149REG(address) = data;
}

void set_ch(unsigned char address, int i)
{
  write_data(address, tp[i]);
}

//YMZ294 related : set the volume between 0x00 (mute) and 0xff(full)
//For the simplicity it sets the volume of the 3 channels at the same time.
//Just make another signature if youwant to control channel per channel.
void setVolumeYMZ294(byte pVolume){
  write_data(ADDR_LEVEL_A, pVolume & 0x0f);
  write_data(ADDR_LEVEL_B, pVolume & 0x0f);
  write_data(ADDR_LEVEL_C, pVolume & 0x0f); 
}

//makes the setup for the Yamaha YMZ294 component
void setupYMZ294(){
  //no noise
  write_data(ADDR_NOISE, 0x00);
  //mixer
  //write_data(ADDR_MIXER, 0x3e);
  write_data(ADDR_MIXER, 0x38);

  //set volume to MUTE
  setVolumeYMZ294(0x00); 
}

void setup(){

    pinMode(AUDIOPIN,OUTPUT);
    digitalWrite(AUDIOPIN,HIGH);
    outputPinForFunction(AUDIOPIN, 14);
    pinModePPS(AUDIOPIN, HIGH);

#ifdef AUDIOPINEXTRA
    pinMode(AUDIOPINEXTRA,OUTPUT);
    outputPinForFunction(AUDIOPINEXTRA, 14);
    pinModePPS(AUDIOPINEXTRA, HIGH);
#endif 
 
  ///Setup the pin modes for the YMZ294
  setupYMZ294();
 
  //don't forget to set the volume or you wont hear a thing...
  setVolumeYMZ294(0xff);
}

void loop(){
    //the best : Final Fantasy!
  ffiv();
}



void ffiv(){
  //mixer
  //channel a  b c
  write_data(ADDR_MIXER, 0x38);
  set_ch(ADDR_FREQ_A,0);
  set_ch(ADDR_FREQ_B,0);
  set_ch(ADDR_FREQ_C,0);

  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,33);
  delay(91);
  set_ch(ADDR_FREQ_B,60);
  delay(107);
  set_ch(ADDR_FREQ_B,64);
  delay(106);
  set_ch(ADDR_FREQ_B,69);
  delay(107);
  set_ch(ADDR_FREQ_B,55);
  set_ch(ADDR_FREQ_C,33);
  delay(106);
  set_ch(ADDR_FREQ_B,59);
  delay(107);
  set_ch(ADDR_FREQ_B,62);
  delay(108);
  set_ch(ADDR_FREQ_B,67);
  delay(106);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,33);
  delay(107);
  set_ch(ADDR_FREQ_B,60);
  delay(106);
  set_ch(ADDR_FREQ_B,64);
  delay(107);
  set_ch(ADDR_FREQ_B,69);
  delay(106);
  set_ch(ADDR_FREQ_B,59);
  set_ch(ADDR_FREQ_C,33);
  delay(107);
  set_ch(ADDR_FREQ_B,62);
  delay(108);
  set_ch(ADDR_FREQ_B,67);
  delay(106);
  set_ch(ADDR_FREQ_B,71);
  delay(107);
  set_ch(ADDR_FREQ_B,60);
  set_ch(ADDR_FREQ_C,33);
  delay(106);
  set_ch(ADDR_FREQ_B,64);
  delay(107);
  set_ch(ADDR_FREQ_B,69);
  delay(106);
  set_ch(ADDR_FREQ_B,72);
  delay(107);
  set_ch(ADDR_FREQ_B,59);
  set_ch(ADDR_FREQ_C,33);
  delay(108);
  set_ch(ADDR_FREQ_B,62);
  delay(106);
  set_ch(ADDR_FREQ_B,67);
  delay(107);
  set_ch(ADDR_FREQ_B,71);
  delay(106);
  set_ch(ADDR_FREQ_B,60);
  set_ch(ADDR_FREQ_C,33);
  delay(107);
  set_ch(ADDR_FREQ_B,64);
  delay(106);
  set_ch(ADDR_FREQ_B,69);
  delay(107);
  set_ch(ADDR_FREQ_B,72);
  delay(108);
  set_ch(ADDR_FREQ_B,62);
  set_ch(ADDR_FREQ_C,33);
  delay(106);
  set_ch(ADDR_FREQ_B,67);
  delay(107);
  set_ch(ADDR_FREQ_B,71);
  delay(106);
  set_ch(ADDR_FREQ_B,74);
  delay(107);
  set_ch(ADDR_FREQ_A,69);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,33);
  delay(106);
  set_ch(ADDR_FREQ_B,60);
  delay(107);
  set_ch(ADDR_FREQ_B,64);
  delay(108);
  set_ch(ADDR_FREQ_B,69);
  delay(106);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,33);
  delay(107);
  set_ch(ADDR_FREQ_B,60);
  delay(106);
  set_ch(ADDR_FREQ_B,64);
  delay(107);
  set_ch(ADDR_FREQ_B,69);
  delay(106);
  set_ch(ADDR_FREQ_A,72);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,33);
  delay(107);
  set_ch(ADDR_FREQ_B,60);
  delay(108);
  set_ch(ADDR_FREQ_B,64);
  delay(106);
  set_ch(ADDR_FREQ_B,69);
  delay(107);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,33);
  delay(106);
  set_ch(ADDR_FREQ_B,60);
  delay(107);
  set_ch(ADDR_FREQ_B,64);
  delay(106);
  set_ch(ADDR_FREQ_B,69);
  delay(107);
  set_ch(ADDR_FREQ_A,76);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,33);
  delay(108);
  set_ch(ADDR_FREQ_B,60);
  delay(106);
  set_ch(ADDR_FREQ_B,64);
  delay(107);
  set_ch(ADDR_FREQ_B,69);
  delay(106);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,33);
  delay(107);
  set_ch(ADDR_FREQ_B,60);
  delay(106);
  set_ch(ADDR_FREQ_B,64);
  delay(107);
  set_ch(ADDR_FREQ_B,69);
  delay(108);
  set_ch(ADDR_FREQ_A,79);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,33);
  delay(105);
  set_ch(ADDR_FREQ_B,60);
  delay(107);
  set_ch(ADDR_FREQ_B,64);
  delay(106);
  set_ch(ADDR_FREQ_B,69);
  delay(107);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,33);
  delay(106);
  set_ch(ADDR_FREQ_B,60);
  delay(107);
  set_ch(ADDR_FREQ_B,64);
  delay(108);
  set_ch(ADDR_FREQ_B,69);
  delay(106);
  set_ch(ADDR_FREQ_A,78);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,38);
  delay(107);
  set_ch(ADDR_FREQ_B,62);
  delay(106);
  set_ch(ADDR_FREQ_B,66);
  delay(107);
  set_ch(ADDR_FREQ_B,69);
  delay(106);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,38);
  delay(107);
  set_ch(ADDR_FREQ_B,62);
  delay(107);
  set_ch(ADDR_FREQ_B,66);
  delay(106);
  set_ch(ADDR_FREQ_B,69);
  delay(107);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,38);
  delay(106);
  set_ch(ADDR_FREQ_B,62);
  delay(107);
  set_ch(ADDR_FREQ_B,66);
  delay(106);
  set_ch(ADDR_FREQ_B,69);
  delay(107);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,38);
  delay(108);
  set_ch(ADDR_FREQ_B,62);
  delay(106);
  set_ch(ADDR_FREQ_B,66);
  delay(107);
  set_ch(ADDR_FREQ_B,69);
  delay(106);
  set_ch(ADDR_FREQ_A,74);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,38);
  delay(107);
  set_ch(ADDR_FREQ_B,62);
  delay(106);
  set_ch(ADDR_FREQ_B,66);
  delay(107);
  set_ch(ADDR_FREQ_B,69);
  delay(108);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,38);
  delay(106);
  set_ch(ADDR_FREQ_B,62);
  delay(107);
  set_ch(ADDR_FREQ_B,66);
  delay(106);
  set_ch(ADDR_FREQ_B,69);
  delay(107);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,38);
  delay(105);
  set_ch(ADDR_FREQ_B,62);
  delay(107);
  set_ch(ADDR_FREQ_A,74);
  set_ch(ADDR_FREQ_B,66);
  delay(108);
  set_ch(ADDR_FREQ_B,69);
  delay(106);
  set_ch(ADDR_FREQ_A,74);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,38);
  delay(107);
  set_ch(ADDR_FREQ_B,62);
  delay(106);
  set_ch(ADDR_FREQ_A,76);
  set_ch(ADDR_FREQ_B,66);
  delay(107);
  set_ch(ADDR_FREQ_B,69);
  delay(106);
  set_ch(ADDR_FREQ_A,77);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,29);
  delay(107);
  set_ch(ADDR_FREQ_B,60);
  delay(108);
  set_ch(ADDR_FREQ_B,65);
  delay(106);
  set_ch(ADDR_FREQ_B,69);
  delay(107);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,29);
  delay(106);
  set_ch(ADDR_FREQ_B,60);
  delay(107);
  set_ch(ADDR_FREQ_B,65);
  delay(106);
  set_ch(ADDR_FREQ_B,69);
  delay(107);
  set_ch(ADDR_FREQ_A,79);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,29);
  delay(108);
  set_ch(ADDR_FREQ_B,60);
  delay(106);
  set_ch(ADDR_FREQ_B,65);
  delay(107);
  set_ch(ADDR_FREQ_B,69);
  delay(106);
  set_ch(ADDR_FREQ_A,77);
  set_ch(ADDR_FREQ_B,57);
  set_ch(ADDR_FREQ_C,31);
  delay(107);
  set_ch(ADDR_FREQ_B,60);
  delay(106);
  set_ch(ADDR_FREQ_B,65);
  delay(107);
  set_ch(ADDR_FREQ_B,69);
  delay(108);
  set_ch(ADDR_FREQ_A,76);
  set_ch(ADDR_FREQ_B,55);
  set_ch(ADDR_FREQ_C,33);
  delay(106);
  set_ch(ADDR_FREQ_B,60);
  delay(107);
  set_ch(ADDR_FREQ_B,64);
  delay(106);
  set_ch(ADDR_FREQ_B,67);
  delay(107);
  set_ch(ADDR_FREQ_A,72);
  set_ch(ADDR_FREQ_B,55);
  set_ch(ADDR_FREQ_C,33);
  delay(106);
  set_ch(ADDR_FREQ_B,60);
  delay(107);
  set_ch(ADDR_FREQ_B,64);
  delay(108);
  set_ch(ADDR_FREQ_B,67);
  delay(106);
  set_ch(ADDR_FREQ_A,69);
  set_ch(ADDR_FREQ_B,55);
  set_ch(ADDR_FREQ_C,33);
  delay(107);
  set_ch(ADDR_FREQ_B,60);
  delay(106);
  set_ch(ADDR_FREQ_B,64);
  delay(107);
  set_ch(ADDR_FREQ_B,67);
  delay(106);
  set_ch(ADDR_FREQ_A,72);
  set_ch(ADDR_FREQ_B,55);
  set_ch(ADDR_FREQ_C,33);
  delay(107);
  set_ch(ADDR_FREQ_B,60);
  delay(108);
  set_ch(ADDR_FREQ_B,64);
  delay(106);
  set_ch(ADDR_FREQ_B,67);
  delay(108);
  set_ch(ADDR_FREQ_A,74);
  set_ch(ADDR_FREQ_B,55);
  set_ch(ADDR_FREQ_C,31);
  delay(105);
  set_ch(ADDR_FREQ_B,58);
  delay(107);
  set_ch(ADDR_FREQ_B,62);
  delay(106);
  set_ch(ADDR_FREQ_B,67);
  delay(107);
  set_ch(ADDR_FREQ_B,55);
  set_ch(ADDR_FREQ_C,31);
  delay(108);
  set_ch(ADDR_FREQ_B,58);
  delay(106);
  set_ch(ADDR_FREQ_B,62);
  delay(107);
  set_ch(ADDR_FREQ_B,67);
  delay(106);
  set_ch(ADDR_FREQ_B,55);
  set_ch(ADDR_FREQ_C,31);
  delay(107);
  set_ch(ADDR_FREQ_B,58);
  delay(106);
  set_ch(ADDR_FREQ_B,62);
  delay(107);
  set_ch(ADDR_FREQ_B,67);
  delay(108);
  set_ch(ADDR_FREQ_B,55);
  set_ch(ADDR_FREQ_C,31);
  delay(106);
  set_ch(ADDR_FREQ_B,58);
  delay(107);
  set_ch(ADDR_FREQ_B,62);
  delay(106);
  set_ch(ADDR_FREQ_B,67);
  delay(107);
  set_ch(ADDR_FREQ_B,55);
  set_ch(ADDR_FREQ_C,31);
  delay(106);
  set_ch(ADDR_FREQ_B,58);
  delay(107);
  set_ch(ADDR_FREQ_B,62);
  delay(108);
  set_ch(ADDR_FREQ_B,67);
  delay(106);
  set_ch(ADDR_FREQ_B,55);
  set_ch(ADDR_FREQ_C,31);
  delay(107);
  set_ch(ADDR_FREQ_B,58);
  delay(106);
  set_ch(ADDR_FREQ_B,62);
  delay(107);
  set_ch(ADDR_FREQ_B,67);
  delay(106);
  set_ch(ADDR_FREQ_B,55);
  set_ch(ADDR_FREQ_C,31);
  delay(107);
  set_ch(ADDR_FREQ_B,58);
  delay(108);
  set_ch(ADDR_FREQ_B,62);
  delay(106);
  set_ch(ADDR_FREQ_B,67);
  delay(107);
  set_ch(ADDR_FREQ_A,72);
  set_ch(ADDR_FREQ_B,55);
  set_ch(ADDR_FREQ_C,31);
  delay(106);
  set_ch(ADDR_FREQ_B,58);
  delay(107);
  set_ch(ADDR_FREQ_B,62);
  delay(106);
  set_ch(ADDR_FREQ_B,67);
  delay(107);
  set_ch(ADDR_FREQ_A,74);
  set_ch(ADDR_FREQ_B,53);
  set_ch(ADDR_FREQ_C,29);
  delay(108);
  set_ch(ADDR_FREQ_B,56);
  delay(106);
  set_ch(ADDR_FREQ_B,60);
  delay(107);
  set_ch(ADDR_FREQ_B,65);
  delay(106);
  set_ch(ADDR_FREQ_B,53);
  set_ch(ADDR_FREQ_C,29);
  delay(107);
  set_ch(ADDR_FREQ_B,56);
  delay(106);
  set_ch(ADDR_FREQ_B,60);
  delay(107);
  set_ch(ADDR_FREQ_B,65);
  delay(108);
  set_ch(ADDR_FREQ_B,53);
  set_ch(ADDR_FREQ_C,29);
  delay(106);
  set_ch(ADDR_FREQ_B,56);
  delay(107);
  set_ch(ADDR_FREQ_B,60);
  delay(106);
  set_ch(ADDR_FREQ_B,65);
  delay(107);
  set_ch(ADDR_FREQ_B,53);
  set_ch(ADDR_FREQ_C,29);
  delay(106);
  set_ch(ADDR_FREQ_B,56);
  delay(107);
  set_ch(ADDR_FREQ_B,60);
  delay(108);
  set_ch(ADDR_FREQ_B,65);


}

Share this post


Link to post
Share on other sites

Well, I worked through this issue a couple days ago. I have Final Fantasy IV theme song playing through YM2149 chip now!

Not only that, I have it working with my MIDI keyboard now too! I can play the YM2149 with my MIDI keyboard and, even cooler, it works with my MIDI guitar too!

Playing a classic arcade sound chip as a MIDI instrument, all controlled by a sketch. It's pretty cool, source code to be released soon.

Jack.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now