diff options
Diffstat (limited to 'blocklib/audio')
-rw-r--r-- | blocklib/audio/.gitignore | 1 | ||||
-rw-r--r-- | blocklib/audio/alsa_sink/alsa_sink.yml | 49 | ||||
-rw-r--r-- | blocklib/audio/alsa_sink/alsa_sink_cpu.cc | 521 | ||||
-rw-r--r-- | blocklib/audio/alsa_sink/alsa_sink_cpu.h | 68 | ||||
-rw-r--r-- | blocklib/audio/examples/.gitignore | 1 | ||||
-rw-r--r-- | blocklib/audio/examples/alsa_tones.grc | 154 | ||||
-rw-r--r-- | blocklib/audio/include/gnuradio/audio/.gitignore | 1 | ||||
-rw-r--r-- | blocklib/audio/include/gnuradio/audio/meson.build | 3 | ||||
-rw-r--r-- | blocklib/audio/lib/.gitignore | 1 | ||||
-rw-r--r-- | blocklib/audio/lib/alsa_internal.cc | 172 | ||||
-rw-r--r-- | blocklib/audio/lib/alsa_internal.h | 89 | ||||
-rw-r--r-- | blocklib/audio/lib/meson.build | 42 | ||||
-rw-r--r-- | blocklib/audio/python/gnuradio/audio/.gitignore | 1 | ||||
-rw-r--r-- | blocklib/audio/python/gnuradio/audio/__init__.py | 9 | ||||
-rw-r--r-- | blocklib/audio/test/.gitignore | 1 | ||||
-rw-r--r-- | blocklib/audio/test/meson.build | 3 |
16 files changed, 0 insertions, 1116 deletions
diff --git a/blocklib/audio/.gitignore b/blocklib/audio/.gitignore deleted file mode 100644 index 25d053a52..000000000 --- a/blocklib/audio/.gitignore +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/blocklib/audio/alsa_sink/alsa_sink.yml b/blocklib/audio/alsa_sink/alsa_sink.yml deleted file mode 100644 index 009b0c9b1..000000000 --- a/blocklib/audio/alsa_sink/alsa_sink.yml +++ /dev/null @@ -1,49 +0,0 @@ -module: audio -block: alsa_sink -label: ALSA Sink -blocktype: sync_block -category: '[Core]/Audio' - -# Example Parameters -parameters: -- id: sampling_rate - label: Sampling Rate - dtype: ru32 - settable: false - default: 0 - grc: - hide: part -- id: device_name - label: Device Name - dtype: string - settable: false - grc: - hide: part -- id: num_inputs - label: Num Inputs - dtype: size - settable: false - default: 1 - grc: - hide: part -- id: ok_to_block - label: OK to Block - dtype: bool - settable: false - default: 'true' - grc: - hide: part - -# Example Ports -ports: -- domain: stream - id: in - direction: input - type: rf32 - multiplicity: parameters/num_inputs - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/audio/alsa_sink/alsa_sink_cpu.cc b/blocklib/audio/alsa_sink/alsa_sink_cpu.cc deleted file mode 100644 index e396c4e0e..000000000 --- a/blocklib/audio/alsa_sink/alsa_sink_cpu.cc +++ /dev/null @@ -1,521 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "alsa_sink_cpu.h" -#include "alsa_sink_cpu_gen.h" - -#include <chrono> -#include <future> -#include <thread> - -#include <gnuradio/prefs.h> - -namespace gr { -namespace audio { - - -static bool CHATTY_DEBUG = true; - -static snd_pcm_format_t acceptable_formats[] = { - // these are in our preferred order... - SND_PCM_FORMAT_S32, - SND_PCM_FORMAT_S16 -}; - -#define NELEMS(x) (sizeof(x) / sizeof(x[0])) - -static std::string default_device_name() -{ - return prefs::get_string("audio_alsa", "default_output_device", "default"); -} - -static double default_period_time() -{ - return std::max(0.001, prefs::get_double("audio_alsa", "period_time", 0.010)); -} - -static int default_nperiods() -{ - return std::max(2L, prefs::get_long("audio_alsa", "nperiods", 32)); -} - - -alsa_sink_cpu::alsa_sink_cpu(block_args args) - : INHERITED_CONSTRUCTORS, - d_sampling_rate(args.sampling_rate), - d_device_name(args.device_name.empty() ? default_device_name() : args.device_name), - d_nperiods(default_nperiods()), - d_period_time_us((size_t)(default_period_time() * 1e6)), - d_special_case_mono_to_stereo(false), - d_ok_to_block(args.ok_to_block), - d_num_inputs(args.num_inputs) -{ - CHATTY_DEBUG = prefs::get_bool("audio_alsa", "verbose", false); - - int error = -1; - int dir; - - // open the device for playback - int attempts = 10; - while ((error != 0) && (attempts-- > 0)) { - snd_pcm_t* t = nullptr; - error = snd_pcm_open(&t, d_device_name.c_str(), SND_PCM_STREAM_PLAYBACK, 0); - d_pcm_handle.set(t); - if (error < 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - } - if (args.ok_to_block == false) - snd_pcm_nonblock(d_pcm_handle.get(), 1); - if (error < 0) { - d_logger->error("[{:s}]: {:s}", d_device_name, snd_strerror(error)); - throw std::runtime_error("audio_alsa_sink"); - } - - // Fill params with a full configuration space for a PCM. - error = snd_pcm_hw_params_any(d_pcm_handle.get(), d_hw_params.get()); - if (error < 0) - bail("broken configuration for playback", error); - - if (CHATTY_DEBUG) - gri_alsa_dump_hw_params(d_pcm_handle.get(), d_hw_params.get(), stdout); - - // now that we know how many channels the h/w can handle, set input signature - unsigned int umin_chan, umax_chan; - snd_pcm_hw_params_get_channels_min(d_hw_params.get(), &umin_chan); - snd_pcm_hw_params_get_channels_max(d_hw_params.get(), &umax_chan); - unsigned int min_chan = std::min(umin_chan, 1000U); - unsigned int max_chan = std::min(umax_chan, 1000U); - - // As a special case, if the hw's min_chan is two, we'll accept - // a single input and handle the duplication ourselves. - if (min_chan == 2) { - min_chan = 1; - d_special_case_mono_to_stereo = true; - } - - if (args.num_inputs < min_chan) { - throw std::runtime_error(fmt::format( - "Detected hardware requires at least {} input channels", min_chan)); - } - if (args.num_inputs > max_chan) { - throw std::runtime_error(fmt::format( - "Detected hardware supports no more than {} input channels", max_chan)); - } - // fill in portions of the d_hw_params that we know now... - - // Specify the access methods we implement - // For now, we only handle RW_INTERLEAVED... - snd_pcm_access_mask_t* access_mask; - snd_pcm_access_mask_t** access_mask_ptr = - &access_mask; // FIXME: workaround for compiler warning - snd_pcm_access_mask_alloca(access_mask_ptr); - snd_pcm_access_mask_none(access_mask); - snd_pcm_access_mask_set(access_mask, SND_PCM_ACCESS_RW_INTERLEAVED); - // snd_pcm_access_mask_set(access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED); - - if ((error = snd_pcm_hw_params_set_access_mask( - d_pcm_handle.get(), d_hw_params.get(), access_mask)) < 0) - bail("failed to set access mask", error); - - // set sample format - if (!gri_alsa_pick_acceptable_format(d_pcm_handle.get(), - d_hw_params.get(), - acceptable_formats, - NELEMS(acceptable_formats), - &d_format, - "audio_alsa_sink", - CHATTY_DEBUG)) - throw std::runtime_error("audio_alsa_sink"); - - // sampling rate - unsigned int orig_sampling_rate = d_sampling_rate; - if ((error = snd_pcm_hw_params_set_rate_near( - d_pcm_handle.get(), d_hw_params.get(), &d_sampling_rate, 0)) < 0) - bail("failed to set rate near", error); - - if (orig_sampling_rate != d_sampling_rate) { - d_logger->info("[{:s}]: unable to support sampling rate {:d}\n\tCard " - "requested {:d} instead.", - snd_pcm_name(d_pcm_handle.get()), - orig_sampling_rate, - d_sampling_rate); - } - - /* - * ALSA transfers data in units of "periods". - * We indirectly determine the underlying buffersize by specifying - * the number of periods we want (typically 4) and the length of each - * period in units of time (typically 1ms). - */ - unsigned int min_nperiods, max_nperiods; - snd_pcm_hw_params_get_periods_min(d_hw_params.get(), &min_nperiods, &dir); - snd_pcm_hw_params_get_periods_max(d_hw_params.get(), &max_nperiods, &dir); - - unsigned int orig_nperiods = d_nperiods; - d_nperiods = std::min(std::max(min_nperiods, d_nperiods), max_nperiods); - - // adjust period time so that total buffering remains more-or-less constant - d_period_time_us = (d_period_time_us * orig_nperiods) / d_nperiods; - - error = snd_pcm_hw_params_set_periods( - d_pcm_handle.get(), d_hw_params.get(), d_nperiods, 0); - if (error < 0) - bail("set_periods failed", error); - - dir = 0; - error = snd_pcm_hw_params_set_period_time_near( - d_pcm_handle.get(), d_hw_params.get(), &d_period_time_us, &dir); - if (error < 0) - bail("set_period_time_near failed", error); - - dir = 0; - error = snd_pcm_hw_params_get_period_size(d_hw_params.get(), &d_period_size, &dir); - if (error < 0) - bail("get_period_size failed", error); - - set_output_multiple(d_period_size); -} - -bool alsa_sink_cpu::start() -{ - int nchan = d_num_inputs; - int err; - - // Check the state of the stream - // Ensure that the pcm is in a state where we can still mess with the hw_params - snd_pcm_state_t state; - state = snd_pcm_state(d_pcm_handle.get()); - if (state == SND_PCM_STATE_RUNNING) - return true; // If stream is running, don't change any parameters - else if (state == SND_PCM_STATE_XRUN) - snd_pcm_prepare( - d_pcm_handle.get()); // Prepare stream on underrun, and we can set parameters; - - bool special_case = nchan == 1 && d_special_case_mono_to_stereo; - if (special_case) - nchan = 2; - - err = snd_pcm_hw_params_set_channels(d_pcm_handle.get(), d_hw_params.get(), nchan); - - if (err < 0) { - output_error_msg("set_channels failed", err); - return false; - } - - // set the parameters into the driver... - err = snd_pcm_hw_params(d_pcm_handle.get(), d_hw_params.get()); - if (err < 0) { - output_error_msg("snd_pcm_hw_params failed", err); - return false; - } - - // get current s/w params - err = snd_pcm_sw_params_current(d_pcm_handle.get(), d_sw_params.get()); - if (err < 0) - bail("snd_pcm_sw_params_current", err); - - // Tell the PCM device to wait to start until we've filled - // it's buffers half way full. This helps avoid audio underruns. - - err = snd_pcm_sw_params_set_start_threshold( - d_pcm_handle.get(), d_sw_params.get(), d_nperiods * d_period_size / 2); - if (err < 0) - bail("snd_pcm_sw_params_set_start_threshold", err); - - // store the s/w params - err = snd_pcm_sw_params(d_pcm_handle.get(), d_sw_params.get()); - if (err < 0) - bail("snd_pcm_sw_params", err); - - d_buffer.resize(d_period_size * nchan * snd_pcm_format_size(d_format, 1)); - - if (CHATTY_DEBUG) { - d_debug_logger->debug("[{:s}]: sample resolution = {:d} bits", - snd_pcm_name(d_pcm_handle.get()), - snd_pcm_hw_params_get_sbits(d_hw_params.get())); - } - - switch (d_format) { - case SND_PCM_FORMAT_S16: - if (special_case) { - d_worker = [this](work_io& wio) { return this->work_s16_1x2(wio); }; - } - else { - d_worker = [this](work_io& wio) { return this->work_s16(wio); }; - } - break; - - case SND_PCM_FORMAT_S32: - if (special_case) { - d_worker = [this](work_io& wio) { return this->work_s32_1x2(wio); }; - } - else { - d_worker = [this](work_io& wio) { return this->work_s32(wio); }; - } - break; - - default: - throw std::runtime_error("Unsupported PCM format returned from ALSA"); - } - - return true; -} - -work_return_t alsa_sink_cpu::work(work_io& wio) - -{ - // assert((noutput_items % d_period_size) == 0); - - // this is a call through std::function - return d_worker(wio); -} - - -/* - * Work function that deals with float to S16 conversion - */ -work_return_t alsa_sink_cpu::work_s16(work_io& wio) -{ - typedef int16_t sample_t; // the type of samples we're creating - static const float scale_factor = std::pow(2.0f, 16 - 1) - 1; - - size_t nchan = wio.inputs().size(); - auto noutput_items = wio.min_ninput_items(); - std::vector<const float*> in_ptrs(nchan); - for (size_t i = 0; i < wio.inputs().size(); i++) { - in_ptrs[i] = wio.inputs()[i].items<float>(); - } - auto in = in_ptrs.data(); - sample_t* buf = reinterpret_cast<sample_t*>(d_buffer.data()); - int bi; - size_t n; - - size_t sizeof_frame = nchan * sizeof(sample_t); - assert(d_buffer.size() == d_period_size * sizeof_frame); - - for (n = 0; n < noutput_items; n += d_period_size) { - // process one period of data - bi = 0; - for (size_t i = 0; i < d_period_size; i++) { - for (size_t chan = 0; chan < nchan; chan++) { - buf[bi++] = (sample_t)(in[chan][i] * scale_factor); - } - } - - // update src pointers - for (size_t chan = 0; chan < nchan; chan++) - in[chan] += d_period_size; - - if (!write_buffer(buf, d_period_size, sizeof_frame)) - return work_return_t::DONE; // No fixing this problem. Say - // we're done. - } - - wio.consume_each(n); - return work_return_t::OK; -} - -/* - * Work function that deals with float to S32 conversion - */ -work_return_t alsa_sink_cpu::work_s32(work_io& wio) -{ - typedef int32_t sample_t; // the type of samples we're creating - static const float scale_factor = std::pow(2.0f, 32 - 1) - 1; - - size_t nchan = wio.inputs().size(); - auto noutput_items = wio.min_ninput_items(); - std::vector<const float*> in_ptrs(nchan); - for (size_t i = 0; i < wio.inputs().size(); i++) { - in_ptrs[i] = wio.inputs()[i].items<float>(); - } - auto in = in_ptrs.data(); - sample_t* buf = reinterpret_cast<sample_t*>(d_buffer.data()); - int bi; - size_t n; - - size_t sizeof_frame = nchan * sizeof(sample_t); - assert(d_buffer.size() == d_period_size * sizeof_frame); - - for (n = 0; n < noutput_items; n += d_period_size) { - // process one period of data - bi = 0; - for (size_t i = 0; i < d_period_size; i++) { - for (size_t chan = 0; chan < nchan; chan++) { - buf[bi++] = (sample_t)(in[chan][i] * scale_factor); - } - } - - // update src pointers - for (size_t chan = 0; chan < nchan; chan++) - in[chan] += d_period_size; - - if (!write_buffer(buf, d_period_size, sizeof_frame)) - return work_return_t::DONE; // No fixing this problem. Say - // we're done. - } - - wio.consume_each(n); - return work_return_t::OK; -} - -/* - * Work function that deals with float to S16 conversion and - * mono to stereo kludge. - */ -work_return_t alsa_sink_cpu::work_s16_1x2(work_io& wio) -{ - typedef int16_t sample_t; // the type of samples we're creating - static const float scale_factor = std::pow(2.0f, 16 - 1) - 1; - - assert(wio.inputs().size() == 1); - static const size_t nchan = 2; - auto noutput_items = wio.min_ninput_items(); - std::vector<const float*> in_ptrs(nchan); - for (size_t i = 0; i < wio.inputs().size(); i++) { - in_ptrs[i] = wio.inputs()[i].items<float>(); - } - auto in = in_ptrs.data(); - sample_t* buf = reinterpret_cast<sample_t*>(d_buffer.data()); - int bi; - size_t n; - - size_t sizeof_frame = nchan * sizeof(sample_t); - assert(d_buffer.size() == d_period_size * sizeof_frame); - - for (n = 0; n < noutput_items; n += d_period_size) { - // process one period of data - bi = 0; - for (size_t i = 0; i < d_period_size; i++) { - sample_t t = (sample_t)(in[0][i] * scale_factor); - buf[bi++] = t; - buf[bi++] = t; - } - - // update src pointers - in[0] += d_period_size; - - if (!write_buffer(buf, d_period_size, sizeof_frame)) - return work_return_t::DONE; // No fixing this problem. Say - // we're done. - } - - wio.consume_each(n); - return work_return_t::OK; -} - -/* - * Work function that deals with float to S32 conversion and - * mono to stereo kludge. - */ -work_return_t alsa_sink_cpu::work_s32_1x2(work_io& wio) -{ - typedef int32_t sample_t; // the type of samples we're creating - static const float scale_factor = std::pow(2.0f, 32 - 1) - 1; - - static size_t nchan = 2; - auto noutput_items = wio.min_ninput_items(); - std::vector<const float*> in_ptrs(nchan); - for (size_t i = 0; i < wio.inputs().size(); i++) { - in_ptrs[i] = wio.inputs()[i].items<float>(); - } - auto in = in_ptrs.data(); - sample_t* buf = reinterpret_cast<sample_t*>(d_buffer.data()); - int bi; - size_t n; - - size_t sizeof_frame = nchan * sizeof(sample_t); - assert(d_buffer.size() == d_period_size * sizeof_frame); - - for (n = 0; n < noutput_items; n += d_period_size) { - // process one period of data - bi = 0; - for (size_t i = 0; i < d_period_size; i++) { - sample_t t = (sample_t)(in[0][i] * scale_factor); - buf[bi++] = t; - buf[bi++] = t; - } - - // update src pointers - in[0] += d_period_size; - - if (!write_buffer(buf, d_period_size, sizeof_frame)) - return work_return_t::DONE; // No fixing this problem. Say - // we're done. - } - - wio.consume_each(n); - return work_return_t::OK; -} - -bool alsa_sink_cpu::write_buffer(const void* vbuffer, - unsigned nframes, - unsigned sizeof_frame) -{ - const unsigned char* buffer = (const unsigned char*)vbuffer; - - while (nframes > 0) { - int r = snd_pcm_writei(d_pcm_handle.get(), buffer, nframes); - if (r == -EAGAIN) { - if (d_ok_to_block == true) - continue; // try again - break; - } - else if (r == -EPIPE) { // underrun - d_nunderuns++; - // we need to have an lvalue, async pitfall! - auto future_local = std::async(::fputs, "aU", stderr); - - if ((r = snd_pcm_prepare(d_pcm_handle.get())) < 0) { - output_error_msg("snd_pcm_prepare failed. Can't recover from underrun", - r); - return false; - } - continue; // try again - } -#ifdef ESTRPIPE - else if (r == -ESTRPIPE) { // h/w is suspended (whatever that means) - // This is apparently related to power management - d_nsuspends++; - if ((r = snd_pcm_resume(d_pcm_handle.get())) < 0) { - output_error_msg("failed to resume from suspend", r); - return false; - } - continue; // try again - } -#endif - else if (r < 0) { - output_error_msg("snd_pcm_writei failed", r); - return false; - } - - nframes -= r; - buffer += r * sizeof_frame; - } - - return true; -} - -void alsa_sink_cpu::output_error_msg(const char* msg, int err) -{ - d_logger->error( - "[{:s}]: {:s}: {:s}", snd_pcm_name(d_pcm_handle.get()), msg, snd_strerror(err)); -} - -void alsa_sink_cpu::bail(const char* msg, int err) -{ - output_error_msg(msg, err); - throw std::runtime_error("audio_alsa_sink"); -} - - -} // namespace audio -} // namespace gr
\ No newline at end of file diff --git a/blocklib/audio/alsa_sink/alsa_sink_cpu.h b/blocklib/audio/alsa_sink/alsa_sink_cpu.h deleted file mode 100644 index fdbd13325..000000000 --- a/blocklib/audio/alsa_sink/alsa_sink_cpu.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include "../lib/alsa_internal.h" -#include <gnuradio/audio/alsa_sink.h> - -#include <functional> - -namespace gr { -namespace audio { - -class alsa_sink_cpu : public virtual alsa_sink -{ -public: - alsa_sink_cpu(block_args args); - work_return_t work(work_io&) override; - -private: - // TODO: change to std::function - - - unsigned int d_sampling_rate; - std::string d_device_name; - alsa_internal::sndpcm_wrap d_pcm_handle; - alsa_internal::hwparam_wrap d_hw_params; - alsa_internal::swparam_wrap d_sw_params; - snd_pcm_format_t d_format; - unsigned int d_nperiods; - unsigned int d_period_time_us; // microseconds - snd_pcm_uframes_t d_period_size = 0; // in frames - std::vector<char> d_buffer; - work_t d_worker = nullptr; // the work method to use - bool d_special_case_mono_to_stereo; - - // random stats - int d_nunderuns = 0; // count of underruns - int d_nsuspends = 0; // count of suspends - bool d_ok_to_block; // defaults to "true", controls blocking/non-block I/O - size_t d_num_inputs; - - void output_error_msg(const char* msg, int err); - void bail(const char* msg, int err); - - bool start() override; - -protected: - bool write_buffer(const void* buffer, unsigned nframes, unsigned sizeof_frame); - - work_return_t work_s16(work_io& wio); - - work_return_t work_s16_1x2(work_io& wio); - - work_return_t work_s32(work_io& wio); - - work_return_t work_s32_1x2(work_io& wio); -}; - -} // namespace audio -} // namespace gr
\ No newline at end of file diff --git a/blocklib/audio/examples/.gitignore b/blocklib/audio/examples/.gitignore deleted file mode 100644 index f104652b6..000000000 --- a/blocklib/audio/examples/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.py diff --git a/blocklib/audio/examples/alsa_tones.grc b/blocklib/audio/examples/alsa_tones.grc deleted file mode 100644 index 6d319df9e..000000000 --- a/blocklib/audio/examples/alsa_tones.grc +++ /dev/null @@ -1,154 +0,0 @@ -options: - parameters: - author: josh - catch_exceptions: 'True' - category: '[GRC Hier Blocks]' - cmake_opt: '' - comment: '' - copyright: '' - description: '' - gen_cmake: 'On' - gen_linking: dynamic - generate_options: qt_gui - hier_block_src_path: '.:' - id: alsa_tones - max_nouts: '0' - output_language: python - placement: (0,0) - qt_qss_theme: '' - realtime_scheduling: '' - run: 'True' - run_command: '{python} -u {filename}' - run_options: prompt - sizing_mode: fixed - thread_safe_setters: '' - title: Not titled yet - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [8, 8] - rotation: 0 - state: enabled - -blocks: -- name: samp_rate - id: variable - parameters: - comment: '' - value: '32000' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [184, 12] - rotation: 0 - state: enabled -- name: analog_sig_source_0 - id: analog_sig_source - parameters: - T: float - affinity: '' - alias: '' - ampl: '0.25' - comment: '' - domain: cpu - frequency: '440' - maxoutbuf: '0' - minoutbuf: '0' - offset: '0' - phase: '0' - sampling_freq: samp_rate - showports: 'False' - waveform: analog.waveform_t.COS - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [344, 324.0] - rotation: 0 - state: enabled -- name: analog_sig_source_0_0 - id: analog_sig_source - parameters: - T: float - affinity: '' - alias: '' - ampl: '0.25' - comment: '' - domain: cpu - frequency: '554.4' - maxoutbuf: '0' - minoutbuf: '0' - offset: '0' - phase: '0' - sampling_freq: samp_rate - showports: 'False' - waveform: analog.waveform_t.COS - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [336, 132.0] - rotation: 0 - state: true -- name: audio_alsa_sink_0 - id: audio_alsa_sink - parameters: - affinity: '' - alias: '' - comment: '' - device_name: '"pulse"' - domain: cpu - num_inputs: '1' - ok_to_block: 'True' - sampling_rate: samp_rate - showports: 'False' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [872, 292.0] - rotation: 0 - state: true -- name: import_0 - id: import - parameters: - alias: '' - comment: '' - imports: from gnuradio import analog - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [296, 12.0] - rotation: 0 - state: true -- name: math_add_0 - id: math_add - parameters: - T: float - affinity: '' - alias: '' - comment: '' - domain: cpu - maxoutbuf: '0' - minoutbuf: '0' - nports: '2' - showports: 'False' - vlen: '1' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [664, 304.0] - rotation: 0 - state: enabled - -connections: -- [analog_sig_source_0, '0', math_add_0, '1'] -- [analog_sig_source_0_0, '0', math_add_0, '0'] -- [math_add_0, '0', audio_alsa_sink_0, '0'] - -metadata: - file_format: 1 diff --git a/blocklib/audio/include/gnuradio/audio/.gitignore b/blocklib/audio/include/gnuradio/audio/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/audio/include/gnuradio/audio/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/audio/include/gnuradio/audio/meson.build b/blocklib/audio/include/gnuradio/audio/meson.build deleted file mode 100644 index 80941fc75..000000000 --- a/blocklib/audio/include/gnuradio/audio/meson.build +++ /dev/null @@ -1,3 +0,0 @@ -headers = [] - -install_headers(headers, subdir : 'gnuradio/audio')
\ No newline at end of file diff --git a/blocklib/audio/lib/.gitignore b/blocklib/audio/lib/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/audio/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/audio/lib/alsa_internal.cc b/blocklib/audio/lib/alsa_internal.cc deleted file mode 100644 index 793d0d0fe..000000000 --- a/blocklib/audio/lib/alsa_internal.cc +++ /dev/null @@ -1,172 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#ifdef HAVE_CONFIG_H -#warning "ALSA CONFIG H" -#include "config.h" -#endif - -#include <gnuradio/logger.h> - -#include "alsa_internal.h" - -#include <algorithm> - -static snd_pcm_access_t access_types[] = { SND_PCM_ACCESS_MMAP_INTERLEAVED, - SND_PCM_ACCESS_MMAP_NONINTERLEAVED, - SND_PCM_ACCESS_MMAP_COMPLEX, - SND_PCM_ACCESS_RW_INTERLEAVED, - SND_PCM_ACCESS_RW_NONINTERLEAVED }; - -static snd_pcm_format_t format_types[] = { - // SND_PCM_FORMAT_UNKNOWN, - SND_PCM_FORMAT_S8, - SND_PCM_FORMAT_U8, - SND_PCM_FORMAT_S16_LE, - SND_PCM_FORMAT_S16_BE, - SND_PCM_FORMAT_U16_LE, - SND_PCM_FORMAT_U16_BE, - SND_PCM_FORMAT_S24_LE, - SND_PCM_FORMAT_S24_BE, - SND_PCM_FORMAT_U24_LE, - SND_PCM_FORMAT_U24_BE, - SND_PCM_FORMAT_S32_LE, - SND_PCM_FORMAT_S32_BE, - SND_PCM_FORMAT_U32_LE, - SND_PCM_FORMAT_U32_BE, - SND_PCM_FORMAT_FLOAT_LE, - SND_PCM_FORMAT_FLOAT_BE, - SND_PCM_FORMAT_FLOAT64_LE, - SND_PCM_FORMAT_FLOAT64_BE, - SND_PCM_FORMAT_IEC958_SUBFRAME_LE, - SND_PCM_FORMAT_IEC958_SUBFRAME_BE, - SND_PCM_FORMAT_MU_LAW, - SND_PCM_FORMAT_A_LAW, - SND_PCM_FORMAT_IMA_ADPCM, - SND_PCM_FORMAT_MPEG, - SND_PCM_FORMAT_GSM, - SND_PCM_FORMAT_SPECIAL, - SND_PCM_FORMAT_S24_3LE, - SND_PCM_FORMAT_S24_3BE, - SND_PCM_FORMAT_U24_3LE, - SND_PCM_FORMAT_U24_3BE, - SND_PCM_FORMAT_S20_3LE, - SND_PCM_FORMAT_S20_3BE, - SND_PCM_FORMAT_U20_3LE, - SND_PCM_FORMAT_U20_3BE, - SND_PCM_FORMAT_S18_3LE, - SND_PCM_FORMAT_S18_3BE, - SND_PCM_FORMAT_U18_3LE, - SND_PCM_FORMAT_U18_3BE -}; - -static unsigned int test_rates[] = { 8000, 16000, 22050, 32000, - 44100, 48000, 96000, 192000 }; - -#define NELEMS(x) (sizeof(x) / sizeof(x[0])) - -void gri_alsa_dump_hw_params(snd_pcm_t* pcm, snd_pcm_hw_params_t* hwparams, FILE* fp) -{ - fprintf(fp, "PCM name: %s\n", snd_pcm_name(pcm)); - - fprintf(fp, "Access types:\n"); - for (unsigned i = 0; i < NELEMS(access_types); i++) { - snd_pcm_access_t at = access_types[i]; - fprintf(fp, - " %-20s %s\n", - snd_pcm_access_name(at), - snd_pcm_hw_params_test_access(pcm, hwparams, at) == 0 ? "YES" : "NO"); - } - - fprintf(fp, "Formats:\n"); - for (unsigned i = 0; i < NELEMS(format_types); i++) { - snd_pcm_format_t ft = format_types[i]; - if (0) - fprintf(fp, - " %-20s %s\n", - snd_pcm_format_name(ft), - snd_pcm_hw_params_test_format(pcm, hwparams, ft) == 0 ? "YES" : "NO"); - else { - if (snd_pcm_hw_params_test_format(pcm, hwparams, ft) == 0) - fprintf(fp, " %-20s YES\n", snd_pcm_format_name(ft)); - } - } - - fprintf(fp, "Number of channels\n"); - unsigned int min_chan, max_chan; - snd_pcm_hw_params_get_channels_min(hwparams, &min_chan); - snd_pcm_hw_params_get_channels_max(hwparams, &max_chan); - fprintf(fp, " min channels: %d\n", min_chan); - fprintf(fp, " max channels: %d\n", max_chan); - unsigned int chan; - max_chan = std::min(max_chan, 16U); // truncate display... - for (chan = min_chan; chan <= max_chan; chan++) { - fprintf(fp, - " %d channels\t%s\n", - chan, - snd_pcm_hw_params_test_channels(pcm, hwparams, chan) == 0 ? "YES" : "NO"); - } - - fprintf(fp, "Sample Rates:\n"); - unsigned int min_rate, max_rate; - int min_dir, max_dir; - - snd_pcm_hw_params_get_rate_min(hwparams, &min_rate, &min_dir); - snd_pcm_hw_params_get_rate_max(hwparams, &max_rate, &max_dir); - fprintf(fp, " min rate: %7d (dir = %d)\n", min_rate, min_dir); - fprintf(fp, " max rate: %7d (dir = %d)\n", max_rate, max_dir); - for (unsigned i = 0; i < NELEMS(test_rates); i++) { - unsigned int rate = test_rates[i]; - fprintf(fp, - " %6u %s\n", - rate, - snd_pcm_hw_params_test_rate(pcm, hwparams, rate, 0) == 0 ? "YES" : "NO"); - } - - fflush(fp); -} - -bool gri_alsa_pick_acceptable_format(snd_pcm_t* pcm, - snd_pcm_hw_params_t* hwparams, - snd_pcm_format_t acceptable_formats[], - unsigned nacceptable_formats, - snd_pcm_format_t* selected_format, - const char* error_msg_tag, - bool verbose) -{ - int err; - gr::logger_ptr logger, debug_logger; - gr::configure_default_loggers( - logger, debug_logger, "gri_alsa_pick_acceptable_format"); - - // pick a format that we like... - for (unsigned i = 0; i < nacceptable_formats; i++) { - if (snd_pcm_hw_params_test_format(pcm, hwparams, acceptable_formats[i]) == 0) { - err = snd_pcm_hw_params_set_format(pcm, hwparams, acceptable_formats[i]); - if (err < 0) { - logger->error("{:s}[{:s}]: failed to set format: {:s}", - error_msg_tag, - snd_pcm_name(pcm), - snd_strerror(err)); - return false; - } - debug_logger->info("{:s}[{:s}]: using {:s}", - error_msg_tag, - snd_pcm_name(pcm), - snd_pcm_format_name(acceptable_formats[i])); - *selected_format = acceptable_formats[i]; - return true; - } - } - - logger->error( - "{:s}[{:s}]: failed to find acceptable format", error_msg_tag, snd_pcm_name(pcm)); - return false; -} diff --git a/blocklib/audio/lib/alsa_internal.h b/blocklib/audio/lib/alsa_internal.h deleted file mode 100644 index 0147cb1b6..000000000 --- a/blocklib/audio/lib/alsa_internal.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <alsa/asoundlib.h> -#include <cstdio> -#include <stdexcept> - -void gri_alsa_dump_hw_params(snd_pcm_t* pcm, snd_pcm_hw_params_t* hwparams, FILE* fp); - -bool gri_alsa_pick_acceptable_format(snd_pcm_t* pcm, - snd_pcm_hw_params_t* hwparams, - snd_pcm_format_t acceptable_formats[], - unsigned nacceptable_formats, - snd_pcm_format_t* selected_format, - const char* error_msg_tag, - bool verbose); - -namespace gr { -namespace audio { -namespace alsa_internal { -// hw/sw params RAII wrapper. -template <typename T, int Alloc(T**), void Free(T*)> -class param_wrap -{ -public: - param_wrap() - { - const int err = Alloc(&d_param); - if (err) { - throw std::runtime_error("failed to allocate ALSA params. Error code " + - std::to_string(err)); - } - } - param_wrap(const param_wrap&) = delete; - param_wrap& operator=(const param_wrap&) = delete; - T* get() { return d_param; } - ~param_wrap() { Free(d_param); } - -private: - T* d_param = nullptr; -}; -typedef param_wrap<snd_pcm_hw_params_t, snd_pcm_hw_params_malloc, snd_pcm_hw_params_free> - hwparam_wrap; -typedef param_wrap<snd_pcm_sw_params_t, snd_pcm_sw_params_malloc, snd_pcm_sw_params_free> - swparam_wrap; - -class sndpcm_wrap -{ -public: - sndpcm_wrap(snd_pcm_t* in = nullptr) : d_pcm_handle(in) {} - sndpcm_wrap(const sndpcm_wrap&) = delete; - sndpcm_wrap(sndpcm_wrap&&) = delete; - sndpcm_wrap& operator=(const sndpcm_wrap&) = delete; - sndpcm_wrap& operator=(sndpcm_wrap&&) = delete; - ~sndpcm_wrap() { close(); } - void close() - { - if (d_pcm_handle == nullptr) { - return; - } - if (snd_pcm_state(d_pcm_handle) == SND_PCM_STATE_RUNNING) { - snd_pcm_drop(d_pcm_handle); - } - snd_pcm_close(d_pcm_handle); - d_pcm_handle = nullptr; - } - void set(snd_pcm_t* ptr) - { - close(); - d_pcm_handle = ptr; - } - snd_pcm_t* get() noexcept { return d_pcm_handle; } - -private: - snd_pcm_t* d_pcm_handle; -}; - -} // namespace alsa_internal -} // namespace audio -} // namespace gr diff --git a/blocklib/audio/lib/meson.build b/blocklib/audio/lib/meson.build deleted file mode 100644 index d0530e463..000000000 --- a/blocklib/audio/lib/meson.build +++ /dev/null @@ -1,42 +0,0 @@ -audio_sources += [ - 'alsa_internal.cc' -] - -alsa_dep = dependency('alsa', required: true) - -audio_deps += [gnuradio_gr_dep, volk_dep, fmt_dep, pmtf_dep, alsa_dep] - -block_cpp_args = ['-DHAVE_CPU'] - -incdir = include_directories(['../include/gnuradio/audio','../include']) -gnuradio_blocklib_audio_lib = library('gnuradio-blocklib-audio', - audio_sources, - include_directories : incdir, - install : true, - link_language: 'cpp', - dependencies : audio_deps, - cpp_args : block_cpp_args) - -gnuradio_blocklib_audio_dep = declare_dependency(include_directories : incdir, - link_with : gnuradio_blocklib_audio_lib, - dependencies : audio_deps) - -cmake_conf = configuration_data() -cmake_conf.set('libdir', join_paths(prefix,get_option('libdir'))) -cmake_conf.set('module', 'audio') -cmake.configure_package_config_file( - name : 'gnuradio-audio', - input : join_paths(meson.source_root(),'cmake','Modules','gnuradioConfigModule.cmake.in'), - install_dir : get_option('prefix') / get_option('libdir') / 'cmake' / 'gnuradio', - configuration : cmake_conf -) - -pkg = import('pkgconfig') -libs = [gnuradio_blocklib_audio_lib] # the library/libraries users need to link against -h = ['.'] # subdirectories of ${prefix}/${includedir} to add to header path -pkg.generate(libraries : libs, - subdirs : h, - version : meson.project_version(), - name : 'libgnuradio-audio', - filebase : 'gnuradio-audio', - description : 'GNU Radio Audio Module') diff --git a/blocklib/audio/python/gnuradio/audio/.gitignore b/blocklib/audio/python/gnuradio/audio/.gitignore deleted file mode 100644 index 25d053a52..000000000 --- a/blocklib/audio/python/gnuradio/audio/.gitignore +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/blocklib/audio/python/gnuradio/audio/__init__.py b/blocklib/audio/python/gnuradio/audio/__init__.py deleted file mode 100644 index e87741f28..000000000 --- a/blocklib/audio/python/gnuradio/audio/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ - -import os - -try: - from .audio_python import * -except ImportError: - dirname, filename = os.path.split(os.path.abspath(__file__)) - __path__.append(os.path.join(dirname, "bindings")) - from .audio_python import * diff --git a/blocklib/audio/test/.gitignore b/blocklib/audio/test/.gitignore deleted file mode 100644 index d53050d7d..000000000 --- a/blocklib/audio/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build diff --git a/blocklib/audio/test/meson.build b/blocklib/audio/test/meson.build deleted file mode 100644 index a3efa7246..000000000 --- a/blocklib/audio/test/meson.build +++ /dev/null @@ -1,3 +0,0 @@ -################################################### -# QA -################################################### |