ABCplayerCodea - play music in your project

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 ! :slight_smile:

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… :slight_smile:

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

This is sweet. Thanks!

That’s amazing!

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.

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)

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

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… :slight_smile:

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’ :slight_smile:

--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.

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.

Done, thanks @Ipda41001 .

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

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


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… :slight_smile:

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… :slight_smile:
  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.

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

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.

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.

@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.