From 784f71b831203e86d08e832401fb40f48600a3a2 Mon Sep 17 00:00:00 2001 From: Paul Dino Jones Date: Sat, 11 Nov 2023 18:19:39 +0000 Subject: [PATCH] Adding pulseaudio backend --- CMakeLists.txt | 16 +- src/monocoque/devices/CMakeLists.txt | 3 + src/monocoque/devices/simdevice.h | 7 +- src/monocoque/devices/sound.c | 79 ++++++++ src/monocoque/devices/sound.h | 13 ++ .../devices/sound/usb_generic_shaker.c | 71 ++++---- .../devices/sound/usb_generic_shaker.h | 5 +- .../devices/sound/usb_generic_shaker_pulse.c | 168 ++++++++++++++++++ src/monocoque/devices/sounddevice.c | 64 +++++-- src/monocoque/devices/sounddevice.h | 19 +- src/monocoque/gameloop/gameloop.c | 8 +- src/monocoque/helper/confighelper.c | 46 ++++- src/monocoque/helper/confighelper.h | 16 +- src/monocoque/helper/parameters.c | 1 + src/monocoque/monocoque.c | 22 ++- 15 files changed, 456 insertions(+), 82 deletions(-) create mode 100644 src/monocoque/devices/sound.c create mode 100644 src/monocoque/devices/sound.h create mode 100644 src/monocoque/devices/sound/usb_generic_shaker_pulse.c diff --git a/CMakeLists.txt b/CMakeLists.txt index a136282..cfaa127 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,16 +33,24 @@ FIND_LIBRARY(LIBUSB_LIBRARY NAMES usb-1.0 set(HIDAPI_WITH_LIBUSB TRUE) # surely will be used only on Linux set(BUILD_SHARED_LIBS TRUE) # HIDAPI as static library on all platforms +add_executable(monocoque src/monocoque/monocoque.c) +if(USE_PULSEAUDIO) + message("Using pulseaudio backend...") + add_compile_definitions(USE_PULSEAUDIO=true) + target_link_libraries(monocoque m ${LIBUSB_LIBRARY} hidapi-libusb pulse serialport xml2 argtable2 config gameloop helper devices slog simulatorapi) +else() + message("Using portaudio backend...") + target_link_libraries(monocoque m ${LIBUSB_LIBRARY} hidapi-libusb portaudio serialport xml2 argtable2 config gameloop helper devices slog simulatorapi) +endif() + +target_include_directories(monocoque PUBLIC config ${LIBUSB_INCLUDE_DIR} ${LIBXML_INCLUDE_DIR}) + add_subdirectory(src/monocoque/gameloop) add_subdirectory(src/monocoque/simulatorapi) add_subdirectory(src/monocoque/helper) add_subdirectory(src/monocoque/devices) add_subdirectory(src/monocoque/slog) -add_executable(monocoque src/monocoque/monocoque.c) -target_include_directories(monocoque PUBLIC config ${LIBUSB_INCLUDE_DIR} ${LIBXML_INCLUDE_DIR}) -target_link_libraries(monocoque m ${LIBUSB_LIBRARY} hidapi-libusb portaudio serialport xml2 argtable2 config gameloop helper devices slog simulatorapi) - add_executable(listusb tests/testlibusb.c) target_include_directories(listusb PUBLIC ${LIBUSB_INCLUDE_DIR}) target_link_libraries(listusb ${LIBUSB_LIBRARY} portaudio) diff --git a/src/monocoque/devices/CMakeLists.txt b/src/monocoque/devices/CMakeLists.txt index 11a819b..b85adde 100644 --- a/src/monocoque/devices/CMakeLists.txt +++ b/src/monocoque/devices/CMakeLists.txt @@ -9,10 +9,13 @@ set(devices_source_files serialdevice.c tachdevice.h tachdevice.c + sound.h + sound.c usb/revburner.h usb/revburner.c sound/usb_generic_shaker.h sound/usb_generic_shaker.c + sound/usb_generic_shaker_pulse.c serial/arduino.h serial/arduino.c ) diff --git a/src/monocoque/devices/simdevice.h b/src/monocoque/devices/simdevice.h index 72bc637..949c696 100644 --- a/src/monocoque/devices/simdevice.h +++ b/src/monocoque/devices/simdevice.h @@ -9,6 +9,7 @@ #include "../helper/confighelper.h" #include "../simulatorapi/simapi/simapi/simdata.h" + typedef struct SimDevice SimDevice; struct SimDevice @@ -83,9 +84,13 @@ typedef struct int id; SoundType type; VibrationEffectType effecttype; - PATestData sounddata; + SoundData sounddata; +#ifdef USE_PULSEAUDIO + pa_stream *stream; +#else PaStreamParameters outputParameters; PaStream* stream; +#endif } SoundDevice; diff --git a/src/monocoque/devices/sound.c b/src/monocoque/devices/sound.c new file mode 100644 index 0000000..9264cec --- /dev/null +++ b/src/monocoque/devices/sound.c @@ -0,0 +1,79 @@ +#include "sound.h" + +#include "../slog/slog.h" + +#ifdef USE_PULSEAUDIO + +pa_threaded_mainloop* mainloop; +pa_context* context; + +void context_state_cb(pa_context* context, void* mainloop) { + pa_threaded_mainloop_signal(mainloop, 0); +} + +int setupsound() +{ + + + + pa_mainloop_api *mainloop_api; + + slogi("connecting pulseaudio..."); + // Get a mainloop and its context + mainloop = pa_threaded_mainloop_new(); + assert(mainloop); + mainloop_api = pa_threaded_mainloop_get_api(mainloop); + context = pa_context_new(mainloop_api, "Monocoque"); + assert(context); + + pa_context_set_state_callback(context, &context_state_cb, mainloop); + + // Lock the mainloop so that it does not run and crash before the context is ready + pa_threaded_mainloop_lock(mainloop); + + // Start the mainloop + assert(pa_threaded_mainloop_start(mainloop) == 0); + assert(pa_context_connect(context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL) == 0); + + // Wait for the context to be ready + for(;;) { + pa_context_state_t context_state = pa_context_get_state(context); + assert(PA_CONTEXT_IS_GOOD(context_state)); + if (context_state == PA_CONTEXT_READY) break; + pa_threaded_mainloop_wait(mainloop); + } + + slogi("successfully connected pulseaudio..."); + return 1; +} + + +int freesound() +{ + if (context) + pa_context_unref(context); + + if (mainloop) { + pa_signal_done(); + pa_threaded_mainloop_free(mainloop); + } + +} + +#else + +int setupsound() +{ + + + + slogi("connecting portaudio..."); +} + + +int freesound() +{ + +} + +#endif diff --git a/src/monocoque/devices/sound.h b/src/monocoque/devices/sound.h new file mode 100644 index 0000000..ff90a12 --- /dev/null +++ b/src/monocoque/devices/sound.h @@ -0,0 +1,13 @@ +#ifndef _SOUND_H +#define _SOUND_H + +#include + +extern pa_threaded_mainloop* mainloop; +extern pa_context* context; + + +int setupsound(); +int freesound(); + +#endif diff --git a/src/monocoque/devices/sound/usb_generic_shaker.c b/src/monocoque/devices/sound/usb_generic_shaker.c index a140f12..9924d7e 100644 --- a/src/monocoque/devices/sound/usb_generic_shaker.c +++ b/src/monocoque/devices/sound/usb_generic_shaker.c @@ -1,3 +1,5 @@ +#ifndef USE_PULSEAUDIO + #include #include #include @@ -10,6 +12,9 @@ #define SAMPLE_RATE (48000) +#define DURATION 4.0 +#define AMPLITUDE .5 + #ifndef M_PI #define M_PI (3.14159265) #endif @@ -22,39 +27,27 @@ int patestCallbackEngineRPM(const void* inputBuffer, PaStreamCallbackFlags statusFlags, void* userData) { - PATestData* data = (PATestData*)userData; + SoundData* data = (SoundData*)userData; float* out = (float*)outputBuffer; memset(out, 0, framesPerBuffer * 2 * sizeof(float)); unsigned int i; unsigned int n; - n = data->n; + //n = data->n; (void) inputBuffer; /* Prevent unused argument warning. */ for( i=0; iamp * sin (2 * M_PI * ((float) n) / (float) SAMPLE_RATE); + static double t = 0.0; + double sample = AMPLITUDE * 32767.0 * sin(2.0 * M_PI * data->curr_frequency * t); - if (n>=data->table_size) - { - n=0; - } - - - if (data->gear_sound_data > 0) - { - *out++ = 0; - *out++ = 0; - } - else - { - *out++ = v; - *out++ = v; + t += 1.0 / SAMPLE_RATE; + if (t >= DURATION) { + t = 0.0; } + *out++ = sample; + *out++ = sample; } - data->gear_sound_data = 0; - data->n=n; return 0; } @@ -66,39 +59,33 @@ int patestCallbackGearShift(const void* inputBuffer, PaStreamCallbackFlags statusFlags, void* userData) { - PATestData* data = (PATestData*)userData; + SoundData* data = (SoundData*)userData; float* out = (float*)outputBuffer; memset(out, 0, framesPerBuffer * 2 * sizeof(float)); unsigned int i; unsigned int n; - n = data->n; + //n = data->n; (void) inputBuffer; /* Prevent unused argument warning. */ for( i=0; iamp * sin (2 * M_PI * ((float) n) / (float) SAMPLE_RATE); - - if (n>=data->table_size) + static double t = 0.0; + double sample = 0; + if (data->frequency>0) { - n=0; + sample = AMPLITUDE * 32767.0 * sin(2.0 * M_PI * data->curr_frequency * data->curr_duration); } - if(data->gear_sound_data > 0) - { - *out++ = v; - *out++ = v; - } - else - { - *out++ = 0; - *out++ = 0; + + data->curr_duration += 1.0 / SAMPLE_RATE; + if (data->curr_duration >= data->duration) { + data->curr_duration = 0.0; + data->curr_frequency = 0; } + + *out++ = sample; + *out++ = sample; } - data->gear_sound_data = 0; - - data->n=n; - return 0; } int usb_generic_shaker_free(SoundDevice* sounddevice) @@ -169,3 +156,5 @@ error: Pa_Terminate(); return err; } + +#endif diff --git a/src/monocoque/devices/sound/usb_generic_shaker.h b/src/monocoque/devices/sound/usb_generic_shaker.h index d8c3f01..83441f3 100644 --- a/src/monocoque/devices/sound/usb_generic_shaker.h +++ b/src/monocoque/devices/sound/usb_generic_shaker.h @@ -1,10 +1,13 @@ #ifndef _USB_GENERIC_SHAKER_H #define _USB_GENERIC_SHAKER_H -//#include "../sounddevice.h" #include "../simdevice.h" +#ifdef USE_PULSEAUDIO +int usb_generic_shaker_init(SoundDevice* sounddevice, pa_threaded_mainloop* mainloop, pa_context* context, const char* devname, int volume, int pan, const char* streamname); +#else int usb_generic_shaker_init(SoundDevice* sounddevice); +#endif int usb_generic_shaker_free(SoundDevice* sounddevice); #endif diff --git a/src/monocoque/devices/sound/usb_generic_shaker_pulse.c b/src/monocoque/devices/sound/usb_generic_shaker_pulse.c new file mode 100644 index 0000000..6c14d60 --- /dev/null +++ b/src/monocoque/devices/sound/usb_generic_shaker_pulse.c @@ -0,0 +1,168 @@ +#ifdef USE_PULSEAUDIO + +#include +#include +#include +#include + + + +#include "usb_generic_shaker.h" +#include "../sounddevice.h" + +#define FORMAT PA_SAMPLE_S16LE +#define SAMPLE_RATE (48000) +#define AMPLITUDE .5 +#define DURATION 4.0 + +#ifndef M_PI +#define M_PI (3.14159265) +#endif + + +void gear_sound_stream(pa_stream *s, size_t length, void *userdata) { + + SoundData* data = (SoundData*)userdata; + size_t num_samples = length / sizeof(int16_t); + int16_t buffer[num_samples]; + + + for (size_t i = 0; i < num_samples; i++) { + static double t = 0.0; + double sample = 0; + if (data->frequency>0) + { + sample = AMPLITUDE * 32767.0 * sin(2.0 * M_PI * data->curr_frequency * data->curr_duration); + } + + + buffer[i] = (int16_t)sample; + + data->curr_duration += 1.0 / SAMPLE_RATE; + if (data->curr_duration >= data->duration) { + data->curr_duration = 0.0; + data->curr_frequency = 0; + } + } + pa_stream_write(s, buffer, length, NULL, 0LL, PA_SEEK_RELATIVE); +} + +void engine_sound_stream(pa_stream *s, size_t length, void *userdata) { + + SoundData* data = (SoundData*)userdata; + size_t num_samples = length / sizeof(int16_t); + int16_t buffer[num_samples]; + + for (size_t i = 0; i < num_samples; i++) { + static double t = 0.0; + double sample = AMPLITUDE * 32767.0 * sin(2.0 * M_PI * data->curr_frequency * t); + + + buffer[i] = (int16_t)sample; + + t += 1.0 / SAMPLE_RATE; + if (t >= DURATION) { + t = 0.0; + } + } + pa_stream_write(s, buffer, length, NULL, 0LL, PA_SEEK_RELATIVE); +} + +void stream_success_cb(pa_stream *stream, int success, void *userdata) { + return; +} + +void stream_state_cb(pa_stream *s, void *mainloop) { + pa_threaded_mainloop_signal(mainloop, 0); +} + +int usb_generic_shaker_free(SoundDevice* sounddevice) +{ + int err = 0; + //err = Pa_CloseStream( sounddevice->stream ); + //if( err != paNoError ) + //{ + // err = Pa_Terminate(); + //} + if (sounddevice->stream) + { + pa_stream_unref(sounddevice->stream); + pa_xfree(sounddevice->stream); + } + return err; +} + +int usb_generic_shaker_init(SoundDevice* sounddevice, pa_threaded_mainloop* mainloop, pa_context* context, const char* devname, int volume, int pan, const char* streamname) +{ + pa_stream *stream; + + // Create a playback stream + pa_sample_spec sample_specifications; + sample_specifications.format = FORMAT; + sample_specifications.rate = SAMPLE_RATE; + sample_specifications.channels = 2; + + + pa_channel_map channel_map; + pa_channel_map_init_stereo(&channel_map); + pa_channel_map_parse(&channel_map, "front-left,front-right"); + + + stream = pa_stream_new(context, streamname, &sample_specifications, &channel_map); + pa_stream_set_state_callback(stream, stream_state_cb, mainloop); + + + if (sounddevice->effecttype == SOUNDEFFECT_GEARSHIFT) + { + pa_stream_set_write_callback(stream, gear_sound_stream, &sounddevice->sounddata); + } + else + { + pa_stream_set_write_callback(stream, engine_sound_stream, &sounddevice->sounddata); + } + + // recommended settings, i.e. server uses sensible values + pa_buffer_attr buffer_attr; + buffer_attr.maxlength = (uint32_t) -1; + buffer_attr.tlength = (uint32_t) -1; + buffer_attr.prebuf = (uint32_t) -1; + buffer_attr.minreq = (uint32_t) -1; + + pa_cvolume cv; + uint16_t pvolume = ceil(((double) volume/100.0d)*65535); + // Settings copied as per the chromium browser source + pa_stream_flags_t stream_flags; + stream_flags = PA_STREAM_INTERPOLATE_TIMING | + PA_STREAM_NOT_MONOTONIC | PA_STREAM_AUTO_TIMING_UPDATE | + PA_STREAM_ADJUST_LATENCY; + + //stream_flags = PA_STREAM_START_CORKED; + // Connect stream to the default audio output sink + pa_cvolume_set(&cv, sample_specifications.channels, pvolume); + //pa_cvolume_set(&cv, 1, 0); + + pa_cvolume_set_balance(&cv, &channel_map, pan); + + assert(pa_stream_connect_playback(stream, devname, &buffer_attr, stream_flags, &cv, NULL) == 0); + + + + // Wait for the stream to be ready + for(;;) { + pa_stream_state_t stream_state = pa_stream_get_state(stream); + assert(PA_STREAM_IS_GOOD(stream_state)); + if (stream_state == PA_STREAM_READY) break; + pa_threaded_mainloop_wait(mainloop); + } + + + //pa_threaded_mainloop_unlock(mainloop); + + // Uncork the stream so it will start playing + pa_stream_cork(stream, 0, stream_success_cb, mainloop); + + sounddevice->stream = stream; + return 0; +} + +#endif diff --git a/src/monocoque/devices/sounddevice.c b/src/monocoque/devices/sounddevice.c index 39b3d17..be1f564 100644 --- a/src/monocoque/devices/sounddevice.c +++ b/src/monocoque/devices/sounddevice.c @@ -5,6 +5,7 @@ #include #include +#include "sound.h" #include "simdevice.h" #include "sounddevice.h" #include "sound/usb_generic_shaker.h" @@ -12,13 +13,18 @@ #include "../helper/parameters.h" #include "../slog/slog.h" + int gear_sound_set(SoundDevice* sounddevice, SimData* simdata) { - if (sounddevice->sounddata.last_gear != simdata->gear && simdata->gear != 0) + if (sounddevice->sounddata.last_gear != simdata->gear && simdata->gear > 1) { - sounddevice->sounddata.gear_sound_data = 3.14; + //sounddevice->sounddata.gear_sound_data = 3.14; + sounddevice->sounddata.curr_frequency = sounddevice->sounddata.frequency; + sounddevice->sounddata.curr_duration = 0; } sounddevice->sounddata.last_gear = simdata->gear; + + slogt("set gear frequency to %i", sounddevice->sounddata.frequency); } // we could make a vtable for these different effects too @@ -26,9 +32,10 @@ int sounddev_engine_update(SimDevice* this, SimData* simdata) { SoundDevice* sounddevice = (void *) this->derived; - gear_sound_set(sounddevice, simdata); + sounddevice->sounddata.curr_frequency = simdata->rpms/60; + //sounddevice->sounddata.table_size = 48000/(sounddevice->sounddata.frequency); - sounddevice->sounddata.table_size = 44100/(simdata->rpms/60); + slogt("set engine frequency to %i", sounddevice->sounddata.frequency); } int sounddev_gearshift_update(SimDevice* this, SimData* simdata) @@ -49,28 +56,51 @@ int sounddev_free(SimDevice* this) return 0; } -int sounddev_init(SoundDevice* sounddevice) +int sounddev_init(SoundDevice* sounddevice, const char* devname, int volume, int frequency, int pan, double duration) { slogi("initializing standalone sound device..."); - sounddevice->sounddata.pitch = 1; - sounddevice->sounddata.pitch = 261.626; - sounddevice->sounddata.amp = 32; - sounddevice->sounddata.left_phase = sounddevice->sounddata.right_phase = 0; - sounddevice->sounddata.table_size = 44100/(100/60); - sounddevice->sounddata.last_gear = 0; + slogi("volume is: %i", volume); + slogi("frequency is: %i", frequency); + slogi("pan is: %i", pan); + slogi("duration is: %f", duration); + + + sounddevice->sounddata.frequency = frequency; + //sounddevice->sounddata.pitch = 1; + //sounddevice->sounddata.pitch = 261.626; + //sounddevice->sounddata.amp = 32; + //sounddevice->sounddata.left_phase = sounddevice->sounddata.right_phase = 0; + //sounddevice->sounddata.table_size = 48000/(100/60); + sounddevice->sounddata.curr_frequency = 100/60; + + + + const char* streamname= "Engine"; switch (sounddevice->effecttype) { case (SOUNDEFFECT_GEARSHIFT): - sounddevice->sounddata.pitch = 500; - sounddevice->sounddata.amp = 128; - sounddevice->sounddata.left_phase = sounddevice->sounddata.right_phase = 0; - sounddevice->sounddata.table_size = 44100/(1); + sounddevice->sounddata.last_gear = 0; + //sounddevice->sounddata.pitch = 500; + //sounddevice->sounddata.amp = 128; + //sounddevice->sounddata.left_phase = sounddevice->sounddata.right_phase = 0; + //sounddevice->sounddata.table_size = 48000/(1); + sounddevice->sounddata.duration = duration; + sounddevice->sounddata.curr_duration = duration; + streamname = "Gear"; break; } +#ifdef USE_PULSEAUDIO + + + //pa_threaded_mainloop* mainloop; + //pa_context* context; + usb_generic_shaker_init(sounddevice, mainloop, context, devname, volume, pan, streamname); +#else usb_generic_shaker_init(sounddevice); +#endif } static const vtable engine_sound_simdevice_vtable = { &sounddev_engine_update, &sounddev_free }; @@ -98,7 +128,9 @@ SoundDevice* new_sound_device(DeviceSettings* ds) { break; } - int error = sounddev_init(this); + slogt("Attempting to use device %s", ds->sounddevsettings.dev); + + int error = sounddev_init(this, ds->sounddevsettings.dev, ds->sounddevsettings.volume, ds->sounddevsettings.frequency, ds->sounddevsettings.pan, ds->sounddevsettings.duration); if (error != 0) { free(this); diff --git a/src/monocoque/devices/sounddevice.h b/src/monocoque/devices/sounddevice.h index 8d1e36b..8019176 100644 --- a/src/monocoque/devices/sounddevice.h +++ b/src/monocoque/devices/sounddevice.h @@ -1,7 +1,11 @@ #ifndef _SOUNDDEVICE_H #define _SOUNDDEVICE_H +#ifdef USE_PULSEAUDIO +#include +#else #include "portaudio.h" +#endif typedef enum { @@ -20,16 +24,13 @@ VibrationEffectType; #define MAX_TABLE_SIZE (6000) typedef struct { - float sine[MAX_TABLE_SIZE]; - float pitch; int last_gear; - int left_phase; - int right_phase; - int n; - int table_size; - int amp; - int gear_sound_data; + int volume; + int frequency; + double duration; + int curr_frequency; + double curr_duration; } -PATestData; +SoundData; #endif diff --git a/src/monocoque/gameloop/gameloop.c b/src/monocoque/gameloop/gameloop.c index 4b6ada0..2b9db20 100644 --- a/src/monocoque/gameloop/gameloop.c +++ b/src/monocoque/gameloop/gameloop.c @@ -321,7 +321,7 @@ int tester(SimDevice* devices, int numdevices) sleep(3); fprintf(stdout, "Shifting into first gear\n"); - simdata->gear = 1; + simdata->gear = 2; for (int x = 0; x < numdevices; x++) { devices[x].update(&devices[x], simdata); @@ -341,7 +341,7 @@ int tester(SimDevice* devices, int numdevices) sleep(3); fprintf(stdout, "Shifting into second gear\n"); - simdata->gear = 2; + simdata->gear = 3; for (int x = 0; x < numdevices; x++) { devices[x].update(&devices[x], simdata); @@ -361,7 +361,7 @@ int tester(SimDevice* devices, int numdevices) sleep(3); fprintf(stdout, "Shifting into third gear\n"); - simdata->gear = 3; + simdata->gear = 4; for (int x = 0; x < numdevices; x++) { devices[x].update(&devices[x], simdata); @@ -389,7 +389,7 @@ int tester(SimDevice* devices, int numdevices) sleep(3); fprintf(stdout, "Shifting into fourth gear\n"); - simdata->gear = 4; + simdata->gear = 5; for (int x = 0; x < numdevices; x++) { devices[x].update(&devices[x], simdata); diff --git a/src/monocoque/helper/confighelper.c b/src/monocoque/helper/confighelper.c index 49dbd37..bc30012 100644 --- a/src/monocoque/helper/confighelper.c +++ b/src/monocoque/helper/confighelper.c @@ -11,7 +11,9 @@ #include "confighelper.h" #include "../slog/slog.h" +#include "parameters.h" +#include int strcicmp(char const *a, char const *b) { @@ -84,6 +86,11 @@ int strtodevsubtype(const char* device_subtype, DeviceSettings* ds, int simdev) ds->dev_subtype = SIMDEVTYPE_GEARSOUND; break; } + if (strcicmp(device_subtype, "ABS") == 0) + { + ds->dev_subtype = SIMDEVTYPE_ABSBRAKES; + break; + } default: ds->is_valid = false; slogw("%s does not appear to be a valid device sub type, but attempting to continue with other devices", device_subtype); @@ -228,7 +235,7 @@ int loadconfig(const char* config_file, DeviceSettings* ds) int devsetup(const char* device_type, const char* device_subtype, const char* config_file, MonocoqueSettings* ms, DeviceSettings* ds, config_setting_t* device_settings) { int error = MONOCOQUE_ERROR_NONE; - slogi("Called device setup with %s %s %s", device_type, device_subtype, config_file); + slogt("Called device setup with %s %s %s", device_type, device_subtype, config_file); ds->dev_type = SIMDEV_UNKNOWN; error = strtodev(device_type, device_subtype, ds); @@ -246,6 +253,41 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co return error; } + if (ds->dev_type == SIMDEV_SOUND) + { + slogi("reading configured sound device settings"); + ds->sounddevsettings.frequency = -1; + ds->sounddevsettings.volume = -1; + ds->sounddevsettings.lowbound_frequency = -1; + ds->sounddevsettings.upperbound_frequency = -1; + ds->sounddevsettings.pan = 0; + ds->sounddevsettings.duration = 2.0; + if (ds->dev_subtype == SIMDEVTYPE_GEARSOUND) + { + ds->sounddevsettings.duration = .125; + } + if (device_settings != NULL) + { + + config_setting_lookup_int(device_settings, "volume", &ds->sounddevsettings.volume); + config_setting_lookup_int(device_settings, "frequency", &ds->sounddevsettings.frequency); + config_setting_lookup_int(device_settings, "pan", &ds->sounddevsettings.pan); + config_setting_lookup_float(device_settings, "duration", &ds->sounddevsettings.duration); + + const char* temp; + int found = 0; + found = config_setting_lookup_string(device_settings, "devid", &temp); + if (found == 0) + { + ds->sounddevsettings.dev = NULL; + } + else + { + ds->sounddevsettings.dev = strdup(temp); + } + } + } + if (ds->dev_subtype == SIMDEVTYPE_TACHOMETER) { if (device_settings != NULL) @@ -264,6 +306,8 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co ds->tachsettings.use_pulses = false; } } + + if (ds->dev_subtype == SIMDEVTYPE_SIMWIND || ds->dev_subtype == SIMDEVTYPE_SHIFTLIGHTS) { if (device_settings != NULL) diff --git a/src/monocoque/helper/confighelper.h b/src/monocoque/helper/confighelper.h index ef7a585..2478347 100644 --- a/src/monocoque/helper/confighelper.h +++ b/src/monocoque/helper/confighelper.h @@ -24,7 +24,8 @@ typedef enum SIMDEVTYPE_SHIFTLIGHTS = 2, SIMDEVTYPE_SIMWIND = 3, SIMDEVTYPE_ENGINESOUND = 4, - SIMDEVTYPE_GEARSOUND = 5 + SIMDEVTYPE_GEARSOUND = 5, + SIMDEVTYPE_ABSBRAKES = 6 } DeviceSubType; @@ -74,6 +75,18 @@ typedef struct } SerialDeviceSettings; +typedef struct +{ + int frequency; + int volume; + int lowbound_frequency; + int upperbound_frequency; + int pan; + double duration; + char* dev; +} +SoundDeviceSettings; + typedef struct { bool is_valid; @@ -81,6 +94,7 @@ typedef struct DeviceSubType dev_subtype; TachometerSettings tachsettings; SerialDeviceSettings serialdevsettings; + SoundDeviceSettings sounddevsettings; } DeviceSettings; diff --git a/src/monocoque/helper/parameters.c b/src/monocoque/helper/parameters.c index 923448d..7d3b82b 100644 --- a/src/monocoque/helper/parameters.c +++ b/src/monocoque/helper/parameters.c @@ -104,6 +104,7 @@ ConfigError getParameters(int argc, char** argv, Parameters* p) else if (nerrors3==0) { p->program_action = A_TEST; + p->verbosity_count = arg_verbosity3->count; exitcode = E_SUCCESS_AND_DO; } else diff --git a/src/monocoque/monocoque.c b/src/monocoque/monocoque.c index 7967067..84daa7d 100644 --- a/src/monocoque/monocoque.c +++ b/src/monocoque/monocoque.c @@ -7,12 +7,14 @@ #include "gameloop/gameloop.h" #include "gameloop/tachconfig.h" #include "devices/simdevice.h" +#include "devices/sound.h" #include "helper/parameters.h" #include "helper/dirhelper.h" #include "helper/confighelper.h" #include "simulatorapi/simapi/simapi/simdata.h" #include "slog/slog.h" + int create_dir(char* dir) { struct stat st = {0}; @@ -149,9 +151,9 @@ int main(int argc, char** argv) DeviceSettings ds[configureddevices]; slogi("found %i devices in configuration", configureddevices); int i = 0; + error = MONOCOQUE_ERROR_NONE; while (iprogram_action == A_PLAY) { - //slogi("running monocoque in gameloop mode.."); + slogi("running monocoque in gameloop mode.."); //error = strtogame(p->sim_string, ms); //if (error != MONOCOQUE_ERROR_NONE) //{ // goto cleanup_final; //} - +#ifdef USE_PULSEAUDIO + pa_threaded_mainloop_unlock(mainloop); +#endif error = looper(devices, initdevices, p); if (error == MONOCOQUE_ERROR_NONE) @@ -205,6 +214,11 @@ int main(int argc, char** argv) else { slogi("running monocoque in test mode..."); + +#ifdef USE_PULSEAUDIO + pa_threaded_mainloop_unlock(mainloop); +#endif + error = tester(devices, initdevices); if (error == MONOCOQUE_ERROR_NONE) {