MusicKit application programs are written in the Objective-C language, an extension to C that adds object-oriented concepts to the language. The software kits define a number of classes, or object templates, that you can use in your own applications. The software kits currently provided by the MusicKit Project are:
The SndKit for adding sounds to your application.
The MusicKit for music composition, synthesis, and performance.
The MusicKit currently uses the MC56001 digital signal processor (the DSP) as a sound synthesizer. Objects in this kit communicates with the DSP by calling functions in the DSP system library. In addition to establishing and managing a channel of communication between your application and the DSP, the functions in the DSP system library also provide diagnostic capabilities and data conversion routines.
Work is underway to remove the requirement of specific DSP hardware to do synthesis, instead using the MPEG-4 Structured Audio language SAOL and any MPEG-4 compatible hardware, or the sfront SAOL interpreter running on the native processor. |
The MusicKit and SndKit provide a useful system for creating and manipulating sound and music. The software for this system is divided into two kits, the kit that you need depends on the demands of your application:
The SndKit lets you incorporate prerecorded sound effects into your application and provides easy access to the microphone input so you can record your own sounds. The objects in the SndKit let you examine and manipulate sound data with microscopic precision.
The MusicKit provides tools for composing, storing, and performing music. It lets you communicate with external synthesizers as well as create your own software instruments. Like the SndKit, the MusicKit provides objects that create and manipulate sounds with exquisite detail; but more important, the Music Kit helps you organize and arrange groups of sounds so you can design a performance.
Many sound recordings, stored in files on the disk (called soundfiles), are now available. Through the SndKit, you can access these files and incorporate the sounds into your application. It's also straightforward to record new sounds into a computer. With a single message to the SndKit's Snd object, you can record your own sound through a microphone. Sound playback is just as simple: Another message and the sound is played to the stereo output jacks on your computer or sound-card.
When you record a sound using the Snd object, a series of audio “snapshots” or samples is created. By storing sound as samples, you can analyze and manipulate your sound data with an almost unlimited degree of precision. The SndView class lets you see your sounds by displaying the samples in a window.
While the SndKit is designed primarily for use on sampled data, you can also use it to send instructions to the DSP. The speed of the DSP makes it an ideal sound synthesizer and, in general, DSP instructions take up much less space than sampled data. The Snd object manages the details of playing sounds for you, so you needn't be aware of whether a particular Snd contains samples or DSP instructions.
The MusicKit provides a number of ways to compose and perform music. By attaching an external synthesizer keyboard to a serial port, you can play a computer as a musical instrument. Alternatively, you can compose music to be played by the computer by creating music data in a text editor or by creating an algorithm that generates it automatically. These approaches can be combined in performance. For instance, a musician can use an external keyboard to trigger precomposed events, allowing the computer to create sounds and gestures that are impossible on a traditional instrument, but at moments specified by the performer.
The MusicKit helps you construct applications that create, organize, process, and render music data. The Objective-C language classes provided by the Kit fall into three categories:
Data representation
Synthesis
Performance
The data representation classes, illustrated in Figure 1-1, are used to encapsulate and organize music data.
MKNotes, MKParts, and MKScores form the core of music representation. Of paramount importance is the MKNote class: A MKNote object represents a musical note as a list of attributes, such as frequency, amplitude, and duration. Music applications use MKNote objects as a common currency: They're the basic package of musical information upon which the other objects act. MKPart and MKScore objects, as their names suggest, provide a means for organizing MKNote objects. The other data classes, MKEnvelope, MKWaveTable (and its progeny), and MKTuningSystem, are designed to help define MKNote object attributes:
MKEnvelopes represent time-varying functions that can be used to continuously control the values of a MKNote's attributes (such as its amplitude and frequency).
A MKWaveTable contains timbral information that's used during music synthesis on the DSP.
A MKTuningSystem is a mapping of pitch names to specific frequencies, allowing an easy representation of alternate tunings.
The MusicKit defines an ASCII file format called scorefile that represents the music data objects as editable text in files on a disk. A few C-like programming constructs, such as variables and arithmetic operators, can be used in a scorefile to help create and fine-tune music data. You can also store music data as a Standard MIDI File.
Synthesizing music is potentially the most technically involved of the three MusicKit areas. At the easiest level, you can use and manipulate the software instruments, called MKSynthPatches, that are provided by the MusicKit. A MKSynthPatch subclass corresponds, roughly, to a voice preset on a MIDI synthesizer. However, the MusicKit MKSynthPatches are generally less confined than most MIDI presets: An enormously wide variety of sounds can be produced by the MKSynthPatches supplied by the MusicKit simply by varying the attributes of the MKNotes that they receive.
At a lower lever, you can design your own MKSynthPatch subclasses by interconnecting DSP synthesis modules that the MusicKit provides as objects called MKUnitGenerators. Finally, at the lowest level, you can design MKUnitGenerators yourself by writing MC56000 assembly language macros and using the dspwrap tool to turn the macros into subclasses of MKUnitGenerator. This last level falls below the boundary of the MusicKit and is described in Programming the DSP. The principal MusicKit synthesis classes are shown in Figure 1-2.
The MKSynthInstrument class isn't strictly part of the synthesis machinery. However, it provides an easy way to allocate and control MKSynthPatch objects.
An additional class, not shown in the illustration above, is MKOrchestra. An MKOrchestra represents an entire DSP; the standard configuration includes a single DSP, thus most applications will create but a single MKOrchestra object. It's through an MKOrchestra that all synthesis resources, such as MKUnitGenerators and MKSynthPatches, are allocated.
During a MusicKit performance, MKNote objects are acquired, scheduled, and rendered (or realized). These functions are embodied by objects of the MKPerformer, MKConductor, and MKInstrument classes:
MKPerformer objects acquire MKNotes.
Through messages scheduled with a MKConductor object, a MKPerformer forwards each MKNote it acquires to one or more MKInstruments. The MKConductor thus controls the tempo of the performance.
An MKInstrument receives MKNotes that are sent to it by a MKPerformer and realizes them in some manner, typically by synthesizing them on the DSP or by sending them to an external MIDI instrument. Other types of realization include writing MKNotes to a scorefile or adding them to a MKPart.
MKPerformer and MKInstrument are abstract classes; each subclass specifies a particular means of MKNote acquisition or realization. The MusicKit provides a number of MKPerformer and MKInstrument subclasses.
Figure 1-3 shows the primary classes that are used to design a MusicKit performance.
In addition to the MKPerformer, MKConductor, and MKInstrument classes described above, five other classes are included in Figure 1-3: MKNoteSender, MKNoteReceiver, MKNoteFilter, MKSynthInstrument, and MKMidi.
MKNoteSender and MKNoteReceiver objects are part of the implementation of MKPerformer and MKInstrument: They're the ports through which MKNotes are sent by MKPerformers and received by MKInstruments.
A MKNoteFilter is a MKPerformer/MKInstrument hybrid; while it inherits from MKInstrument, it also implements MKPerformer protocol. Thus, it can receive MKNotes like an MKInstrument and then send them on to other MKInstruments, like a MKPerformer. MKNoteFilters are interposed between MKPerformers and MKInstruments and act as MKNote-processing modules.
MKSynthInstrument is a subclass of MKInstrument that causes MKNotes to be realized on the DSP.
A MKMidi object represents an external MIDI synthesizer that's attached to a computer through one of the serial ports. It can receive as well as send MIDI signals from and to the synthesizer it represents. While it inherits neither from MKPerformer nor MKInstrument, it implements their protocols and contains MKNoteSenders and MKNoteReceivers.
A number of other MKPerformer and MKInstrument subclasses are provided by the MusicKit. During a MusicKit performance, performance objects can be dynamically connected and reconnected. This allows you to mix and match MKNote sources with any means of realization. For example, the MIDI signals sent from an external MIDI synthesizer are automatically converted to MKNote objects by a MKMidi object. The MKNotes can then be sent to a MKSynthInstrument for realization on the DSP, or written to a scorefile by a MKScorefileWriter MKInstrument.
Figure 1-4 shows the components for creating, playing, and storing music and sound with the hardware and software of a typical (circa 2001) computer.