Tone library and RTTTL (RingTone Text Transfer Language) player
Download Tone and RTTTL player libraries v1.1
Overview
The Tone library is an enhanced version of the arduino library, useful for generating square waves.
It uses a TMR + CCP peripheral, along with an interrupt to generate square waves on any user-defined pin.
Many times the PWM peripheral is used to generate waveforms. While this is convenient, PWM on the PIC18 is tied to the clock frequency and for most devices is limited in its low-frequency range. With a limit of a 1:16 clock prescaler, generating a 30Hz audio tone using PWM would limit you to a max cpu clock of < 1MHz!
Also, unless the device has PPS you are limited by the fixed output pins of the device available for PWM.
This library uses a TMR and CCP peripheral in compare mode to generate the timing, with the output pin controlled by software using the CCP interrupt. This allows for generation of a wide range of tones at almost any clock setting. The code presented here is written for the 18FxxK22 using TMR1 and CCP1 but could easily be adapted for other devices/peripheral combinations.
Enhancements to the original arduino library include both blocking and non-blocking mode operation, and the ability to play an array of notes instead of just a single tone.
V1.1 Update
- adds events that get called when a tone starts and stops playing (see tone_events.bas and RTTTL_events.bas for examples)
- consolidate into single download for both libraries
Basic Operation
Using the module is easy. Simply define your output pin using '#option TONE_OUTPUT_PIN', include tone.bas and call the init() routine to set up the hardware.
// specify output pin #option TONE_OUTPUT_PIN = PORTC.2 include "tone.bas" tone.init()
There are several methods available for playing tones, the simplest of which is the 'Play(freq, duration)' routine, where 'freq' is in Hz and 'duration' in msecs. The tones will automatically stop when the duration expires, or you can use Stop() to terminate it. If 'duration' is 0 (or is not specified) then the tone plays continuously until Stop() is called.
tone.play(440, 1000) // play A (440Hz) for 1000ms tone.play(440) // play note until stop delayms(1000) // do other stuff tone.stop() // stop playing tone
You can also specify a const array of notes (freq and duration word pairs) and play the entire sequence, or just a portion of it. Another method allows you to build an array in ram at runtime and play that. For ease of use, constants are defined for the 88 notes found on standard piano keys (ie NOTE_A4). A special NOTE_PAUSE allows to to insert a delay in the sequence.
const song() as word = // an array of (freq, duration) note pairs ( NOTE_A4, 500, NOTE_PAUSE, 250, NOTE_F4, 350, NOTE_CS4, 850 } tone.play(song)
Blocking vs Non-blocking Mode
By default, Play() is non-blocking and will start a tone playing and immediately return while the tone plays (this replicates the original arduino library). You must use isPlaying() or Wait() to determine when a tone has finished before calling Play() again or the current tone will just stop.
tone.play(NOTE_A4, 1000) // play A (440Hz) for 1000ms while tone.isPlaying() // wait for tone to finish... end while // or tone.play(440, 1000) // play A (440Hz) for 1000ms tone.wait() // wait for tone to finish
The module allows you to change the mode to blocking so that Play() will automatically wait for tones to finish before returning. This makes it simpler if you're playing a sequence of tones. Blocking mode is enabled using the SetWait() routine, or can be set by specifying '#option TONE_WAIT = true' before including the module.
tone.setwait() // enable blocking mode // no longer have to call wait between notes... tone.play(NOTE_A4, 500) // play A for 500ms tone.play(NOTE_G4, 500) // play G for 500ms
Start and Stop Events
The Tone module defines two events: a Start event that's called when a tone begins playing, and a Stop event that gets called when a tone stops. You can set these to your user-defined event routines using 'set_events()'. Since the events are implemented as part of the tone library, they can also be defined when using the RTTTL player.
tone.init() tone.setwait() // enable blocking mode // set tone events tone.set_events(tone_start_event, tone_stop_event)
Tone library example program
// tone library example program tone_example device = 18F26K22 clock = 64 // int osc and IO pin libraries include "intosc.bas" #option DIGITALIO_INIT = true // automatically call setalldigital #option DIGITALIO_SLEWRATE = 1 // 1=slow (we don't need fast edges) include "setdigitalio.bas" // tone library options // specify output pin #option TONE_OUTPUT_PIN = PORTC.2 // wait flag setting (default = false) '#option TONE_WAIT = true include "tone.bas" // star wars imperial march using individual tone play calls sub Play_Imperial_March() tone.setwait() tone.play(NOTE_A4, 500) tone.play(NOTE_A4, 500) tone.play(NOTE_A4, 500) tone.play(NOTE_F4, 350) tone.play(NOTE_C5, 150) tone.play(NOTE_A4, 500) tone.play(NOTE_F4, 350) tone.play(NOTE_C5, 150) tone.play(NOTE_A4, 1000) tone.play(NOTE_PAUSE, 250) tone.play(NOTE_E5, 500) tone.play(NOTE_E5, 500) tone.play(NOTE_E5, 500) tone.play(NOTE_F5, 350) tone.play(NOTE_C5, 150) tone.play(NOTE_GS4, 500) tone.play(NOTE_F4, 350) tone.play(NOTE_C5, 150) tone.play(NOTE_A4, 1000) tone.play(NOTE_PAUSE, 250) end sub // const array of (freq, duration) note pairs const Imperial_March() as word = ( NOTE_A4, 500, NOTE_A4, 500, NOTE_A4, 500, NOTE_F4, 350, NOTE_C5, 150, NOTE_A4, 500, NOTE_F4, 350, NOTE_C5, 150, NOTE_A4, 1000, NOTE_PAUSE, 250, NOTE_E5, 500, NOTE_E5, 500, NOTE_E5, 500, NOTE_F5, 350, NOTE_C5, 150, NOTE_GS4, 500, NOTE_F4, 350, NOTE_C5, 150, NOTE_A4, 1000, NOTE_PAUSE, 250 ) dim ix as byte dim note as word dim num_notes as word // note list in ram (freq, duration pairs) dim note_list(64*2) as word main: // init tone library module tone.init() // play a note until stop() tone.play(NOTE_A4) // tone A (440) will play forever... delayms(1000) // allow note to play for 1sec tone.stop() // and now stop it // tone.play defaults to non-blocking mode... // it returns immediately and does not wait tone.setwait(false) // this is the tone library default setting tone.play(NOTE_G4, 500) // play G for 500ms tone.wait() // wait for note to finish // set play to blocking mode... // it now returns when done and no need to call wait // (you can change the tone library default using '#option TONE_WAIT = true') tone.setwait() // set wait_flag true tone.play(NOTE_A4, 100) // play A for 100ms // play all 88 piano notes defined in the tone module for 250ms each for ix = 0 to bound(tone.notes) note = tone.notes(ix) // get note from the list tone.play(note, 250) // play note for 250ms delayms(10) // short delay between notes next // play a tune using individual calls (long winded approach) Play_Imperial_March() // array functions // play a const array of notes tone.play(Imperial_March) // play first 9 notes from the const array tone.play(Imperial_March, 9) // play an array of notes in ram clear(note_list) note_list = Imperial_March // copy the const array to ram num_notes = NOTE_COUNT(Imperial_March) // get number of notes defined in the const array tone.play(note_list, num_notes) // play entire tune // play first 9 notes from the array in ram tone.play(note_list, 9) while (true) end while end program
RingTone Text Transfer Language (RTTTL) Player using Tone library
RTTTL is a text-based method for specifying sequences of notes, first developed by Nokia for cell phone ringtones.
There is a description of the language in the RTTTL.bas module so I won't repeat it here. Since it uses the Tone library to generate the notes, using the player is simple... include RTTTL, define your tune, and play it! You can find many examples of RTTTL and ringtones on the web.
public const HappyBday = "HappyBday:d=4,o=5,b=125:8d.,16d,e,d,g,2f#,8p, 8d.,16d,e,d,a,2g,8p, 8d.,16d,d6,b,g,f#,2e,8p,8c6.,16c6,b,g,a,2g" rtttl.play(@HappyBday)
RTTTL library example program
// RTTTL example (RingTone Text Transfer Language) // uses tone module for generating notes program RTTTL_example device = 18F26K22 clock = 64 // int osc and IO pin libraries include "intosc.bas" #option DIGITALIO_INIT = true // automatically call setalldigital #option DIGITALIO_SLEWRATE = 1 // 1=slow (we don't need fast edges) include "setdigitalio.bas" // tone library // specify output pin #option TONE_OUTPUT_PIN = PORTC.2 include "tone.bas" // RTTTL library (uses tone library) include "rtttl.bas" // some example RTTTL tunes public const HappyBday = "HappyBday:d=4,o=5,b=125:8d.,16d,e,d,g,2f#,8p, 8d.,16d,e,d,a,2g,8p, 8d.,16d,d6,b,g,f#,2e,8p,8c6.,16c6,b,g,a,2g" public const Simpsons = "The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6" public const IndianaJones = "IndianaJones:d=4,o=5,b=250:e,8p,8f,8g,8p,1c6,8p.,d,8p,8e,1f,p.,g,8p,8a,8b,8p,1f6,p,a,8p,8b,2c6,2d6,2e6,e,8p,8f,8g,8p,1c6,p,d6,8p,8e6,1f.6,g,8p,8g,e.6,8p,d6,8p,8g,e.6,8p,d6,8p,8g,f.6,8p,e6,8p,8d6,2c6" public const TakeOnMe = "TakeOnMe:d=4,o=4,b=160:8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5,8f#5,8e5,8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5" public const Entertainer = "Entertainer:d=4,o=5,b=140:8d,8d#,8e,c6,8e,c6,8e,2c.6,8c6,8d6,8d#6,8e6,8c6,8d6,e6,8b,d6,2c6,p,8d,8d#,8e,c6,8e,c6,8e,2c.6,8p,8a,8g,8f#,8a,8c6,e6,8d6,8c6,8a,2d6" public const Muppets = "Muppets:d=4,o=5,b=250:c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,8a,8p,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,8e,8p,8e,g,2p,c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,a,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,d,8d,c" public const Xfiles = "Xfiles:d=4,o=5,b=125:e,b,a,b,d6,2b.,2p,e,b,a,b,e6,2b.,2p,g6,f#6,e6,d6,e6,2b.,2p,g6,f#6,e6,d6,f#6,2b.,2p,e,b,a,b,d6,2b.,2p,e,b,a,b,e6,2b.,2p,e6,2b." public const LooneyTunes = "Looney:d=4,o=5,b=140:32p,c6,8f6,8e6,8d6,8c6,a.,8c6,8f6,8e6,8d6,8d#6,e.6,8e6,8e6,8c6,8d6,8c6,8e6,8c6,8d6,8a,8c6,8g,8a#,8a,8f" public const TwentyCenFox = "20thCenFox:d=16,o=5,b=140:b,8p,b,b,2b,p,c6,32p,b,32p,c6,32p,b,32p,c6,32p,b,8p,b,b,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,g#,32p,a,32p,b,8p,b,b,2b,4p,8e,8g#,8b,1c#6,8f#,8a,8c#6,1e6,8a,8c#6,8e6,1e6,8b,8g#,8a,2b" public const Bond = "Bond:d=4,o=5,b=80:32p,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d#6,16d#6,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d6,16c#6,16c#7,c.7,16g#6,16f#6,g#.6" public const MASH = "MASH:d=8,o=5,b=140:4a,4g,f#,g,p,f#,p,g,p,f#,p,2e.,p,f#,e,4f#,e,f#,p,e,p,4d.,p,f#,4e,d,e,p,d,p,e,p,d,p,2c#.,p,d,c#,4d,c#,d,p,e,p,4f#,p,a,p,4b,a,b,p,a,p,b,p,2a.,4p,a,b,a,4b,a,b,p,2a.,a,4f#,a,b,p,d6,p,4e.6,d6,b,p,a,p,2b" public const StarWars = "StarWars:d=4,o=5,b=35:32p,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#.6,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#6" public const ImperialMarch = "ImperialMarch:d=4,o=5,b=100:e,e,e,8c,16p,16g,e,8c,16p,16g,e,p,b,b,b,8c6,16p,16g,d#,8c,16p,16g,e,8p" public const GoodBadUgly = "GoodBad:d=4,o=5,b=56:32a#,32d#6,32a#,32d#6,8a#.,16f#.,16g#.,d#,8p,32a#,32d#6,32a#,32d#6,8a#.,16f#.,16g#.,c#6,8p,32a#,32d#6,32a#,32d#6,8a#.,16f#.,32f.,32d#.,c#,8p,32a#,32d#6,32a#,32d#6,8a#.,16g#.,d#" public const TopGun = "TopGun:d=4,o=4,b=31:32p,16c#,16g#,16g#,32f#,32f,32f#,32f,16d#,16d#,32c#,32d#,16f,32d#,32f,16f#,32f,32c#,16f,d#,16c#,16g#,16g#,32f#,32f,32f#,32f,16d#,16d#,32c#,32d#,16f,32d#,32f,16f#,32f,32c#,g#" public const ATeam = "A-Team:d=8,o=5,b=125:4d#6,a#,2d#6,16p,g#,4a#,4d#.,p,16g,16a#,d#6,a#,f6,2d#6,16p,c#.6,16c6,16a#,g#.,2a#" public const Flintstones = "Flinstones:d=4,o=5,b=40:32p,16f6,16a#,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,d6,16f6,16a#.,16a#6,32g6,16f6,16a#.,32f6,32f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,a#,16a6,16d.6,16a#6,32a6,32a6,32g6,32f#6,32a6,8g6,16g6,16c.6,32a6,32a6,32g6,32g6,32f6,32e6,32g6,8f6,16f6,16a#.,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#6,16c7,8a#.6" public const Jeopardy = "Jeopardy:d=4,o=6,b=125:c,f,c,f5,c,f,2c,c,f,c,f,a.,8g,8f,8e,8d,8c#,c,f,c,f5,c,f,2c,f.,8d,c,a#5,a5,g5,f5,p,d#,g#,d#,g#5,d#,g#,2d#,d#,g#,d#,g#,c.7,8a#,8g#,8g,8f,8e,d#,g#,d#,g#5,d#,g#,2d#,g#.,8f,d#,c#,c,p,a#5,p,g#.5,d#,g#" public const Gadget = "Gadget:d=16,o=5,b=50:32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,32d#,32f,32f#,32g#,a#,d#6,4d6,32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,8d#" public const Smurfs = "Smurfs:d=32,o=5,b=200:4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8f#,p,8a#,p,4g#,4p,g#,p,a#,p,b,p,c6,p,4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8b,p,8f,p,4f#" public const MahnaMahna = "MahnaMahna:d=16,o=6,b=125:c#,c.,b5,8a#.5,8f.,4g#,a#,g.,4d#,8p,c#,c.,b5,8a#.5,8f.,g#.,8a#.,4g,8p,c#,c.,b5,8a#.5,8f.,4g#,f,g.,8d#.,f,g.,8d#.,f,8g,8d#.,f,8g,d#,8c,a#5,8d#.,8d#.,4d#,8d#." public const LeisureSuit = "LeisureSuit:d=16,o=6,b=56:f.5,f#.5,g.5,g#5,32a#5,f5,g#.5,a#.5,32f5,g#5,32a#5,g#5,8c#.,a#5,32c#,a5,a#.5,c#.,32a5,a#5,32c#,d#,8e,c#.,f.,f.,f.,f.,f,32e,d#,8d,a#.5,e,32f,e,32f,c#,d#.,c#" public const MissionImp = "MissionImp:d=16,o=6,b=95:32d,32d#,32d,32d#,32d,32d#,32d,32d#,32d,32d,32d#,32e,32f,32f#,32g,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,a#,g,2d,32p,a#,g,2c#,32p,a#,g,2c,a#5,8c,2p,32p,a#5,g5,2f#,32p,a#5,g5,2f,32p,a#5,g5,2e,d#,8d" public const Pacman = "Pacman:d=4,o=5,b=112:32b,32p,32b6,32p,32f#6,32p,32d#6,32p,32b6,32f#6,16p,16d#6,16p,32c6,32p,32c7,32p,32g6,32p,32e6,32p,32c7,32g6,16p,16e6,16p,32b,32p,32b6,32p,32f#6,32p,32d#6,32p,32b6,32f#6,16p,16d#6,16p,32d#6,32e6,32f6,32p,32f6,32f#6,32g6,32p,32g6,32g#6,32a6,32p,32b.6" public const OffToSeeWiz = "OffToSeeWiz:d=32,o=5,b=45:16g#.,16c#6,f#,16f,f#,g#,8c#6,g#,a#,g#,f#,f,f#,d#,8c#.,c#,16c#,c#,16c#6,c#6,c6,c6,c6,16a#,a#,d#6,d#6,d#6,16d#6,c6,8g#" public const MontyPython = "MontyPython:d=4,o=5,b=200:32p,f6,8e6,d6,8c#6,c6,8b,a#,8a,8g,8a,8a#,a,8g,2c6,8p,8c6,8a,8p,8a,8a,8g#,8a,8f6,8p,8c6,8c6,8p,8a,8a#,8p,8a#,8a#,8p,8c6,2d6,8p,8a#,8g,8p,8g,8g,8f#,8g,8e6,8p,8d6,8d6,8p,8a#,8a,8p,8a,8a,8p,8a#,2c6,8p,8c6" const SONG_DELAY = 1000 // 1000ms delay between songs main: // init tone library module tone.init() // play all the example RTTTL tunes rtttl.play(@HappyBday) delayms(SONG_DELAY) rtttl.play(@Simpsons) delayms(SONG_DELAY) rtttl.play(@IndianaJones) delayms(SONG_DELAY) rtttl.play(@TakeOnMe) delayms(SONG_DELAY) rtttl.play(@Entertainer) delayms(SONG_DELAY) rtttl.play(@Muppets) delayms(SONG_DELAY) rtttl.play(@Xfiles) delayms(SONG_DELAY) rtttl.play(@LooneyTunes) delayms(SONG_DELAY) rtttl.play(@TwentyCenFox) delayms(SONG_DELAY) rtttl.play(@Bond) delayms(SONG_DELAY) rtttl.play(@MASH) delayms(SONG_DELAY) rtttl.play(@StarWars) delayms(SONG_DELAY) rtttl.play(@ImperialMarch) delayms(SONG_DELAY) rtttl.play(@GoodBadUgly) delayms(SONG_DELAY) rtttl.play(@TopGun) delayms(SONG_DELAY) rtttl.play(@ATeam) delayms(SONG_DELAY) rtttl.play(@Flintstones) delayms(SONG_DELAY) rtttl.play(@Jeopardy) delayms(SONG_DELAY) rtttl.play(@Gadget) delayms(SONG_DELAY) rtttl.play(@Smurfs) delayms(SONG_DELAY) rtttl.play(@MahnaMahna) delayms(SONG_DELAY) rtttl.play(@LeisureSuit) delayms(SONG_DELAY) rtttl.play(@MissionImp) delayms(SONG_DELAY) rtttl.play(@Pacman) delayms(SONG_DELAY) rtttl.play(@OffToSeeWiz) delayms(SONG_DELAY) rtttl.play(@MontyPython) delayms(SONG_DELAY) // we're done tone.play(NOTE_A4, 2000) tone.wait while (true) end while end program
RTTTL example #2 - Using events
// RTTTL example with tone events to control LEDs program RTTTL_events_example device = 18F26K22 clock = 16 // int osc and IO pin libraries include "intosc.bas" #option DIGITALIO_INIT = true // automatically call setalldigital #option DIGITALIO_SLEWRATE = 1 // 1=slow (we don't need fast edges) include "setdigitalio.bas" // tone library // specify output pin #option TONE_OUTPUT_PIN = PORTA.0 // wait flag setting (default = false) #option TONE_WAIT = true include "tone.bas" // RTTTL library (uses tone library) include "rtttl.bas" // there are 8 leds... one for each note (C, D, E, F, G, A, B), and a spare #option _LED_PORT = PORTC #option _LED_PORT_TRIS = GetTris(_LED_PORT) dim LED_PORT as _LED_PORT, LED_PORT_TRIS as _LED_PORT_TRIS, LED_C as LED_PORT.0, // led 1 LED_D as LED_PORT.1, // led 2 LED_E as LED_PORT.2, // led 3 LED_F as LED_PORT.3, // led 4 LED_G as LED_PORT.4, // led 5 LED_A as LED_PORT.5, // led 6 LED_B as LED_PORT.6, // led 7 LED_8 as LED_PORT.7 // led 8 (outside RTTTL range) //------------ // tone events //------------ // tone start event - turn on leds // there are 12 notes in a scale, but there are only 8 leds // combine the notes and sharps together into a single led (ie, C or C# -> LED_C, G or G# -> LED_G, etc) // since RTTTL supports 4 scales (C4 to C7) combine all the scales into one // so that a C played in any scale turns on LED_C // for any notes outside the 4 scales covered by RTTTL it turns on LED_8 event tone_start_event() dim freq as word // get the current freq freq = tone.freq() // put all RTTTL supported notes into the same scale (scale 4) if (freq > NOTE_B6) then freq = freq >> 3 // divide by 8... scale 7 -> 4 elseif (freq > NOTE_B5) then freq = freq >> 2 // divide by 4... scale 6 -> 4 elseif (freq > NOTE_B4) then freq = freq >> 1 // divide by 2... scale 5 -> 4 endif // determine which led to turn on select (freq) case > NOTE_B4 // above B7... lite spare LED LED_8 = 1 case > NOTE_AS4 // B LED_B = 1 case > NOTE_GS4 // A and A# LED_A = 1 case > NOTE_FS4 // G and G# LED_G = 1 case > NOTE_E4 // F and F# LED_F = 1 case > NOTE_DS4 // E LED_E = 1 case > NOTE_CS4 // D and D# LED_D = 1 case > NOTE_B3 // C and C# LED_C = 1 else LED_8 = 1 // below C4/unknown... lite spare LED end select end event // tone stop event - turn off leds event tone_stop_event() LED_PORT = 0 // turn off all leds end event // some example RTTTL tunes public const IndianaJones = "IndianaJones:d=4,o=5,b=250:e,8p,8f,8g,8p,1c6,8p.,d,8p,8e,1f,p.,g,8p,8a,8b,8p,1f6,p,a,8p,8b,2c6,2d6,2e6,e,8p,8f,8g,8p,1c6,p,d6,8p,8e6,1f.6,g,8p,8g,e.6,8p,d6,8p,8g,e.6,8p,d6,8p,8g,f.6,8p,e6,8p,8d6,2c6" main: // set led pins as outputs and turn them off LED_PORT = 0 LED_PORT_TRIS = 0 // init tone library module tone.init() tone.setwait() // set wait_flag true // set tone events tone.set_events(tone_start_event, tone_stop_event) // play tune rtttl.play(@IndianaJones) while (true) end while end program