Audio In
Impromptu can only connect to a single audio device per session - the default output device as specified in your system preferences. Impromptu automatically creates an output unit for you *au:output-node* that connects to the output of the device. Impromptu also attempts to create an input unit for you *au:input-node* if the device supports input. The *au:output-node* has a single input bus 0. The *au:input-node* has a single output bus 1. So, in short, if your output device supports input as well as output Impromptu will create an *au:input-node* for you on startup. NOTE: Setting the default input device in system preferences will have NO effect on Impromptu (which completely ignores the request).
Now, if you happen to have input and output on separate audio devices there is a way to trick Impromptu into working. We can use the Audio MIDI Setup utility to construct a single virtual device made up from multiple physical devices. CoreAudio will treat this virtual device as a single device, allowing us to select the virtual device as the default output and thereby trick Impromptu into running with the input and output we would like to use. Intel laptops, for example, have separate physical audio devices for line output and mic input, so we will use that as our example.
First, open up the Audio MIDI Setup application in your Application/Utilities folder. Then select Open Aggregate Device Editor from the Audio menu.
Add a new aggregate device (i.e. virtual device) and select the input and output devices you wish to use.
Name your virtual device, then select done and your done. Make sure you select the MyVirtualDevice as your default output device from the system preferences.
Now when you restart Impromptu the MyVirtualDevice provides both input and output.
You can use the *au:input-node* just as you would use any other aumu or augn AudioUnit. Here's the simplest example, sending the input single straight to the output.
(au:connect-node *au:input-node* 1 *au:output-node* 0)
(au:update-graph)
Let's disconnect the input from the output and add a filter between the two.
(au:disconnect-node *au:output-node* 0)
(define filter (au:make-node "aufx" "filt" "appl"))
(au:connect-node *au:input-node* 1 filter 0)
(au:connect-node filter 0 *au:output-node* 0)
(au:update-graph)
(au:open-view filter)
You should now be able to mess with the input signal by adjusting the filters parameters.
3D Sound
This panel also presents you with a number of 3D options.
Stereo Panning provides a simple stereo panning option. The Head Related Transfer Function attempts to emulate a 3D space in headphones or stereo speakers. Sound field renders to multi-channel output providing a weighting towards the location in which sound derives. Vector based also renders to multi-channel output but provides a 100% weighting to the location in which the sound derives.
If you select either Sound Field or Vector Based you will also need to configure your speaker setup in the Audio MIDI Setup utility. Currently only Quadraphonic setups have been tested (although 5.1 should also work).
Remember that you will need to restart Impromptu before any changes made to either Impromptu preferences or the Audio MIDI Setup will take effect. Change the order of speakers around to suite your setup.
Whenever you start Impromptu with the 3D Mixer setting selected the *au:output-node* becomes Apples 3D Mixer (the *au:output-node* is then connected to the actual output node). This means that you can control the *au:output-node* exactly as you would the aumx 3dmx appl AudioUnit (i.e. the 3d mixer), including it's multiple input buses. Let's take a look at an example.
(define dls1 (au:make-node "aumu" "dls " "appl"))
(define dls2 (au:make-node "aumu" "dls " "appl"))
(au:connect-node dls1 0 *au:output-node* 0)
(au:connect-node dls2 0 *au:output-node* 1)
(au:update-graph)
First of all we setup two dls instruments. Note that we can now connect both dls's directly to the *au:output-node* on input bus 0 and 1 because the *au:output-node* is now the 3d mixer AudioUnit. Next we will send program change messages to the two dls instruments so we can have two distinct timbres.
The two dls's should now play with a spatial location of 0 degrees.
(au:midi-out (now) dls1 *io:midi-pc* 0 35 0)
(au:midi-out (now) dls2 *io:midi-pc* 0 45 0)
OK. Let's print out the parameters available for the 3d mixer (*au:output-node*).
(au:print-params *au:output-node* *au:input-scope*)
0 "azimuth"
1 "elevation"
2 "distance"
3 "gain"
Remember when setting the 3D mixers parameters that it is the *au:input-scope* parameters that we are changing. OK, let's set the azimuth parameter. This parameters takes a value between -180 and 180 degrees (where -90 is pan left and 90 is pan right if you are using a stereo field or a standard quad speaker setup). Let's set input bus 1 (i.e. the second dls's input into the mixer) azimuth value to -180. This should result in dls1 sounding directly in front and dls2 sounding directly to the rear.
(au:set-param (now) *au:output-node* 0 *au:input-scope* 1 -180)
Try playing the two dls's again. Just to finish off this short tutorial let's setup two constantly contrary revolving signals. First of all we will create a loop playing notes on two dls's, then a function to constantly move the azimuth of both dls's in contrary motion.
(define loop
(lambda (time)
(play-note time dls2 (random '(36 48 60 63)) (random 30 80) 1000)
(play-note time dls1 (random '(72 77 74 79)) (random 30 80) 1000)
(callback (+ time 1000) 'loop (+ time 2000))))
(loop (now))
(define azimuth-loop
(lambda (degrees)
(let* ((pos (fmod degrees 360))
(ldegrees (if (> pos 180) (- pos 360) pos)))
(au:set-param (now) *au:output-node* 0 *au:input-scope* 0 ldegrees)
(au:set-param (now) *au:output-node* 0 *au:input-scope* 1 (* -1 ldegrees))
(callback (+ (now) 1000) 'azimuth-loop (+ degrees 1)))))
(azimuth-loop 0)
Change the increment of degrees to create some interesting phasing effects.
Recording
You can record directly to aiff or m4a file. It's a simple as starting the recording and then stopping the recording when you're finished. you can start recording to disk by calling start-audio-capture. The files extension defines whether an aif or m4a file is created.
(start-audio-capture "/tmp/test.aif" 2)
This will record two channels to the file /tmp/test.aif. You can specify more than 2 channels if your device supports more than 2 channels (and you have selected to save as aif. m4a does not support more than 2 channels). To stop the recording call the function stop-audio-capture.
(stop-audio-capture)
If your find you are getting audio dropouts during the recording try increasing the audio frames per cycle in Impromptu's preferences (yes you will need to restart for the change to take effect). This will increase your latency but will give Impromptu more time to complete the required disk-IO.