Developer Guide - Events, Signals and Time(Relevant reading: generator.h) EventsThere are two kinds of event commonly used in gAlan - GDK/GTK events, dealing with the user interface, and audio-events or (commonly in this developer guide) simply events. I will not deal with GDK/GTK events here - the GTK Tutorial (combined with judicious header-file-reading) deals with that topic nicely. Audio events are mostly used for setting parameters associated with Generators - they are used to send numeric values along the edges of the vertical directed graph the user draws on the main sheet, and are also emitted by Controls when their values are changed. Audio events (from here on AEvents, to avoid confusion with GDK/GTK events) are also used to signal to interested Generators that real-time has elapsed. These two uses are reflected in the different values for AEvent.kind: AE_NUMBER for parameter-setting and general typeless communication, and AE_REALTIME for notifications of real-time events. Each AEvent has associated with it an item of variable data stored in AEvent.d. AE_NUMBER events always use AEvent.d.number, and AE_REALTIME and AE_MASTER_PLAY events always use AEvent.d.integer. Use the macro GEN_DOUBLE_TO_INT to convert AEvent.d.number to an integer. Items from generator.h useful when dealing with AEvents:
gen_init_aevent
gen_send_events
gen_post_aevent SignalsSignals are the actual audio data that is manipulated by the various generators. A signal is represented in gAlan only indirectly - as the buffer and buflen arguments to a callback function. Signals are mostly used to represent straight audio data, but they have interesting other uses as well - as signals are just a stream (at sample-resolution) of double-precision floating-point numbers, they also make an ideal time-varying control source. For instance, using a signal-to-event adaptor, you can convert a signal stream to a series of AEvents. This is useful to implement a low-frequency oscillator as a control device for some other generator, among other things. When a generator needs a buffer-full of audio data to process, it calls gen_read_realtime_input or gen_read_randomaccess_input (depending on the way the generator wants to process its input) with the buffer to fill with the input audio signal. The callback that was configured by the call to gen_new_generatorclass is called, which may either fill the buffer on its own (if it's a "sample source"), or read its own inputs in turn, processing the result before handing it back to the caller. The two kinds of signal output that a generator can produce reflect the two different access methods - random-access and realtime. Random-access can be useful in situations such as
TimeTime is dealt with in gAlan with the concept of a "master clock". Each generator in the system has the opportunity to register a clock (with gen_register_clock()) that may be selected by the user as the master clock for use in providing accurate information about the passing of time. The master clock's job is to accurately schedule calls to gen_mainloop_once(), gen_send_realtime_fns() and gen_advance_clock(). Examples of clocks registered by plugins include:
Currently the program keeps track of realtime in a global variable, gen_current_sampletime. Note that you should not access this variable directly - use gen_get_sampletime() instead. The program's idea of realtime is updated every time gen_advance_clock() is called. This is usually when an AE_REALTIME event has been sent to all the realtime-functions, in order to retrieve an audio snippet for playback. |