Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

ABCplayerCodea - play music in your project

edited May 2012 in Code Sharing Posts: 384

Hi All,

As foreshadowed in thread http://twolivesleft.com/Codea/Talk/discussion/102/a-song#Item_14 , here is my first version of an extensible music player for Codea/Codify. It is aimed at providing a way to add music to your projects, using the simple sound() function and an existing musical notation format called ABC. You can find the latest code link at the end of this thread.

It is very much a work in progress (so far only really plays in the key of C), and I will need your help to get it into a form that we all can use. For starters, it needs:

  1. To be turned into a class
  2. To have more notes added
  3. To implement accidentals
  4. To have more chords added
  5. To have repeats implemented
  6. Implement the rest of the ABC standard ! :)

If more control over sound() function is developed in future versions of Codea, the music will sound better and be capable of more expression.

I've tested it on one of the games and the music works fine without lagging the graphics or gameplay. There are plenty of tunes available on the web, and there are a few to try out in the code. By default it will play a little number I wrote called 'Bogg Blues', which I dedicate to the Codea team... :)

Edited: removed old link. GitHub project now at: https://github.com/fredbogg/ABCplayerCodea

Tagged:
«1

Comments

  • This is sweet. Thanks!

  • NatNat
    Posts: 143

    That's amazing!

  • BortelsBortels Mod
    Posts: 1,557

    Big grin. This is a feature I've asked for, because at the time I couldn't figure out how to implement it. Very very cool.

  • edited November 2011 Posts: 622

    I didn't want to do too much without your buy in

    Forked to https://gist.github.com/1407495


    --0.1.1
    --moved iparameter("tempo", 40, 480, 120) to setup, renamed ptempo
    --added watch("tempo") to setup
    --added ptempo = tempo to setup
    --added tempo = ptempo to draw
    --added ptempo = 230 to draw
    --this was all to show that what ptempo displays may not be what ptempo or tempo is
    --moved draw() up (to get things not to be in the class together)
    --created sampleMusic()
    --moved all sample songs to sampleMusic()
    --added sampleMusic() to setup()
    --sample music will not be in the class (music will be passed in on init)
    --a default song could be added back into the class if no music provided

    This was done to separate out some things that will not be in the class from things that are purely to demo the part that will be a class

    If you like it I'll continue.

    Trying to help now since I'll be useless later on. I know little about music (had to look up that accidentally are sharps and flats, been too long since I was thought those things)

  • Posts: 384

    Thanks guys for your feedback, I hope when it is ready we will see it provide a soundtrack to your games... :)

    Thanks Ipda41001, those look like good changes that move it towards becoming a class. He he yes, accidentals are sharps and flats, I have enough 'accidents' in the code already... :)

    Your help is appreciated, and will allow me to develop the next set of values for the sharps and flats. That involves a torturous and noisy few hours with my 'tuner app' :)

  • edited November 2011 Posts: 622


    --0.1.2
    -- initialiseMusic() >> ABCMusic:init(ABCTune,DEBUG,DUMP)
    -- createSoundTable() >> ABCMusic:createSoundTable(DEBUG)
    -- parseTune() >> ABCMusic:parseTune(destructableABCtune,DEBUG)
    -- playParsedTune() >> ABCMusic:play()
    -- dump(t,indent) >> ABCMusic:dump(t,indent)

    It's technically a class now.
    The next step would be making the variables local.

  • Posts: 384

    Thanks @Ipda41001, I've done some tuning and added more notes. I forked your code to: https://gist.github.com/1418039, not really knowing how gist/github works in terms of merging...

    -- 0.1.3
    -- Added sharps to central octave.
    -- Amended pattern to detect notes with sharps.
    -- Added escape character % to double sharp token, as ^ also means start of line like RegEx.
    -- Removed hard coded ptempo in draw() to allow adjustable tempo

  • I'm not familiar with git either. My guess is if you edit the orginal 0.1 with new code, it will hide the forks off of prior versions. Even if it doesn't I can refork from the orginal and maybe just delete my old forks as clean up.

  • Posts: 384

    Done, thanks @Ipda41001 .

  • edited December 2011 Posts: 622

    Reforked https://gist.github.com/1421256

    -- 0.1.4
    -- DEBUG to self.DEBUG, stopped passing it around
    -- soundTablePointer to self.soundTablePointer
    -- added fromTheTop() (a rewind)
    -- added demo touched function to demo fromTheTop()
    -- moved tempChord={} from init to createSoundTable() made local
    -- commented out parsedTunePointer in init, made local in createSoundTable
    -- timeElapsedSinceLastNote to self.timeElapsedSinceLastNote
    -- lastLongest made local
    -- framesToBeSkipped made local
    

    You can delete most of my comments, they're only there for your review

    The only relevant comment for this fork is there is now a "fromTheTop" (feel free to rename) function demoed with a screen touch

  • edited December 2011 Posts: 622

    I'd like to get your thoughts on some changes before I make them..

    
    Class
    
    1) Move notes table from init() to play() and make it local
    2) Move chordlist table from init() to 
    3) Make the SoundTable self (it will add alotta selfs)
    4) frame doesn't appear to be used, was that replaced by time?, remove frame?
    5) I may be wrong on this one but should duration be made self in init() and play() but local in createSoundTable()?
    6) tempDuration to self
    7) tempo to self
    8) noteLength to createSoundTable() and make local
    9) lasttoken, lastokenmatch, captureFinal1, captureFinal2, capture1, capture2 to local
    10) rawmatch, value1, value2 to local
    
    Demo
    
    1) put all ABCTunes in a table
    2) make a table of all ABCTunes parsed into ABCMusic
    3) provide a slider to change tunes
    
    
  • edited December 2011 Posts: 384

    That's great, Ipda41001 ! I've incorporated your changes for 0.1.4 at:

    https://gist.github.com/1401229

    Perhaps you could help me with a better way to loop the music rather than messing with testing the pointer like I have? Perhaps another argument that specifies the music should be looped?

    You were right about frame, it was a vestige of the past and has been purged... :)

    I really like the suggestion of putting all those demo tunes into a mega table and the slider to choose the song would be cool. Would that would best be done outside the class?

    Here are my thoughts on your next change suggestions:

    1. Would putting the notes and chordList tables in play() cause it to be re-defined every draw()?
    2. As above
    3. sounds fine
    4. yes you are right - I've removed frame as a redundant value, now that it works on time.
    5. Yes, I think you are right - let's try it out to see... :)
    6. to 10: yes, they sound like good changes.

    How about having the tune data in a separate tab, like I've seen in some of the other projects? Perhaps that'll make it easier when people want to import ABC tunes of their own. I'd certainly like to separate the music player to its own tab so it can be easily reused and called in other people's projects.

    Thanks again for your help! I'll focus on adding more of those pesky sharps and defining more chords. Then I'll need to tackle how to nicely deal with sharps and flats. Actually they are really the same thing: C# == Db, but as we are using string matching for the notes only the sharps are going to work at the moment.

  • You may be right about the notes() and chordlist()

    I attempted to make some updates but they did not go well.

    Cut/paste everything below class to a new tab and Possibly post on posterous

    I'm going to have to reattempt on another day. I started with the megatable and should probally restart with the class instead.

  • Posts: 384

    I also failed with the megatable... !

    I've separated it into different tabs to make it easier to tack on to other projects.

    Posted at: http://fredbogg.posterous.com/abcplayercodea-v015

  • I'm going to take another day or so before I attempt to make another run at it #-O

  • Posts: 384

    Version 0.1.6 is on Posterous. It adds some more sharps, support for some more key signatures.

    http://fredbogg.posterous.com/abcplayercodea-v016

  • Nice default song.

    Sorry I haven't gotten back to this. When Codea first came out things were slow at work. Now they're making me think and work. I've been limiting myself to those one line of code plus a couple of cute phrases kid tutorials.

    Anyway I think a core thing that needs handled is tempo. Tempo is set by default by reading a song, but it's also set from the main. Maybe having a dtempo (default) and ctempo (current) would better isolate those two traits.

  • Posts: 384

    Thanks @Ipda41001 ! Likewise things have been slow going for me on this project, but have done a little more. It's almost ready to publish, and plays a nice version of 'Still Alive'. The parsing is very fiddly, and I will need to neaten up the new work I did.

    On tempo, I guess in the end I thought the sliding tempo setter wouldn't be necessary, as the song data sets it.

  • SimeonSimeon Admin Mod
    Posts: 4,958

    @Fred if we were to change the default random number generator in the future, would it mess up your project? We probably won't because there are no complaints, but it will be good for us to keep in mind.

  • I think if you implemented access to the notes directly before the rand num change then he would switch to direct access.

  • SimeonSimeon Admin Mod
    Posts: 4,958

    Good point. That scenario is more likely, too.

  • Posts: 384

    10 points for @Ipda41001 ! :) Yes, if you implement direct pitch control of the sound, e.g. in Hertz, I would convert it in an instant. That would make the music sound much better, as the current random seed method is only approximate.

  • Posts: 384

    New version at http://fredbogg.posterous.com/abcplayercodea-v017
    Plays 'Still Alive' by Jonathan Coulton from the Portal soundtrack, arranged by Meldowen of Silverlode from http://www.TheFatLute.com


    -- 0.1.7
    -- Added flats
    -- Implemented key signatures
    -- Improved parsing of rendered MIDI files

  • SimeonSimeon Admin Mod
    Posts: 4,958

    Fred: I can't believe you included the third movement of Moonlight Sonata. Still Alive sounds great too.

    It's like you "tuned" Codea through its random number generator. We'll have to get proper sound effect control implemented for you.

  • Posts: 384

    Heh heh, Beethoven would roll in his grave if he heard the tuning... :) But yes, if we could specify the frequency of the tones that would fix a few dud notes in there!

  • Posts: 622

    Where does one find music in the right format? I found this but it doesn't seem all that close.

    http://abcnotation.com/tunePage?a=www.thesession.org/tunes/display/8426.no-ext/0000

  • Posts: 384

    Hi @Ipda41001, yes this is the right format and it should play, barring bugs. I tried this song before but it didn't sound very good due to the current tuning. Another site I have found useful is www.thefatlute.com.

    I'll post another update tonight that fixes some bugs.

  • edited January 2012 Posts: 384

    For those who haven't upgraded yet: http://fredbogg.posterous.com/abcplayercodea-v019-89980

    P.S. @Ipda41001, fixed a bug that prevented that last tune from playing. It's in this version.

  • Posts: 2,161

    Can you post the flat files somewhere for those of us who have upgraded?

  • BortelsBortels Mod
    Posts: 1,557

    I will post my .codea exploder, or a web utility that does the same, later today, so people who have a .codea file and can't import it directly aren't stuck.

  • Posts: 384

    Here you go, @Andrew_Stacey:

    Main: https://gist.github.com/1560744
    ABCMusicData: https://gist.github.com/1560736
    ABCMusic: https://gist.github.com/1560732

    @Bortels, bring on the wizardry, I don't know how long I can last with the copy and paste method! :)

  • Posts: 384

    New version that takes advantage of new sound() API : http://fredbogg.posterous.com/abcplayercodea-v021

    Separate link to follow for individual tabs...

  • SimeonSimeon Admin Mod
    Posts: 4,958

    Wow Fred. It sounds incredible now that you have full control over SFXR.

  • SimeonSimeon Admin Mod
    Posts: 4,958

    Your Fawlty Towers track makes me want to make a Tiny Tower style game where you slap the guests and force them to leave.

  • Posts: 384

    Heh, thanks @Simeon!

    I'm only using StartFrequency and SustainTime here, there is a lot more we can do to shape the sounds into different instrument sounds.

    The old way was like playing a honky tonk piano held together with string and sticky tape. :)

    I'll release some more tools soon to assist people get the ABC file ready for Codea. Basically a few find and replaces that have to be done.

  • Posts: 384

    Ha ha @Simeon... "Basil!"

    Also will post some links soon to a good MIDI to ABC converter.

  • Posts: 2,820

    Speaking about MIDI, slightly different subject, there isn't a way to get a MIDI keyboard input, is there? By the way, it's awesome.
    Thanks!

  • Posts: 384

    Thanks! Here's a bug fix to get the pitches in concert pitch. https://gist.github.com/1686322 is an update of the ABCMusic class.

  • It's really really good !!!!!
    I have write a part of a music from stanley myers :

    Cavatina = 
         'X:1\n'
        ..'T:Cavatina\n'
        ..'C:Stanley Myers\n'
        ..'Q:60\n'
        ..'M:3/4\n'
        ..'L:1/8\n'
        ..'K:E major\n'
        ..'[E2b]BegeB | [D2b]BdgdB | [C2a/2] b/2 [Ac\'2] cecA | F,AcecA | '
        ..'[B,2a/2] b/2 [Ac\'2] cecA | B,FAdA [Fb/2] a/2 | [E,b2]DGBGD | E,B =d g =d [Ba/2] g/2 |'
        ..'[A,g] cegec | [=Df]Acfc[AA/2] e/2 | [=G,f]B=df=dB | [=Ce]=GBeB=G | [F,e]AcecA |'
        ..' B,E[Af]c[Ad]F | [E,4Ae4]FGFGB | e4'

    But if you look a good Midi to abc converter, it's better :)

  • Posts: 384

    Hi Hyro, that's a nice tune! You know I really liked your game that you posted recently, do you plan to add some music?

    I'm still working on improvements to the program, which should be ready for another update soon.

    I've been using a MIDI to ABC converter called MidiZyx2abc, which you learn more about at:

    http://www.midicond.de/Freeware/MidiZyx2abc_EnglishManual.html

  • Thanks ! And yes, I will create and add music in my game :-D
    And thanks again for MidiZyx2abc !

  • Posts: 384

    New version copied and pasted in one page on github:

    https://gist.github.com/1971776

    .codea file on Posterous:

    http://fredbogg.posterous.com/abcplayercodea-v04

    This version (still lots of work to do!) adds caching support to ensure your sounds are buffered for lag-free animation.

  • Posts: 2,820

    Cool! Thanks.

  • Posts: 384

    In case anyone is using MidiZyx2abc to make ABC files from MIDI files, you might want to use these regular expressions to prepare the file for pasting in to Codea as a variable...

    I've been using a web-based RegEx thing at http://gskinner.com/RegExr/

    This one adds the escape character \ in front of the apostrophes that denote higher octaves:

    Pattern: /([a-g'])'/gxsm

    Replace: $1\'

    If you care about how long the lines get, use this to 'word wrap', it puts a newline character after every 40 - 80 characters, depending on chord endings and bar lines:

    Pattern: /([.{40,80}?]\s?|?\s?)/gxm

    Replace: $1\n

    Then use this one, it adds ..' to start and \n' to end of a line:

    Pattern: /^[^..\'](.*?[^\'])[^\n']$/gxsm

    Replace: ..'$&\n'

  • Posts: 384

    New version with experimental sound changer and better note sustain.

    https://gist.github.com/2782181

    or for beta users: http://fredbogg.posterous.com/abcplayercodea-v043-71112

    Thanks to @MdMbunny, @Codeslinger and @KMEB I have incorporated some improvements, but still a long way to go... ! Next plan is to implement multi voicing as per the ABC standard.

  • Posts: 141

    @Fred have you considered creating a traditional GitHub project for this? That way I could just directly fork it or do a clone

  • Posts: 384

    Hi @JockM, I looked into it briefly and settled on gist as a lightweight alternative. If it would encourage collaboration I could be convinced to move to a project. If you've looked at the code you will know I'm not a software engineer... :) so I would benefit from some help. Some questions:

    Can I manage it from the iPad?
    Will it make it easier to incorporate changes?
    Is it much more overhead?

    Over the last few evenings I have been working on restructuring the class, reducing global namespace pollution (thanks!), and adding multivoicing and different instrument sounds. I will look in to GitHub again and perhaps start my next version there.

  • Posts: 141

    Well if you make it a full GitHub project you can have an issue tracker, and a wiki for documentation. People can also watch the project and be notified if there are changes.

    Its also a bit handier for people who are using the Codea Run Time producing something for the App Store.

  • Posts: 384

    Ok folks, @JockM has convinced me to manage it as a GitHub project, so from now on I will be updating it at: https://github.com/fredbogg/ABCplayerCodea

    I found that, in conjunction with iExplorer, it is fairly easy to upload and download the project files this way.

Sign In or Register to comment.