HulaLoop
Simple cross-platform audio loopback and recording.
Quick Start

A quick start for getting HulaLoop'd audio into your application.

Incorporating HulaLoop into your application should be simple and easy.

To understand the simplest way to get started with HulaLoop, we'll break down the following example. See the Building HulaLoop page for help building and linking the library.

Example

#include <thread>
int main()
{
// Create the controller object
Controller c;
// Set the active input device
std::vector<Device *> devices = c.getDevices(LOOPBACK);
if (devices.size() > 0)
{
// This calls the copy constructor on the selected device
c.setActiveInputDevice(devices[0]);
}
// Delete the devices
Device::deleteDevices(devices);
// Add a buffer to start receiving data
HL_RingBuffer * rb = c.createAndAddBuffer();
std::thread t = std::thread(&listen, rb);
t.join();
// Remove and delete the buffer
c.removeBuffer(rb);
delete rb;
}
void listen(HulaRingBuffer *rb)
{
int maxSize = 256;
float *temp = new float[maxSize];
// Read 100 temp buffers
for (int i = 0; i < 100; i++)
{
size_t bytesRead = rb->read(temp, maxSize);
printf("Read %d bytes.@n", bytesRead);
}
delete [] temp;
}

Create an instance of Controller. This is the main component in in the audio backend.

Controller c;

Fetch the device list, set the active device, and delete the allocated the devices.

// Set the active input device
std::vector<Device *> devices = c.getDevices(LOOPBACK);
if (devices.size() > 0)
{
// This calls the copy constructor on the selected device
c.setActiveInputDevice(devices[0]);
}
// Delete the devices
Device::deleteDevices(devices);

Create a ring buffer and add it to the list of buffers that should receive audio data.

HulaRingBuffer *rb = c.createAndAddBuffer();

Since the loop (typically infinite), will block until the application terminates, start a thread with the "listen" routine.

std::thread t = std::thread(&listen, rb);

Create a function that handles reading the ring buffer and processing the data.

void listen(HulaRingBuffer *rb);

A local buffer that data will be read into.

int maxSize = 256;
float *temp = new float[maxSize];

This loop would typically be infinite or rely on some flag to signal that capture should stop. For this example, we read a finite number of buffers as a proof of concept.

for (int i = 0; i < 100; i++)

Read data from the ring buffer into our local buffer.

size_t bytesRead = rb->read(temp, maxSize);
printf("Read %d bytes.@n", bytesRead);

Clean up our local buffer.

delete [] temp;