|
About Andrew Choi
MIDI Programs
MIDI File Player (External Device)
MIDI Destination Pop-Up Button
Other Programs Cocoa Sample Programs Syntax Coloring Using Flex Algorithms Jazz Chord Analysis as Optimization
|
A blog where I will write mostly about programming in Cocoa and CoreMIDI, and experiences from my ports of Emacs and XEmacs to the Mac OS.
Id like to put Play and Stop buttons at the top of each document window so the user can easily play the generated accompaniment. Ill also need a measure and beat counter somewhere. It turns out, after studying a number of Apple applications and reading the Human Interface Guide, that these are probably best implemented as items in a toolbar. So I wrote a little sample program to see how this may work.
NSToolbar is to read the Cocoa documentation and study the sample code /Developer/Examples/AppKit/SimpleToolbar. A tutorial at the OReilly website helps too. The icons in the sample program comes from the Scotland Software website. I resized and edited them in Gimp. Anyway Ill design and create my own icons for use in my final products. For now I can apparently include these icons in the sample code if I acknowledge their creators.
It took a little more programming to get the code for highlighting the current measure during playback of the generated accompaniment sequences to work correctly. One needs to call the
I wrote some code to highlight the current measure as my program plays back the generated accompaniment. Didnt want too many objects prancing across the window. So I settled on just highlighting the current measure. Performance will also be a problem if the GUI needs to be updated too frequently. DrawRect will then need to be re-coded to make use of the update rectangle. Anyway Ill add ticking repeat, measure, and beat counters somewhere. Oh, the view also scrolls automatically when playback reaches the bottom of the window.
I spent a little time today studying how different MIDI programs provide visual feedback when sequences are being played. Band in a Box highlights the bar being played in reversed video. It switches to another page of the chord chart when playback reaches the bottom of the view.
Im back writing programs again. The vacation lasted longer than planned. I visited my aunts and uncles in San Francisco in June. Then my sisters and my cousins families came to see me here in Calgary. There were a lot of sightseeing, shopping, barbecues, and Chinese food. Everyone had a wonderful time. Heres a flock of big-horn sheep we ran into at the top of Sulphur Mountain in Banff. Neat, huh?
So this blog is mostly just my personal log. Im not trying to sell anyone anything, promote any isms, voice my opinions, etc. Youve got the rest of the Internet for that kind of content :-)! My only real job had been in teaching so if you accidentally learn something from my sample programs, I wouldnt mind very much :-). I also love designing and writing programs so if I can spread some of this excitement around, that would be very nice too! Probably because of my Emacs port, people think I advocate free software. And I sometimes receive requests for source code for my programs and libraries Ive described in the blog. To explain my thoughts on software (free or otherwise) will take quite a bit of time. Suffice it to say I ported Emacs to the Mac just for the fun of it! In any case Ive been developing the MIDI programs as commercial products and plan on selling them. So the source code Ive posted and will be posting is already what Im happy with giving away. Note that all the sample code is released under the Perl Artistic License and not the GPL. This is the tiny political statement that Im making, for those who understand software licenses. Enough of that. Lets talk about programming. I posted this tiny MIDI file player that demonstrates the use of MusicPlayer and MusicSequence to play MIDI files. In a real MIDI program, however, we need visual feedback when the sequence is being played: a ticking counter, a moving wiper cursor, whatever. How should we structure such a program? At first glance this seems to be a very simple problem. Create a recurring timer and update the counter or cursor when it fires. But when we consider the following questions, the problem becomes a bit more involved.
NSTimer that fires at the time of the next beat. It handles tempo changes correctly by obtaining the time of the next beat by calling MusicPlayerGetHostTimeForBeats. If the firing of the timer runs behind (this can be demonstrated by resizing the document window), the program catches up by skipping the missed beats. In addition to a beat count callback function, the design also provides a callback function that is invoked when the sequence finishes playing.The coding is also made a little more difficult by a bug (arbitrarily imposed restriction?) in MusicPlayerGetHostTimeForBeats and the need to properly cancel and dispose of pending timers under all circumstances. Anyway the code is there for all to scrutinize.
|
Lists
Less-Known Facts About Emacs
Chinese Restaurants in Calgary
Calgary/Banff Tourist Attractions
Top-10 Reason I Stopped Working on Emacs
Misc
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Copyright © 2003, 2004, 2005 Andrew Choi (Contact Information). | Created with FCBlog |