1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
class:: Recorder
summary:: Write Audio to Harddisk
categories:: Server>Abstractions
related:: Classes/Server, Classes/DiskOut, Guides/Non-Realtime-Synthesis
description:: A Recorder allows you to write audio to harddisk, reading from a given bus and a certain number of channels, relative to a given node. A link::Classes/Server:: has one instance, which is accessible also through the link::Classes/ScIDE::. You can use the server directly to record its output
code::
(
{ SinOsc.ar(
SinOsc.ar(
XLine.kr(1, 100, 5)).exprange(*XLine.kr([20, 800], [7000, 200], 10)
)
) * 0.1
}.play;
s.record(duration: 10);
)
::
This functionality is also available through the recording button on the server windows.
Pressing it once calls record, and pressing it again calls stopRecording (see below). When doing so the file created will be in your recordings folder and be named for the current date and time.
The default location of the recordings folder varies from platform to platform. Setting this variable allows you to change the default.
code::
// find where the recordings are written to
thisProcess.platform.recordingsDir
::
NOTE::
By default, record creates the recording synth after the Server's default group and uses In.ar. Thus if you add nodes after the recording synth their output will not be captured.
To avoid this, either use Node objects (which use the default node as their target) or (when using messaging style) use a target nodeID of 1.
code::
s.sendMsg("/s_new", "default", s.nextNodeID, 1, 1);
::
::
For more detail on this subject see link::Guides/Order-of-execution::, link::Reference/default_group::, and link::Guides/NodeMessaging::.
See link::Classes/SoundFile:: for information on the various sample and header formats.
Not all sample and header formats are compatible. Note that the sampling rate of the output file will be the same as that of the server app. This can be set using the Server's link::Classes/ServerOptions::.
ClassMethods::
method::new
Create a new instance for a given server.
argument::server
InstanceMethods::
method:: prepareForRecord
Allocates the necessary buffer, etc. for recording the server's output. (See code::record:: below.)
argument:: path
a link::Classes/String:: representing the path and name of the output file. If the directory does not exist, it will be created for you. (Note, however, that if this fails for any reason, recording will also fail.)
argument::numChannels
The number of output channels to record.
discussion::
If you do not specify a path than a file will be created in your recordings folder (see the note above on this) called code::SC_thisDateAndTime::. Changes to the header or sample format, or to the number of channels must be made strong::before:: calling this.
method:: record
Starts or resumes recording the output.
argument:: path
this is optional, and is passed to code::prepareForRecord:: (above).
argument:: bus
The bus (link::Classes/Bus:: object or integer bus index), the offset at which to start to count the number of channels. You can record any adjacent number of bus channels.
argument:: numChannels
The number of output channels to record.
argument:: node
The link::Classes/Node:: to record immediately after. By default, this is the default group 1.
argument:: duration
If set, this limits recording to a given time in seconds.
note::The recording starts when the buffer has been allocated, and after the usually very short network latency. It will last for the code::duration:: exactly down to one server block size (64 samples). For scheduling the starting point of a recording precisely, call link::#-prepareForRecord:: first, and then call link::#-record:: a bundle (see link::Classes/Server#-bind:: and link::Classes/Server#-sync::).::
discussion::
If you have not called prepareForRecord first (see above) then it will be invoked for you (but that adds a slight delay before recording starts for real).
code::
r = Recorder(s);
{ GVerb.ar(Dust.ar(4)) }.play; // play on bus 64
r.record(numChannels:2);
r.stopRecording;
::
method:: pauseRecording
Pauses recording. Can be resumed by executing record again, or by calling resumeRecording.
method:: resumeRecording
Start recording again.
method:: stopRecording
Stops recording, closes the file, and frees the associated resources.
discussion::
You must call this when finished recording or the output file will be unusable. Cmd-. while recording has the same effect.
method::filePrefix
a string used as prefix for the path when recording. This can be used to separate the outputs of several recorders. The default is code::"SC_"::.
method::numChannels
a number of sound file channels that is used always when using this recorder, unless a different one is specified in the link::#-record:: method. When not set, we use link::Classes/Server#-recChannels::.
method:: recHeaderFormat
Get/set the header format (string) of the output file. The default is "wav". Must be called strong::before:: prepareForRecord.
method:: recSampleFormat
Get/set the sample format (string) of the output file. The default is "float". Must be called strong::before:: prepareForRecord.
method::recBufSize
Get/set the size of the link::Classes/Buffer:: to use with the link::Classes/DiskOut:: UGen. This must be a power of two. The default is the code::sampleRate.nextPowerOfTwo:: or the first power of two number of samples longer than one second. Must be called strong::before:: prepareForRecord.
method::isRecording
returns true if we are in the process of recording
method::paused
returns true if recording is paused
method::duration
returns the number of seconds we have been recording so far
method::path
returns the path of the current recording
method::numFrames
returns the number of frames of the recording buffer
method::notifyServer
if set to true, it will send code::changed:: notifications to the server instance. This is used internally by the link::Classes/Server:: class.
method::server
server to record from
private::cmdPeriod
private::prRecord
private::prStopRecord
private::makePath
private::changedServer
section::Examples
code::
// something to record
(
SynthDef("bubbles", { |out|
var f, sound;
f = LFSaw.kr(0.4, 0, 24, LFSaw.kr([8, 7.23], 0, 3, 80)).midicps; // glissando function
sound = CombN.ar(SinOsc.ar(f, 0, 0.04), 0.2, 0.2, 4); // echoing sine wave
Out.ar(out, sound);
}).add;
SynthDef("tpulse", { |out = 0, freq = 700, sawFreq = 440.0|
Out.ar(out, SyncSaw.ar(freq, sawFreq, 0.1))
}).add;
)
x = Synth.new("bubbles");
s.prepareForRecord; // if you want to start recording on a precise moment in time, you have to call this first.
s.record; // start recording. This can also be called directly, if it isn't imprtant when precisely you need to start.
s.pauseRecording; // pausable
s.record // start again
s.stopRecording; // this closes the file and deallocates the buffer recording node, etc.
x.free; // stop the synths
// look in your recordings folder and you'll find a file named for this date and time
::
code::
// set location to your home folder (change user with your username)
thisProcess.platform.recordingsDir = "/home/user/";
// instantiate the Recorder
r = Recorder.new(s);
// record into a flac file
r.recHeaderFormat = "flac";
// default 'float' is incompatible with flac. set to 24bit:
r.recSampleFormat = "int24";
// set very obvious prefix for files
r.filePrefix = "SuperCollider_";
// start recording:
r.record;
// stop recording
r.stopRecording;
::
|