Queues a fresh buffer for consumption by the DAC
Device
Not available on the imp005
Name | Type | Description |
---|---|---|
newBuffer | Blob |
The buffer to queue
|
Nothing
Providing the fixed-frequency DAC with a buffer of fresh data to process will raise an error if the fixed-frequency DAC has not been configured. It will also raise an error if this method will cause there to be more than eight unconsumed buffers in flight. At any one time, the total number of buffers in play is the number of buffers specified in fixedfrequencydac.configure() plus the number of buffers added using fixedfrequencydac.addbuffer() minus the number of running data-consumed callbacks which have been triggered and passed non-null buffers. This total can never exceed eight.
For safety, this function should only be called after (or during) the execution of the data-consumed callback that you have already registered using fixedfrequencydac.configure().
Stream a sinusoidal wave from agent to an imp. In this example the original 16-bit signal is A-law compressed, and the resulting 8-bit data are sent to the imp.
// AGENT CODE | |
const AMPLITUDE = 0x3FFF; | |
const NUMBER_POINTS = 1024; | |
const CLIP_VALUE = 32635; | |
const INCR_X = 0.78531475; | |
local streaming = false; | |
local logTable = [ | |
1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, | |
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, | |
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, | |
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 | |
]; | |
function aLawCompress(sample) { | |
local sample = sample == -32768 ? -32767 : sample; | |
local sign = ((~sample) >> 8) & 0x80; | |
if (!sign) sample = -sample; | |
if (sample > CLIP_VALUE) sample = CLIP_VALUE; | |
local compressedValue = 0; | |
if (sample >= 256) { | |
local exponent = logTable[(sample >> 8) & 0x7F]; | |
local mantissa = (sample >> (exponent + 3)) & 0x0F; | |
compressedValue = ((exponent << 4) | mantissa); | |
} else { | |
compressedValue = sample >> 4; | |
} | |
compressedValue = compressedValue ^ (sign ^ 0x55); | |
return compressedValue; | |
} | |
function writeSineBuffer() { | |
// Generate a 1kHz sine wave data as a blob | |
local buffer = blob(); | |
local curr_x = 0; | |
for (local i = 0 ; i < NUMBER_POINTS ; i++) { | |
local a = AMPLITUDE * math.cos(curr_x); | |
curr_x += INCR_X; | |
local y = aLawCompress(a.tointeger()); | |
buffer.writen(y, 'c'); | |
} | |
return buffer; | |
} | |
// Define the DAC configuration | |
local configuration = { | |
"buffers" : [writeSineBuffer(), writeSineBuffer(), writeSineBuffer(), writeSineBuffer()], | |
"sampleRateHz" : 8000, | |
"usePin1" : true, | |
"useALAW" : true | |
} | |
// Set up our device message handlers: | |
// First, deal with requests for more audio data | |
device.on("more.data.please", function(nbuffers) { | |
if (streaming) device.send("more.data", writeSineBuffer()); | |
}); | |
// Second, continue when the device has signalled its readiness | |
device.on("device.ready", function(dummy) { | |
streaming = true; | |
// Tell the DAC to start and send its configuration | |
device.send("start.fixed.frequency.dac", configuration); | |
// Wake after 10s and tell the device to stop the DAC | |
imp.wakeup(10, function() { | |
device.send("stop.fixed.frequency.dac", true); | |
streaming = false; | |
}); | |
}); |
// DEVICE CODE | |
// Define the buffer-processing function | |
function bufferEmpty(buffer) { | |
server.log("bufferEmpty() called"); | |
if (!buffer) { | |
server.log("Warning: buffer underrun"); | |
return; | |
} | |
// Get another buffer | |
agent.send("more.data.please", 1); | |
} | |
// Set up our agent message handlers | |
agent.on("start.fixed.frequency.dac", function(configuration) { | |
server.log("Got start message with " + configuration.buffers.len() + " buffers"); | |
local options = configuration.useALAW ? A_LAW_DECOMPRESS : 0; | |
local type = ("info" in imp) ? imp.info().type : "imp001"; | |
if (type == "imp004m") { | |
// Set the configuration | |
hardware.fixedfrequencydac.configure(hardware.pwmpairKD, | |
configuration.sampleRateHz, | |
configuration.buffers, | |
bufferEmpty, | |
options); | |
} else { | |
// Set the FFDAC pin as specified | |
local pin = null; | |
if (type == "imp001" || type == "imp002") pin = configuration.usePin1 ? hardware.pin1 : hardware.pin5; | |
if (type == "imp003") pin = configuration.usePin1 ? hardware.pinA : hardware.pinC; | |
if (type == "imp006") pin = configuration.usePin1 ? hardware.pinXC : hardware.pinXD; | |
if (type == "imp005") throw "This code will not run on an imp005, which has no FFDAC"; | |
// Set the configuration | |
hardware.fixedfrequencydac.configure(pin, | |
configuration.sampleRateHz, | |
configuration.buffers, | |
bufferEmpty, | |
options); | |
} | |
// Start the DAC | |
hardware.fixedfrequencydac.start(); | |
}); | |
agent.on("stop.fixed.frequency.dac", function(dummy) { | |
// Stop the DAC | |
hardware.fixedfrequencydac.stop(); | |
server.log("Received stop message"); | |
}); | |
agent.on("more.data", function(buffer) { | |
// Add the received data buffer to the DAC | |
hardware.fixedfrequencydac.addbuffer(buffer); | |
server.log("Received more data"); | |
}); | |
// Start the process by signalling device readiness | |
agent.send("device.ready", true); |