reactor-c
C Runtime for Lingua Franca
Loading...
Searching...
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
 

Macros

#define AUDIO_DEVICE   "default"
 

Functions

void add_to_sound (int index_offset, double value)
 
int callback (snd_pcm_t *playback_handle, int16_t buf_ref[])
 
voidrun_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)
 

Variables

pthread_mutex_t lf_audio_mutex = PTHREAD_MUTEX_INITIALIZER
 
pthread_cond_t lf_audio_cond = PTHREAD_COND_INITIALIZER
 
int16_tnext_buffer = NULL
 
instant_t next_buffer_start_time = NEVER
 
snd_pcm_tplayback_handle
 
snd_async_handler_tpcm_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.

Author
Edward A. Lee
Soroush Bateni

See audio_loop.h for instructions.

Help from http://equalarea.com/paul/alsa-audio.html

Macro Definition Documentation

◆ AUDIO_DEVICE

#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.

Parameters
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.

Parameters
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.

Parameters
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.

Parameters
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

◆ lf_audio_mutex

◆ 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