86 if (res == 1 || res == 0)
return res;
97 if (res == 1 || res == 0)
return res;
117 unsigned long framesPerBuffer,
118 const PaStreamCallbackTimeInfo *timeInfo,
119 PaStreamCallbackFlags statusFlags,
123 const int16_t *rptr = (
const int16_t *)inputBuffer;
130 for (
unsigned long i = 0; i < framesPerBuffer; i++) {
131 data->
audiodata[data->
pos_w] = (inputBuffer !=
nullptr) ? *rptr++ : 0;
149 unsigned long framesPerBuffer,
150 const PaStreamCallbackTimeInfo *timeInfo,
151 PaStreamCallbackFlags statusFlags,
155 const int16_t *rptr = (
const int16_t *)inputBuffer;
163 unsigned long framesLeft = data->
len - data->
pos_w;
164 unsigned long framesToRec;
167 if (framesLeft <= framesPerBuffer) {
168 framesToRec = framesLeft;
169 finished = paComplete;
171 framesToRec = framesPerBuffer;
172 finished = paContinue;
176 for (
unsigned long i = 0; i < framesToRec; i++) {
177 *wptr++ = (inputBuffer !=
nullptr) ? *rptr++ : 0;
179 data->
pos_w += framesToRec;
190 unsigned long framesPerBuffer,
191 const PaStreamCallbackTimeInfo *timeInfo,
192 PaStreamCallbackFlags statusFlags,
196 int16_t *out = (int16_t *)outputBuffer;
202 int finished = paContinue;
203 unsigned long nout = framesPerBuffer;
206 if (data->
pos_r + framesPerBuffer >= data->
len) {
207 finished = paComplete;
212 for (
unsigned long i = 0; i < nout; i++) {
229 if (err != paNoError) {
230 fprintf(stderr,
"PortAudio Error: %s\n", Pa_GetErrorText(err));
242 if (err != paNoError) {
243 fprintf(stderr,
"PortAudio Error: %s\n", Pa_GetErrorText(err));
263 p->device = Pa_GetDefaultInputDevice();
264 if (p->device == paNoDevice) {
269 p->sampleFormat = paInt16;
270 p->suggestedLatency = Pa_GetDeviceInfo(p->device)->defaultHighInputLatency;
271 p->hostApiSpecificStreamInfo =
nullptr;
278 p->device = Pa_GetDefaultOutputDevice();
279 if (p->device == paNoDevice) {
284 p->sampleFormat = paInt16;
285 p->suggestedLatency = Pa_GetDeviceInfo(p->device)->defaultHighOutputLatency;
286 p->hostApiSpecificStreamInfo =
nullptr;
299 PaStreamParameters inputParams;
304 samprate, paFramesPerBufferUnspecified,
305 paClipOff, cb, cb_data);
306 if (err != paNoError)
return LA_ERROR;
309 if (err != paNoError)
return LA_ERROR;
315 unsigned samprate,
int rectype)
324 PaStreamParameters inputParams;
327 PaStreamCallback *cb;
338 samprate, paFramesPerBufferUnspecified,
340 if (err != paNoError)
return LA_ERROR;
345 if (err != paNoError)
return LA_ERROR;
349 if (err != paNoError)
return LA_ERROR;
363 PaStreamParameters outputParams;
368 samprate, paFramesPerBufferUnspecified,
369 paNoFlag, cb, cb_data);
370 if (err != paNoError)
return LA_ERROR;
373 if (err != paNoError)
return LA_ERROR;
387 PaStreamParameters outputParams;
392 samprate, paFramesPerBufferUnspecified,
394 if (err != paNoError)
return LA_ERROR;
397 if (err != paNoError)
return LA_ERROR;
400 if (err != paNoError)
return LA_ERROR;
411 fprintf(stream,
"PortAudio Error: %s\n", Pa_GetErrorText(
LA_LastError));
static int _ContinuousRecordCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
Callback for continuous (circular buffer) recording.
static LaError_t _setup_input_params(PaStreamParameters *p)
Configure mono 16-bit input parameters for the default device.
double LA_get_cur_play_time(void)
Get the current time (in seconds) of the playback stream.
int LA_is_playing(void)
Check if the playback stream is currently active.
static int LA_InitDone
Has PA been initialised?
static void _PlayStreamFinished(void *userData)
Called by PortAudio when a playback stream finishes.
static LA_simpleData LA_data
Shared buffer descriptor
static LaError_t _ensure_init(void)
Auto-initialise PortAudio if not already done.
static int _RecordCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
Callback for one-shot recording (fill the buffer once, then stop).
LaError_t LA_terminate(void)
Terminate the PortAudio system and release resources.
static PaError LA_LastError
Most recent PA error code.
LaError_t LA_init(void)
Initialise the PortAudio system.
static PaStream * LA_RecordStream
Active recording stream
LaError_t LA_record(void *buffer, unsigned long bufsize, unsigned samprate, int rectype)
Record audio from the default input device into a buffer.
LaError_t LA_play(const void *buffer, unsigned long bufsize, unsigned samprate)
Play audio from a buffer to the default output device.
LaError_t LA_record_callback(unsigned samprate, PaStreamCallback *cb, void *cb_data)
Record using a user-supplied PortAudio callback function.
void LA_stop_recording(void)
Stop the current recording.
LaError_t LA_play_callback(unsigned samprate, PaStreamCallback *cb, void *cb_data)
Play using a user-supplied PortAudio callback function.
static void _RecordStreamFinished(void *userData)
Called by PortAudio when a one-shot recording stream finishes.
int LA_is_recording(void)
Check if the recording stream is currently active.
static int _PlayCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
Callback for playback: reads mono samples and duplicates them to both stereo output channels (left an...
void LA_print_last_error(FILE *stream)
Print the last PortAudio error message to the given stream.
static PaStream * LA_PlayStream
Active playback stream
void LA_stop_playing(void)
Stop the current playback.
static LaError_t _setup_output_params(PaStreamParameters *p)
Configure stereo 16-bit output parameters for the default device.
double LA_get_cur_record_time(void)
Get the current time (in seconds) of the recording stream.
Live audio recording and playback via PortAudio.
int LaError_t
Return type for live audio functions.
@ LA_REC_CONT
Record continuously in a circular buffer.
@ LA_REC_ONCE
Record until the buffer is full, then stop.
@ LA_OK
Operation succeeded.
@ LA_ERROR
Something went wrong.
Simple audio buffer with read/write positions.
unsigned long pos_w
Current write position (recording).
int16_t * audiodata
Pointer to the sample buffer.
unsigned long pos_r
Current read position (playback).
unsigned long len
Total number of samples in the buffer.