![]() |
Forum Index : Microcontroller and PC projects : Micromite RTTTL player using PWM
Author | Message | ||||
Oldbitcollector![]() Senior Member ![]() Joined: 16/05/2014 Location: United StatesPosts: 172 |
I've been working on a little RTTTL player. This version isn't quite perfect, but it's fun to play with. [code] ''RTTTL Player for Micromite using PWM pin. Pin 4. ''Name and Default values have been removed from the songs. ''By Jeff Ledger ''The Simpsons SONG$ = "c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f #,8g,a#.,8c,8c6,8c6,c6" ''Entertainer 'SONG$="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,8c 6,e6,8d6,8c6,8a,2d6" ''Looney 'SONG$="32p,c6,8f6,8e6,8d6,8c6,a.,8c6,8f6,8e6,8d6,8d#6,e.6,8 e6,8e6,8c6,8d6,8c6,8e6,8c6,8d6,8a,8c6,8g,8a#,8a,8f" ''MASH 'SONG$="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" ''A-Team 'SONG$="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#" ''Smurfs 'SONG$="4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,1 6a#,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#" '' RTTTL Player for Micromite length=LEN(song$) pointer=1 PRINT song$ songplay: IF pointer > length THEN END '' Process note duration IF MID$(song$,pointer,2) = "32" THEN SETDUR 42,2 IF MID$(song$,pointer,2) = "16" THEN SETDUR 95,2 IF MID$(song$,pointer,1) = "8" THEN SETDUR 188,1 IF MID$(song$,pointer,1) = "4" THEN SETDUR 375,1 IF MID$(song$,pointer,1) = "2" THEN SETDUR 750,1 IF MID$(song$,pointer,1) = "1" THEN SETDUR 900,1 '' Process sharps IF MID$(song$,pointer,2) = "a#" THEN SETNOTE 466.08,2 IF MID$(song$,pointer,2) = "c#" THEN SETNOTE 277.18,2 IF MID$(song$,pointer,2) = "d#" THEN SETNOTE 311.13,2 IF MID$(song$,pointer,2) = "f#" THEN SETNOTE 369.13,2 IF MID$(song$,pointer,2) = "g#" THEN SETNOTE 415.30,2 '' Process notes IF MID$(song$,pointer,1) = "a" THEN SETNOTE 440,1 IF MID$(song$,pointer,1) = "b" THEN SETNOTE 493,1 IF MID$(song$,pointer,1) = "c" THEN SETNOTE 261.63,1 IF MID$(song$,pointer,1) = "d" THEN SETNOTE 293.66,1 IF MID$(song$,pointer,1) = "e" THEN SETNOTE 329.63,1 IF MID$(song$,pointer,1) = "f" THEN SETNOTE 349.23,1 IF MID$(song$,pointer,1) = "g" THEN SETNOTE 392,1 IF MID$(song$,pointer,1) = "p" THEN SETNOTE 0,1 IF MID$(song$,pointer,1) = "." THEN notedur=notedur+128 : pointer=pointer+1 ENDIF '' Process Octaves oct=4 'IF MID$(song$,pointer,1) = "4" THEN SETOCTAVE 4,1 IF MID$(song$,pointer,1) = "5" THEN SETOCTAVE 5,1 IF MID$(song$,pointer,1) = "6" THEN SETOCTAVE 6,1 IF MID$(song$,pointer,1) = "7" THEN SETOCTAVE 7,1 IF MID$(song$,pointer,1) = "," THEN play (note,oct,notedur) IF MID$(song$,pointer,1) = "." THEN pointer=pointer+1 GOTO songplay SUB play (n,o,d) IF o = 5 THEN n = n * 2 IF o = 6 THEN n = n * 4 IF o = 7 THEN n = n * 8 IF n > 0 THEN PWM 1,n,5 IF n = 0 THEN d = 5 PAUSE d PWM 1,stop pointer=pointer+1 END SUB SUB SETDUR ndur,adv notedur=ndur pointer=pointer+adv END SUB SUB SETNOTE tone,adv note=tone pointer=pointer+adv END SUB SUB SETOCTAVE o,adv oct=o pointer=pointer+adv END SUB [/code] My Propeller/Micromite mini-computer project. |
||||
Oldbitcollector![]() Senior Member ![]() Joined: 16/05/2014 Location: United StatesPosts: 172 |
Update: found a small bug, change PAUSE d to PAUSE d+25 and it'll sound better. jeff My Propeller/Micromite mini-computer project. |
||||
Oldbitcollector![]() Senior Member ![]() Joined: 16/05/2014 Location: United StatesPosts: 172 |
Found one more bug.. I think it's pretty close to right now for a quick hack. Here's an update of the entire program: [code] ''RTTTL Player for Micromite using PWM pin. Pin 4. ''Name and Default values have been removed from the songs. ''By Jeff Ledger ''The Simpsons 'SONG$ = "c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f #,8g,a#.,8c,8c6,8c6,c6" ''Entertainer SONG$="8d,8d#,8e,c6,8e,c6,8e,2c.6,8c6,8d6,8d#6,8e6,8c6,8d6,e 6,8b,d6,2c6,p,8d,8d#,8e,c6,8e,c6,8e,2c.6,8p,8a,8g,8f#,8a,8c6 ,e6,8d6,8c6,8a,2d6" ''Looney 'SONG$="32p,c6,8f6,8e6,8d6,8c6,a.,8c6,8f6,8e6,8d6,8d#6,e.6,8 e6,8e6,8c6,8d6,8c6,8e6,8c6,8d6,8a,8c6,8g,8a#,8a,8f" ''MASH 'SONG$="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" ''A-Team 'SONG$="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#" ''Smurfs 'SONG$="4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,1 6a#,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#" '' RTTTL Player for Micromite song$=song$+"," length=LEN(song$) pointer=1 PRINT song$ songplay: IF pointer > length THEN END '' Process note duration IF MID$(song$,pointer,2) = "32" THEN SETDUR 42,2 IF MID$(song$,pointer,2) = "16" THEN SETDUR 95,2 IF MID$(song$,pointer,1) = "8" THEN SETDUR 188,1 IF MID$(song$,pointer,1) = "4" THEN SETDUR 375,1 IF MID$(song$,pointer,1) = "2" THEN SETDUR 750,1 IF MID$(song$,pointer,1) = "1" THEN SETDUR 900,1 '' Process sharps IF MID$(song$,pointer,2) = "a#" THEN SETNOTE 466.08,2 IF MID$(song$,pointer,2) = "c#" THEN SETNOTE 277.18,2 IF MID$(song$,pointer,2) = "d#" THEN SETNOTE 311.13,2 IF MID$(song$,pointer,2) = "f#" THEN SETNOTE 369.13,2 IF MID$(song$,pointer,2) = "g#" THEN SETNOTE 415.30,2 '' Process notes IF MID$(song$,pointer,1) = "a" THEN SETNOTE 440,1 IF MID$(song$,pointer,1) = "b" THEN SETNOTE 493,1 IF MID$(song$,pointer,1) = "c" THEN SETNOTE 261.63,1 IF MID$(song$,pointer,1) = "d" THEN SETNOTE 293.66,1 IF MID$(song$,pointer,1) = "e" THEN SETNOTE 329.63,1 IF MID$(song$,pointer,1) = "f" THEN SETNOTE 349.23,1 IF MID$(song$,pointer,1) = "g" THEN SETNOTE 392,1 IF MID$(song$,pointer,1) = "p" THEN SETNOTE 0,1 IF MID$(song$,pointer,1) = "." THEN notedur=notedur+128 : pointer=pointer+1 ENDIF '' Process Octaves oct=4 IF MID$(song$,pointer,1) = "5" THEN SETOCTAVE 5,1 IF MID$(song$,pointer,1) = "6" THEN SETOCTAVE 6,1 IF MID$(song$,pointer,1) = "7" THEN SETOCTAVE 7,1 IF MID$(song$,pointer,1) = "," THEN play (note,oct,notedur) IF MID$(song$,pointer,1) = "." THEN pointer=pointer+1 GOTO songplay SUB play (n,o,d) IF o = 5 THEN n = n * 2 IF o = 6 THEN n = n * 4 IF o = 7 THEN n = n * 8 IF n > 0 THEN PWM 1,n,5 IF n = 0 THEN d = 5 PAUSE d +25 PWM 1,stop pointer=pointer+1 END SUB SUB SETDUR ndur,adv notedur=ndur pointer=pointer+adv END SUB SUB SETNOTE tone,adv note=tone pointer=pointer+adv END SUB SUB SETOCTAVE o,adv oct=o pointer=pointer+adv END SUB [/code] My Propeller/Micromite mini-computer project. |
||||
hitsware Guru ![]() Joined: 23/11/2012 Location: United StatesPosts: 535 |
Neato ! ![]() Today I was able to add COM1 for percussion ! Do you use any external circuitry ? I would guess not if you want it to run on a phone. I think maybe MIDI can be used though ? |
||||
Oldbitcollector![]() Senior Member ![]() Joined: 16/05/2014 Location: United StatesPosts: 172 |
I'm running it on an audio circuit that looks like this.. Then into a set PC speakers.. My Propeller/Micromite mini-computer project. |
||||
OA47 Guru ![]() Joined: 11/04/2012 Location: AustraliaPosts: 1000 |
Dropbox Screen The link without the two spaces |
||||
hitsware Guru ![]() Joined: 23/11/2012 Location: United StatesPosts: 535 |
''''''''' Serial Com Drum Selector ' Sum Com pin with PWM pin for crude percussion '''' left right arrows for coarse adjust '''''' up down arrows for fine adjust a=2: b=10 Do If KeyDown=131 Then a=a+1 If KeyDown=130 Then a=a-1 If KeyDown= 128 Then b=b+1 If KeyDown= 129 Then b=b-1 If a<1 Then a=1 If a>6 Then a=6 If b<0 Then b=0 If b>255 Then b=255 On a GoSub A,B,C,D,E,F Print#1, Chr$(b); Pause 350: Cls: Close #1 Loop A: Open"com1:300" As #1 Print " com1:300"; " chr$ =" b Return B: Open"com1:600" As #1 Print" com1:600"; " chr$ =" b Return C: Open"com1:1200" As #1 Print " com1:1200"; " chr$ =" b Return D: Open"com1:2400" As #1 Print" com1:2400"; " chr$ =" b Return E: Open"com1:4800" As #1 Print" com1:4800"; " chr$ =" b Return F: Open"com1:9600" As #1 Print" com1:9600"; " chr$ =" b Return |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2948 |
Hi Jeff, ![]() Is anyone else playing with a RTTTL player? The only thing I am not 100% sure about is the '. half-note' feature. You are simply adding 128 to the duration - but is that 100% correct? Nice demo tunes . . . . . WW |
||||
peterv Newbie ![]() Joined: 19/04/2012 Location: AustraliaPosts: 3 |
Hi Haven't posted here much but I have a project to create a kitchen timer. I saw Jeff's RTTTL code and thought that could be handy so have been playing with it. I'm going to have the kitchen timer play a random tune when the time is up..just for fun ![]() Anyway here is the program I created to help me test and develop the RTTTL part of my project. I have taken Jeff's code a bit further using a few case statements and making sure it would play a full RTTTL string. I'm not totally happy with how it plays re beats per minute but it is close enough for my purposes. If anyone has any suggestions for improvement I'm all ears. 2015-02-25_090603_MELODY2.zip |
||||
peterv Newbie ![]() Joined: 19/04/2012 Location: AustraliaPosts: 3 |
Hi I should also have answered WW's question since I've now done a fair bit of research on RTTTL. Although this thread is a bit out of date now. A dot does mean half the duration of a note is added. In Jeff's code adding 128 is about right but that is because he stayed with a standard beats per minute. However the RTTTL code allows you to specify the beats per minute and this means when a '.' is seen then whatever the duration of that particular note is there should be half a note added. Example if a note duration was 2 which stands for half of a whole note then the duration of dotted 2 is 2 + 4 because 4 stands for quarter of a whole note. If you look at the code in my melody2.bas program then the adjust_for_dotting function is where this is accounted for. HTH |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |