Skip to main content

fixedfrequencydac.addbuffer(newBuffer)

Queues a fresh buffer for consumption by the DAC

Availability

Device
Not available on the imp005

Parameters

Name Type Description
newBuffer Blob The buffer to queue

Returns

Nothing

Description

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().

Example Code

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);