Skip to content

Commit

Permalink
portaudio realtime playback works
Browse files Browse the repository at this point in the history
  • Loading branch information
Ramesh authored and Ramesh committed Nov 29, 2021
1 parent a48e7de commit c49a216
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 37 deletions.
2 changes: 0 additions & 2 deletions libbluos_ssc_ipc.c
Expand Up @@ -80,8 +80,6 @@ ipc_mqa_struct *bluos_ssc_ipc_init(SF_INFO in_file_info,
// We block until the decoder has put the initial details required into the
// shared_mqa_struct, and then return the handle.
while (shared_mqa_struct->turn != AMDREAD) {
printf("turn value %d\n", shared_mqa_struct->turn);
printf("frame value %d\n", shared_mqa_struct->get_samples_var.frame_size);
}

// TODO fork mqaplay_ipc here using a config file
Expand Down
3 changes: 2 additions & 1 deletion meson.build
Expand Up @@ -2,6 +2,7 @@ project('libbluos_ssc_ipc', 'c')

sndfile = dependency('sndfile')
gmp = dependency('gmp')
portaudio = dependency('portaudio-2.0')

bits = static_library('bits', 'mqa-files/bits.c')
mqa_common = static_library('mqa-common', 'mqa-files/mqa-common.c')
Expand All @@ -12,4 +13,4 @@ mqascan = static_library('mqascan', 'mqa-files/mqascan.c', dependencies:

bluos_ssc_ipc = library('bluos_ssc_ipc', 'libbluos_ssc_ipc.c', dependencies: sndfile, link_with: mqascan)

executable('sndfile_portaudio', 'samples/sndfile_portaudio.c', dependencies: sndfile, link_with: bluos_ssc_ipc )
executable('sndfile_portaudio', 'samples/sndfile_portaudio.c', dependencies: [sndfile, portaudio], link_with: bluos_ssc_ipc )
110 changes: 76 additions & 34 deletions samples/sndfile_portaudio.c
@@ -1,19 +1,27 @@
#include "../libbluos_ssc_ipc.h"
#include "ipc_structs.h"
#include "mqa-files/mqascan.h"
#include <portaudio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv) {
// lol help
// code partially stolen from
// https://github.com/hosackm/wavplayer/blob/master/src/wavplay.c

static int portaudio_callback(const void *input, void *output,
ulong frame_count,
const PaStreamCallbackTimeInfo *time_info,
PaStreamCallbackFlags status_flags,
void *user_data);
static ipc_mqa_struct *handle;
static SNDFILE *in_file;

ipc_mqa_struct *handle;
int main(int argc, char **argv) {
mqa_sample_rates rates;
int num_folds;
SNDFILE *in_file;
SNDFILE *out_file;
SF_INFO in_file_info;
SF_INFO out_file_info;
PaStream *stream;

memset(&in_file_info, 0, sizeof(in_file_info));
in_file = sf_open(argv[1], SFM_READ, &in_file_info);
Expand All @@ -26,39 +34,73 @@ int main(int argc, char **argv) {
num_folds = (rates.original_rate / rates.compressed_rate) / 2;
printf("initialising decoder with %d folds\n", num_folds);

// Set up outfile
out_file_info.samplerate = rates.original_rate; // infmt.samplerate << rs;
out_file_info.channels = in_file_info.channels;
out_file_info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_24;
out_file = sf_open(argv[2], SFM_WRITE, &out_file_info);
if (!out_file) {
// printf("sf_open (out) failed!\n");
// TODO convert rates into number of folds
handle = bluos_ssc_ipc_init(in_file_info, num_folds);

// PASTART
int error = Pa_Initialize();
if (error != paNoError) {
printf("Pa_Initialise failed!\n");
return 1;
}
error = Pa_OpenDefaultStream(
&stream, 0, in_file_info.channels, paInt32, rates.original_rate,
BUF_SIZE * handle->number_of_folds, portaudio_callback, NULL);
if (error != paNoError) {
printf("Pa_OpenDefaultStream failed!\n");
return 1;
}

// TODO convert rates into number of folds
handle = bluos_ssc_ipc_init(in_file_info, num_folds);
error = Pa_StartStream(stream);
if (error != paNoError) {
printf("Pa_StartStream failed!\n");
return 1;
}

while (Pa_IsStreamActive(stream)) {
Pa_Sleep(100);
}

sf_close(in_file);

error = Pa_Terminate();
if (error != paNoError) {
printf("Pa_Terminate failed!\n");
return 1;
}
// PAEND
return 0;
}

static int portaudio_callback(const void *input, void *output,
ulong frame_count,
const PaStreamCallbackTimeInfo *time_info,
PaStreamCallbackFlags status_flags,
void *user_data) {

out_file_info.samplerate = rates.original_rate; // infmt.samplerate << rs;
out_file_info.channels = in_file_info.channels;
out_file_info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_24;
int *out = (int *)output;

while (handle->turn != FINISHED) {
switch (handle->turn) {
case AMDREAD:
// read;
bluos_ssc_sndfile_read_samples_shm(handle, in_file);
goto handoff_point;
case AMDWRITE:
// write
sf_writef_int(out_file, handle->output_buffer,
handle->write_samples_var.len * num_folds);
goto handoff_point;
handoff_point:
bluos_ssc_ipc_handoff(handle);
break;
default:
continue;
if (handle->turn != FINISHED) {
while (true) {
switch (handle->turn) {
case AMDREAD:
// read;
bluos_ssc_sndfile_read_samples_shm(handle, in_file);
bluos_ssc_ipc_handoff(handle);
break;
case AMDWRITE:
// write
memcpy(out, handle->output_buffer,
sizeof(int) * handle->write_samples_var.len *
handle->audio_info.channels * handle->number_of_folds);
bluos_ssc_ipc_handoff(handle);
// we're done with this execution of the function
return paContinue;
default:
continue;
}
}
} else {
return paComplete;
}
}

0 comments on commit c49a216

Please sign in to comment.