From 08a3caf0b60fbf1d1776acb4d135bca483ddb91a Mon Sep 17 00:00:00 2001 From: Marek Blok <marek.blok@pg.edu.pl> Date: Sun, 16 May 2021 12:06:59 +0200 Subject: [PATCH] initial convertion of ALSA_object_t to class based on SOUND_object_t --- CHANGELOG | 3 ++ src/Main.cpp | 39 ++++++++++------- src/Makefile.linux | 20 +++++++-- src/cpp/ALSA_support.cpp | 90 ++++++++++++++++++++++++++++++++++---- src/cpp/DSP_IO.cpp | 23 ++++++++-- src/cpp/WMM_support.cpp | 4 +- src/include/ALSA_support.h | 42 +++++++++++++++--- src/include/DSP_IO.h | 12 ++++- src/include/DSP_lib.h | 2 +- src/include/DSP_types.h | 25 ++++++++--- src/include/WMM_support.h | 4 +- 11 files changed, 212 insertions(+), 52 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 00975c4..15826cb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,9 @@ TODO:: LAST DONE: CHANGES: +- ver. 0.20.007 - <b>2021.05.16</b> Changed: + - initial convertion of ALSA_object_t to class based on SOUND_object_t + - ver. 0.20.006 - <b>2021.05.14</b> Changed: - Included examples tests in DEBUG compilation for windows (test_hello, test_sound_input) - DSP::u::AudioInput now uses SOUND_object_t (currently just WMM_object_t) for soundcard API diff --git a/src/Main.cpp b/src/Main.cpp index 2b929e3..339600d 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -2718,21 +2718,22 @@ int test_ZPSTC_cw_3() to the default PCM device for 5 seconds of data. */ - int test_playback(vector<int16_t> buffer) { + int test_playback(DSP::Float_vector &float_buffer) { long loops; - int rc; + long rc; int frames_size; snd_pcm_uframes_t frames; //char *buffer; unsigned int period_time; - ALSA_object_t ALSA_object; + DSP::ALSA_object_t ALSA_object; /* Open PCM device for playback (2 channels). */ - unsigned int Fs = 44100; - rc = ALSA_object.open_alsa_device(SND_PCM_STREAM_PLAYBACK, 2, Fs); + long Fs = 44100; + //rc = ALSA_object.open_alsa_device(SND_PCM_STREAM_PLAYBACK, 2, Fs); + rc = ALSA_object.open_PCM_device_4_output(2, 16, Fs); - ALSA_object.get_params(frames, period_time); + //ALSA_object.get_period_size(frames, period_time); // /* Allocate a hardware parameters object. */ // snd_pcm_hw_params_alloca(¶ms); @@ -2741,15 +2742,17 @@ int test_ZPSTC_cw_3() // // /* Use a buffer large enough to hold one period */ // snd_pcm_hw_params_get_period_size(params, &frames, &dir); - frames_size = frames * 2/sizeof(int16_t) * 2; /* 2 bytes/sample, 2 channels */ +// frames_size = frames * 2/sizeof(int16_t) * 2; /* 2 bytes/sample, 2 channels */ + frames_size = 1024 * 2/sizeof(int16_t) * 2; /* 2 bytes/sample, 2 channels */ //buffer = (char *) malloc(size); // // /* We want to loop for 5 seconds */ // snd_pcm_hw_params_get_period_time(params, &val, &dir); /* 5 seconds in microseconds divided by * period time */ + period_time = Fs/frames_size; loops = 5000000 / period_time; - buffer.resize(loops * frames_size, 0); + float_buffer.resize(loops * frames_size, 0); int loop_index = 0; while (loops > 0) { @@ -2758,16 +2761,18 @@ int test_ZPSTC_cw_3() // //rc = read(0, buffer, size); for (int ind = 0; ind < frames_size; ind++) { - buffer[ind + loop_index * frames_size] = (4*ind) % INT16_MAX; + float_buffer[ind + loop_index * frames_size] = (4*ind) % INT16_MAX; } //! \TODO check problem with vector aligments - rc = ALSA_object.pcm_writei(buffer.data() + loop_index * frames_size, frames); + //rc = ALSA_object.pcm_writei(buffer.data() + loop_index * frames_size, frames); + rc = ALSA_object.append_playback_buffer(float_buffer); loop_index++; } - ALSA_object.close_alsa_device(true); //snd_pcm_close(alsa_handle); + //ALSA_object.close_alsa_device(true); //snd_pcm_close(alsa_handle); + ALSA_object.close_PCM_device_output(); //free(buffer); return 0; @@ -2907,19 +2912,23 @@ polling: */ int test_ALSA() { - ALSA_object_t ALSA_object; + DSP::ALSA_object_t ALSA_object; ALSA_object.log_driver_data(); unsigned int Fs = 44100; - int rs = ALSA_object.open_alsa_device(SND_PCM_STREAM_PLAYBACK, 2, Fs); + int rs = ALSA_object.open_PCM_device_4_output(2, 16, Fs); if (rs == 1) { - ALSA_object.close_alsa_device(); + ALSA_object.close_PCM_device_output(); } vector<int16_t> signal = test_record(); - test_playback(signal); + DSP::Float_vector float_signal; + for (auto ind=0; ind < signal.size(); ind++) { + float_signal[ind] = signal[ind]; + } + test_playback(float_signal); return 0; } diff --git a/src/Makefile.linux b/src/Makefile.linux index bb16c0b..2443d6c 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -11,6 +11,7 @@ com_ver = $(shell gcc -dumpmachine)-gcc_$(shell gcc -dumpversion) INSTALL_DIR_ROOT = ../_DSPE_lib_linux_ SRC_DIR = ./src +SRC_EXAMPLES_DIR = ./examples SRC_CPP_SUBDIR = $(SRC_DIR)/cpp @@ -42,6 +43,9 @@ SOURCES = $(addprefix $(SRC_CPP_SUBDIR)/,$(SOURCES_NAMES)) SOURCES_DBG = SOURCES_DBG += $(SRC_DIR)/Main.cpp +SOURCES_EXAMPLES_DBG = +SOURCES_EXAMPLES_DBG += $(SRC_EXAMPLES_DIR)/hello.cpp $(SRC_EXAMPLES_DIR)/sound_input.cpp + # ################################################# # # Just sockets // currently not supported in Linux SOURCES_SOCKETS_NAMES = DSP_sockets.cpp @@ -64,6 +68,8 @@ OBJECTS_Debug := $(SOURCES:%.cpp=$(OUT_DIR_DBG)/%.o) DEPENDS_Debug := $(SOURCES:%.cpp=$(OUT_DIR_DBG)/%.d) OBJECTS_Debug += $(SOURCES_DBG:%.cpp=$(OUT_DIR_DBG)/%.o) DEPENDS_Debug += $(SOURCES_DBG:%.cpp=$(OUT_DIR_DBG)/%.d) +OBJECTS_EXAMPLES_Debug := $(SOURCES_EXAMPLES_DBG:%.cpp=$(OUT_DIR_DBG)/%.o) +DEPENDS_EXAMPLES_Debug := $(SOURCES_EXAMPLES_DBG:%.cpp=$(OUT_DIR_DBG)/%.d) OBJECTS_SOCKETS_Debug := $(SOURCES_SOCKETS:%.cpp=$(OUT_DIR_DBG)/%.o) DEPENDS_SOCKETS_Debug := $(SOURCES_SOCKETS:%.cpp=$(OUT_DIR_DBG)/%.d) @@ -77,6 +83,7 @@ OBJECTS_MISC_Debug := -include $(DEPENDS_SOCKETS_Release) -include $(DEPENDS_Debug) -include $(DEPENDS_SOCKETS_Debug) +-include $(DEPENDS_EXAMPLES_Debug) all: Debug Release @@ -105,11 +112,11 @@ $(OBJECTS_Release) $(OBJECTS_SOCKETS_Release): $(OUT_DIR_RLS)/%.o : %.cpp # ########################################################################################### # # ########################################################################################### # -# Debug: $(OUT_DIR_DBG)/libDSPE.a $(OUT_DIR_DBG)/libDSPEsockets.a +# Debug: $(OUT_DIR_DBG)/libDSPE.a $(OUT_DIR_DBG)/libDSPEsockets.a $(OUT_DIR_DBG)/libDSPEexamples.a Debug: $(OUT_DIR_DBG)/DSPElib.exe -$(OUT_DIR_DBG)/DSPElib.exe: $(OUT_DIR_DBG)/libDSPE.a $(OUT_DIR_DBG)/libDSPEsockets.a - $(CC) -L"$(OUT_DIR_DBG)" "$(OUT_DIR_DBG)/src/Main.o" -o"$(OUT_DIR_DBG)/DSPElib.exe" $(LINKER_FLAGS_debug) -lDSPE $(LIBS) +$(OUT_DIR_DBG)/DSPElib.exe: $(OUT_DIR_DBG)/libDSPE.a $(OUT_DIR_DBG)/libDSPEsockets.a $(OUT_DIR_DBG)/libDSPEexamples.a + $(CC) -L"$(OUT_DIR_DBG)" "$(OUT_DIR_DBG)/src/Main.o" -o"$(OUT_DIR_DBG)/DSPElib.exe" $(LINKER_FLAGS_debug) -lDSPE -lDSPEexamples $(LIBS) $(OUT_DIR_DBG)/libDSPE.a: $(OBJECTS_Debug) $(OBJECTS_MISC_Debug) @echo Preparing lib file $@ @@ -120,8 +127,13 @@ $(OUT_DIR_DBG)/libDSPEsockets.a: $(OBJECTS_SOCKETS_Debug) ar rc $@ $(OBJECTS_SOCKETS_Debug) ranlib $@ +$(OUT_DIR_DBG)/libDSPEexamples.a: $(OBJECTS_EXAMPLES_Debug) + @echo Preparing lib file $@ + ar rc $@ $(OBJECTS_EXAMPLES_Debug) + ranlib $@ + # Z podanej listy usuwany $(OUT_DIR_RLS)/ oraz '.o' zamieniamy na '.cpp' -$(OBJECTS_Debug) $(OBJECTS_SOCKETS_Debug) $(OBJECTS_MISC_Debug): $(OUT_DIR_DBG)/%.o : %.cpp +$(OBJECTS_Debug) $(OBJECTS_EXAMPLES_Debug) $(OBJECTS_SOCKETS_Debug) $(OBJECTS_MISC_Debug): $(OUT_DIR_DBG)/%.o : %.cpp @echo $(@D) $< $@ mkdir -p $(@D) diff --git a/src/cpp/ALSA_support.cpp b/src/cpp/ALSA_support.cpp index 0632be7..7013fd0 100644 --- a/src/cpp/ALSA_support.cpp +++ b/src/cpp/ALSA_support.cpp @@ -4,18 +4,20 @@ * \author Marek Blok */ -#include "ALSA_support.h" +#include <ALSA_support.h> + +#include <DSP_lib.h> // for logging // ============================================================= // // Based on: https://www.linuxjournal.com/article/6735 // ============================================================= // -ALSA_object_t::ALSA_object_t() +DSP::ALSA_object_t::ALSA_object_t() { alsa_handle = NULL; hw_params = NULL; }; -ALSA_object_t::~ALSA_object_t() +DSP::ALSA_object_t::~ALSA_object_t() { if (hw_params != NULL){ snd_pcm_hw_params_free(hw_params); @@ -23,8 +25,25 @@ ALSA_object_t::~ALSA_object_t() } } +unsigned int DSP::ALSA_object_t::select_input_device_by_number(const unsigned int &device_number) { + assert(!"ALSA_object_t::select_input_device_by_number not yet implemented"); +} + +unsigned int DSP::ALSA_object_t::select_output_device_by_number(const unsigned int &device_number) { + assert(!"ALSA_object_t::select_output_device_by_number not yet implemented"); +} + +bool DSP::ALSA_object_t::is_output_callback_supported(void) { + assert(!"ALSA_object_t::is_output_callback_supported not yet implemented"); + return false; +} + +bool DSP::ALSA_object_t::is_input_callback_supported(void) { + assert(!"ALSA_object_t::is_input_callback_supported not yet implemented"); + return false; +} -void ALSA_object_t::log_driver_data() { +void DSP::ALSA_object_t::log_driver_data() { int val; DSP::log << "ALSA library version: " << SND_LIB_VERSION_STR << endl; @@ -69,7 +88,7 @@ perform any sound playback or recording. returns actually selected sampling_rate */ -int ALSA_object_t::open_alsa_device(snd_pcm_stream_t stream_type, int no_of_channels, unsigned int &sampling_rate) { +int DSP::ALSA_object_t::open_alsa_device(snd_pcm_stream_t stream_type, int no_of_channels, unsigned int &sampling_rate) { int rc; snd_pcm_t *handle; unsigned int val, val2; @@ -86,7 +105,7 @@ int ALSA_object_t::open_alsa_device(snd_pcm_stream_t stream_type, int no_of_chan //! \TODO Test mode: Open mode (see SND_PCM_NONBLOCK, SND_PCM_ASYNC) /* Open PCM device for playback. */ rc = snd_pcm_open(&handle, "default", - stream_type, 0); + stream_type, SND_PCM_NONBLOCK); if (rc < 0) { DSP::log << "unable to open pcm device: " << snd_strerror(rc) << endl; //exit(1); @@ -120,6 +139,8 @@ int ALSA_object_t::open_alsa_device(snd_pcm_stream_t stream_type, int no_of_chan /* 44100 bits/second sampling rate (CD quality) */ snd_pcm_hw_params_set_rate_near(alsa_handle, params, &sampling_rate, &dir); + //snd_pcm_hw_params_set_buffer_size(); + /* Write the parameters to the driver */ rc = snd_pcm_hw_params(alsa_handle, params); if (rc < 0) { @@ -225,12 +246,16 @@ int ALSA_object_t::open_alsa_device(snd_pcm_stream_t stream_type, int no_of_chan return 1; } -void ALSA_object_t::get_params(snd_pcm_uframes_t &frames, unsigned int &period_time) { +void DSP::ALSA_object_t::get_period_size(snd_pcm_uframes_t &frames, unsigned int &period_time) { int dir; // snd_pcm_hw_params_current() // Retreive current PCM hardware configuration chosen with snd_pcm_hw_params. //snd_pcm_hw_params_current(alsa_handle, hw_params); + // https://www.alsa-project.org/wiki/FramesPeriods + // frame - size of sample in byts + // A period is the number of frames in between each hardware interrupt + /* Use a buffer large enough to hold one period */ snd_pcm_hw_params_get_period_size(hw_params, &frames, &dir); @@ -238,7 +263,54 @@ void ALSA_object_t::get_params(snd_pcm_uframes_t &frames, unsigned int &period_t snd_pcm_hw_params_get_period_time(hw_params, &period_time, &dir); } -snd_pcm_sframes_t ALSA_object_t::pcm_writei(const void *buffer, snd_pcm_uframes_t &frames) { +long DSP::ALSA_object_t::open_PCM_device_4_output(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size) { + assert(!"DSP::ALSA_object_t::open_PCM_device_4_output not implemented yet"); +} + +long DSP::ALSA_object_t::open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size) { + assert(!"DSP::ALSA_object_t::open_PCM_device_4_input not implemented yet"); +} + +long DSP::ALSA_object_t::append_playback_buffer(DSP::Float_vector &float_buffer) { + assert(!"DSP::ALSA_object_t::append_playback_buffer not implemented yet"); +} + +bool DSP::ALSA_object_t::close_PCM_device_input(void) { + assert(!"DSP::ALSA_object_t::close_PCM_device_input not implemented yet"); + close_alsa_device(true); + return true; +} + +bool DSP::ALSA_object_t::close_PCM_device_output(void) { + assert(!"DSP::ALSA_object_t::close_PCM_device_output not implemented yet"); + close_alsa_device(true); + return true; +} + +bool DSP::ALSA_object_t::is_device_playing(void) { + assert(!"DSP::ALSA_object_t::is_device_playing not implemented yet"); + return false; +} + +bool DSP::ALSA_object_t::is_device_recording(void) { + assert(!"DSP::ALSA_object_t::is_device_recording not implemented yet"); + return false; +} + +bool DSP::ALSA_object_t::stop_playback(void) { + assert(!"DSP::ALSA_object_t::stop_playback not implemented yet"); +} + +bool DSP::ALSA_object_t::stop_recording(void) { + assert(!"DSP::ALSA_object_t::stop_recording not implemented yet"); +} + +bool DSP::ALSA_object_t::start_recording(void) { + assert(!"DSP::ALSA_object_t::stop_recording not implemented yet"); +} + + +snd_pcm_sframes_t DSP::ALSA_object_t::pcm_writei(const void *buffer, snd_pcm_uframes_t &frames) { snd_pcm_sframes_t rc = snd_pcm_writei(alsa_handle, buffer, frames); if (rc == -EPIPE) { /* EPIPE means underrun */ @@ -255,7 +327,7 @@ snd_pcm_sframes_t ALSA_object_t::pcm_writei(const void *buffer, snd_pcm_uframes_ return rc; } -void ALSA_object_t::close_alsa_device(bool do_drain, bool use_log) { +void DSP::ALSA_object_t::close_alsa_device(bool do_drain, bool use_log) { if (alsa_handle != NULL) { if (do_drain == true) { snd_pcm_drain(alsa_handle); diff --git a/src/cpp/DSP_IO.cpp b/src/cpp/DSP_IO.cpp index dea7ebd..af3da1b 100644 --- a/src/cpp/DSP_IO.cpp +++ b/src/cpp/DSP_IO.cpp @@ -14,6 +14,7 @@ #include <limits.h> #include <typeinfo> #include <cstdint> // int16_t, itp. +#include <functional> #ifdef WINMMAPI // #include <stdarg.h> @@ -4127,7 +4128,9 @@ void DSP::u::AudioInput::Init(DSP::Clock_ptr ParentClock, audio_inbuffer_size = DSP::f::GetAudioBufferSize(SamplingFreq, DSP::e::AudioBufferType::input); snd_object.select_input_device_by_number(WaveInDevNo); // use default device - snd_object.register_input_callback_object(this, SOUND_object_callback); // use default device +// DSP::input_callback_function cp = std::bind(&DSP::u::AudioInput::SOUND_object_callback, this, std::placeholders::_1, std::placeholders::_2); + DSP::input_callback_function cp = &DSP::u::AudioInput::SOUND_object_callback; + snd_object.register_input_callback_object(this, cp); // use default device if (snd_object.open_PCM_device_4_input(NoOfOutputs, BitPrec, SamplingFreq, audio_inbuffer_size) > 0) { InBufferLen=NoOfOutputs*audio_inbuffer_size; for (ind = 0; ind < DSP::NoOfAudioInputBuffers; ind++) @@ -5841,11 +5844,13 @@ DSP::u::AudioOutput *DSP::SOUND_object_t::get_output_callback_object() { return AudioOutput_object; } -bool DSP::SOUND_object_t::output_callback_call() { - return (AudioOutput_object->*AudioOutput_callback)(); +bool DSP::SOUND_object_t::output_callback_call(const DSP::e::SampleType &OutSampleType, const std::vector<char> &wave_out_raw_buffer) { +// return (AudioOutput_object->*AudioOutput_callback)(); + return (AudioOutput_object->*AudioOutput_callback)(OutSampleType, wave_out_raw_buffer); } -bool DSP::SOUND_object_t::register_input_callback_object(DSP::u::AudioInput *callback_object, bool(DSP::u::AudioInput::*cp)(const DSP::e::SampleType &, const std::vector<char> &)) { +//bool DSP::SOUND_object_t::register_input_callback_object(DSP::u::AudioInput *callback_object, bool(DSP::u::AudioInput::*cp)(const DSP::e::SampleType &, const std::vector<char> &)) { +bool DSP::SOUND_object_t::register_input_callback_object(DSP::u::AudioInput *callback_object, input_callback_function &cp) { if (is_input_callback_supported() == true) { AudioInput_object = callback_object; AudioInput_callback = cp; @@ -5854,6 +5859,16 @@ bool DSP::SOUND_object_t::register_input_callback_object(DSP::u::AudioInput *cal return false; } +bool DSP::SOUND_object_t::register_output_callback_object(DSP::u::AudioOutput *callback_object, output_callback_function &cp) { + if (is_output_callback_supported() == true) { + AudioOutput_object = callback_object; + AudioOutput_callback = cp; + return true; + } + return false; +} + + long int DSP::SOUND_object_t::get_current_CallbackInstance() { return Current_CallbackInstance; } diff --git a/src/cpp/WMM_support.cpp b/src/cpp/WMM_support.cpp index 75d9842..dbb8067 100644 --- a/src/cpp/WMM_support.cpp +++ b/src/cpp/WMM_support.cpp @@ -159,7 +159,7 @@ bool DSP::WMM_object_t::is_device_recording(void) { return IsRecordingNow; } -long DSP::WMM_object_t::open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_inbuffer_size) { +long DSP::WMM_object_t::open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_inbuffer_size = -1) { if (is_device_input_open) { DSP::log << "DSP::WMM_object_t::open_PCM_device_4_input" << DSP::e::LogMode::second << "Device has been already opened: closing device before reopening" << endl; @@ -252,7 +252,7 @@ long DSP::WMM_object_t::open_PCM_device_4_input(const int &no_of_channels, int n return -1; } -long DSP::WMM_object_t::open_PCM_device_4_output(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size) { +long DSP::WMM_object_t::open_PCM_device_4_output(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size = -1) { if (is_device_output_open) { DSP::log << "DSP::WMM_object_t::open_PCM_device_4_output" << DSP::e::LogMode::second << "Device has been already opened: closing device before reopening" << endl; diff --git a/src/include/ALSA_support.h b/src/include/ALSA_support.h index cf7084b..a6a62a4 100644 --- a/src/include/ALSA_support.h +++ b/src/include/ALSA_support.h @@ -13,7 +13,7 @@ /* All of the ALSA library API is defined in this header */ #include <alsa/asoundlib.h> -#include <DSP_lib.h> // for logging and types +#include <DSP_types.h> // for types namespace DSP { @@ -22,20 +22,48 @@ namespace DSP { snd_pcm_t *alsa_handle; snd_pcm_hw_params_t *hw_params; - public: - - //! log basic ALSA information - void log_driver_data(); - //! open default PCM device and return 1 on success or negative error code /*! stream_type = SND_PCM_STREAM_PLAYBACK or SND_PCM_STREAM_CAPTURE */ int open_alsa_device(snd_pcm_stream_t stream_type, int no_of_channels, unsigned int &sampling_rate); void close_alsa_device(bool do_drain = false, bool use_log = false); - void get_params(snd_pcm_uframes_t &frames, unsigned int &period_time); + void get_period_size(snd_pcm_uframes_t &frames, unsigned int &period_time); snd_pcm_sframes_t pcm_writei(const void *buffer, snd_pcm_uframes_t &frames); + public: + + //! log basic ALSA information + void log_driver_data(); + + unsigned int select_input_device_by_number(const unsigned int &device_number=UINT_MAX); + unsigned int select_output_device_by_number(const unsigned int &device_number=UINT_MAX); + + long open_PCM_device_4_output(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size = -1); + long open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size = -1); + bool close_PCM_device_input(void); + bool close_PCM_device_output(void); + + //! returns true is the playback is on + bool is_device_playing(void); + //! initializes playback stopping + bool stop_playback(void); + //! returns true is the sound capture is on + bool is_device_recording(void); + //! returns true is the sound capture is on + bool stop_recording(void); + + //! \note values stored in float_buffer might be altered + long append_playback_buffer(DSP::Float_vector &float_buffer); + //! Starts sound capture + bool start_recording(void); + + //! Returns false if callbacks are not supported of recording + bool is_input_callback_supported(void); + + //! Returns false if callbacks are not supported of playback + bool is_output_callback_supported(void); + //! object constructor ALSA_object_t(); ~ALSA_object_t(); diff --git a/src/include/DSP_IO.h b/src/include/DSP_IO.h index faf93e2..b084891 100644 --- a/src/include/DSP_IO.h +++ b/src/include/DSP_IO.h @@ -27,7 +27,7 @@ #else #ifdef LINUX //! \TODO adapt for linux - #include "ALSA_support.h" + #include <ALSA_support.h> #else #error NO WIN32 @@ -719,6 +719,11 @@ class DSP::u::AudioInput : public DSP::Source #ifdef WINMMAPI // HWAVEIN hWaveIn; DSP::WMM_object_t snd_object; + #else + #ifdef ALSA_support_H + DSP::ALSA_object_t snd_object; + #else + #endif #endif //! Called by SOUND_object_t when new data buffer is ready @@ -839,6 +844,11 @@ class DSP::u::AudioOutput : public DSP::Block #ifdef WINMMAPI //HWAVEOUT hWaveOut; DSP::WMM_object_t snd_object; + #else + #ifdef ALSA_support_H + DSP::ALSA_object_t snd_object; + #else + #endif #endif // //! Index of the buffer which must be used next time diff --git a/src/include/DSP_lib.h b/src/include/DSP_lib.h index 5b12ff0..0abe1b4 100644 --- a/src/include/DSP_lib.h +++ b/src/include/DSP_lib.h @@ -11,7 +11,7 @@ #define DSP_VER_MAJOR 0 #define DSP_VER_MINOR 20 -#define DSP_VER_BUILD 6 // !!! without zeroes before, else this will be treated as octal number +#define DSP_VER_BUILD 7 // !!! without zeroes before, else this will be treated as octal number #define DSP_VER_YEAR 2021 #define DSP_VER DSP_VER_MAJOR.DSP_VER_MINOR.DSP_VER_BUILD diff --git a/src/include/DSP_types.h b/src/include/DSP_types.h index 76880e7..750f7ea 100644 --- a/src/include/DSP_types.h +++ b/src/include/DSP_types.h @@ -13,6 +13,7 @@ #include <limits.h> #include <vector> #include <string> +#include <functional> using namespace std; //--------------------------------------------------------------------------- @@ -534,15 +535,23 @@ namespace DSP { class AudioOutput; } +// typedef std::function<bool(const DSP::e::SampleType &, const std::vector<char> &)> input_callback_function; + // https://isocpp.org/wiki/faq/pointers-to-members#typedef-for-ptr-to-memfn + //! defining a type for pointer to member funtion of DSP::u::AudioInput + typedef bool(DSP::u::AudioInput::*input_callback_function)(const DSP::e::SampleType &, const std::vector<char> &); + //! defining a type for pointer to member funtion of DSP::u::AudioOutput + typedef bool(DSP::u::AudioOutput::*output_callback_function)(const DSP::e::SampleType &, const std::vector<char> &); + //! Base class for classes implementing sound card support for DSP::u::AudioInput and DSP::u::AudioOutput /*! \TODO convert WMM support in DSP::u::AudioInput and DSP::u::AudioOutput into support through WMM_object_t */ class SOUND_object_t { private: DSP::u::AudioInput * AudioInput_object; - bool (DSP::u::AudioInput::*AudioInput_callback)(const DSP::e::SampleType &InSampleType, const std::vector<char> &wave_in_raw_buffer); + //bool (DSP::u::AudioInput::*AudioInput_callback)(const DSP::e::SampleType &InSampleType, const std::vector<char> &wave_in_raw_buffer); + input_callback_function AudioInput_callback; DSP::u::AudioOutput * AudioOutput_object; - bool (DSP::u::AudioOutput::*AudioOutput_callback)(void); + output_callback_function AudioOutput_callback; //static unsigned long Next_CallbackInstance; unsigned long Current_CallbackInstance; @@ -555,8 +564,8 @@ namespace DSP { virtual unsigned int select_input_device_by_number(const unsigned int &device_number=UINT_MAX) = 0; virtual unsigned int select_output_device_by_number(const unsigned int &device_number=UINT_MAX) = 0; - virtual long open_PCM_device_4_output(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size) = 0; - virtual long open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size) = 0; + virtual long open_PCM_device_4_output(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size = -1) = 0; + virtual long open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size = -1) = 0; virtual bool close_PCM_device_input(void) = 0; virtual bool close_PCM_device_output(void) = 0; @@ -584,8 +593,10 @@ namespace DSP { virtual bool is_input_callback_supported(void) = 0; /*! Returns false if callbacks are not supported * \TODO define when it will be called and what for? + * + * bool register_input_callback_object(DSP::u::AudioInput *callback_object, bool(DSP::u::AudioInput::*cp)(const DSP::e::SampleType &, const std::vector<char> &)); */ - bool register_input_callback_object(DSP::u::AudioInput *callback_object, bool(DSP::u::AudioInput::*cp)(const DSP::e::SampleType &, const std::vector<char> &)); + bool register_input_callback_object(DSP::u::AudioInput *callback_object, input_callback_function &cp); DSP::u::AudioInput *get_input_callback_object(); bool input_callback_call(const DSP::e::SampleType &InSampleType, const std::vector<char> &wave_in_raw_buffer); @@ -595,9 +606,9 @@ namespace DSP { /*! Returns false if callbacks are not supported * \TODO define when it will be called and what for? */ - bool register_output_callback_object(DSP::u::AudioOutput *callback_object, bool(DSP::u::AudioOutput::*cp)()); + bool register_output_callback_object(DSP::u::AudioOutput *callback_object, output_callback_function &cp); DSP::u::AudioOutput *get_output_callback_object(); - bool output_callback_call(); + bool output_callback_call(const DSP::e::SampleType &OutSampleType, const std::vector<char> &wave_out_raw_buffer); SOUND_object_t(); virtual ~SOUND_object_t(); diff --git a/src/include/WMM_support.h b/src/include/WMM_support.h index c16f8c0..1f61d12 100644 --- a/src/include/WMM_support.h +++ b/src/include/WMM_support.h @@ -79,9 +79,9 @@ namespace DSP { unsigned int select_output_device_by_number(const unsigned int &device_number=UINT_MAX); //! opens default PCM device for playback and returns selected sampling rate on success or negative error code - long open_PCM_device_4_output(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size); + long open_PCM_device_4_output(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size = -1); //! opens default PCM device for capture and returns selected sampling rate on success or negative error code - long open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_inbuffer_size); + long open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_inbuffer_size = -1); bool close_PCM_device_input(void); bool close_PCM_device_output(void); -- GitLab