C Runtime for Lingua Franca
No Matches
audio_loop_linux.c File Reference

Utility function for playing audio on Linux. More...

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <pthread.h>
#include "audio_loop.h"
#include <unistd.h>
#include <poll.h>
#include <alsa/asoundlib.h>
#include <stdbool.h>

Data Structures

struct  note


#define AUDIO_DEVICE   "default"


void add_to_sound (int index_offset, double value)
int callback (snd_pcm_t *playback_handle, int16_t buf_ref[])
void * run_audio_loop (void *ignored)
void lf_start_audio_loop (instant_t start_time)
void lf_stop_audio_loop ()
int lf_play_audio_waveform (lf_waveform_t *waveform, float emphasis, instant_t start_time)


pthread_mutex_t lf_audio_mutex = PTHREAD_MUTEX_INITIALIZER
pthread_cond_t lf_audio_cond = PTHREAD_COND_INITIALIZER
int16_t * next_buffer = NULL
instant_t next_buffer_start_time = NEVER
snd_pcm_t * playback_handle
snd_async_handler_t * pcm_callback
struct note notes [NUM_NOTES] = {0}
int note_counter = 0
bool stop_audio = false
pthread_t loop_thread_id
bool loop_thread_started = false

Detailed Description

Utility function for playing audio on Linux.

Edward A. Lee
Soroush Bateni

See audio_loop.h for instructions.

Help from

Macro Definition Documentation


#define AUDIO_DEVICE   "default"

Function Documentation

◆ add_to_sound()

void add_to_sound ( int index_offset,
double value )

Add the given value to the current write buffer at the specified index. If the resulting value is larger than what can be represented in the 16-bit short, truncate it.

indexWhere in the buffer to add the amplitude.
valueThe amplitude to add to whatever amplitude is already there.

◆ callback()

int callback ( snd_pcm_t * playback_handle,
int16_t buf_ref[] )

Function that is called by the audio loop to fill the audio buffer with the next batch of audio data. When this callback occurs, this grabs the mutex lock, copies the buffer that the main program has been filling into the destination buffer, clears the next buffer, and updates the start time of the next buffer.

playback_handleHandle for the audio interface
buffer_refReference to the buffer of size AUDIO_BUFFER_SIZE to be copied to the hardware

◆ lf_play_audio_waveform()

int lf_play_audio_waveform ( lf_waveform_t * waveform,
float emphasis,
instant_t start_time )

Play the specified waveform with the specified emphasis at the specified time. If the waveform is null, play a simple tick (an impulse). If the waveform has length zero or volume 0, play nothing.

If the time is too far in the future (beyond the window of the current audio write buffer), then block until the audio output catches up. If the audio playback has already passed the specified point, then play the waveform as soon as possible and return 1. Otherwise, return 0.

waveformThe waveform to play or NULL to just play a tick.
emphasisThe emphasis (0.0 for silence, 1.0 for waveform volume).
start_timeThe time to start playing the waveform.

◆ lf_start_audio_loop()

void lf_start_audio_loop ( instant_t start_time)

Start an audio loop thread that becomes ready to receive audio amplitude samples via add_to_sound(). If there is already an audio loop running, then do nothing.

start_timeThe logical time that aligns with the first audio buffer.

◆ lf_stop_audio_loop()

void lf_stop_audio_loop ( )

Stop the audio loop thread.

◆ run_audio_loop()

void * run_audio_loop ( void * ignored)

Run the audio loop indefinitely.

Variable Documentation

◆ lf_audio_cond

pthread_cond_t lf_audio_cond = PTHREAD_COND_INITIALIZER

◆ lf_audio_mutex

pthread_mutex_t lf_audio_mutex = PTHREAD_MUTEX_INITIALIZER

◆ loop_thread_id

pthread_t loop_thread_id

◆ loop_thread_started

bool loop_thread_started = false

◆ next_buffer

int16_t* next_buffer = NULL

◆ next_buffer_start_time

instant_t next_buffer_start_time = NEVER

◆ note_counter

int note_counter = 0

◆ notes

struct note notes[NUM_NOTES] = {0}

◆ pcm_callback

snd_async_handler_t* pcm_callback

◆ playback_handle

snd_pcm_t* playback_handle

◆ stop_audio

bool stop_audio = false