Skip to content

Commit

Permalink
Rename "Sampling" to more common "Rate" term
Browse files Browse the repository at this point in the history
In audio processing software the sampling frequency of recorded audio
is mostly named as sample rate or simply "rate". On the other hand the
sampling frequency is more scientific term. Since bluez-alsa is audio
processing software, the term "rate" should fit better here. Also, it
will align with ALSA nomenclature.
  • Loading branch information
arkq committed Sep 14, 2024
1 parent e3c3184 commit 04e8277
Show file tree
Hide file tree
Showing 47 changed files with 540 additions and 531 deletions.
4 changes: 2 additions & 2 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ bluez-alsa v4.3.1 (2024-08-30)
==============================

- fix crash when playing audio with more than 2 channels
- fix AAC configuration selection for low sampling rates
- fix AAC configuration selection for low sample rates

bluez-alsa v4.3.0 (2024-08-13)
==============================

- optional support for Android 13 A2DP Opus codec
- multi channels and sampling rates mode for ALSA PCM plug-in
- multi channels and sample rates mode for ALSA PCM plug-in
- bluealsa-aplay: fix volume synchronization on Raspberry Pi

bluez-alsa v4.2.0 (2024-05-11)
Expand Down
2 changes: 1 addition & 1 deletion doc/bluealsa-aplay.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ OPTIONS
Internally, **bluealsa-aplay** does not perform any audio transformations
nor streams mixing. If multiple Bluetooth devices are connected it simply
opens a new connection to the ALSA PCM device for each stream. Selected
hardware parameters like sampling frequency and number of channels are
hardware parameters like sample rate and number of channels are
taken from the audio profile of a particular Bluetooth connection. Note,
that each connection can have a different setup.

Expand Down
4 changes: 2 additions & 2 deletions doc/bluealsa-plugins.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ PCM Parameters
For the A2DP profile it is possible to also specify a "configuration" for
the codec by appending the configuration as a hex string separated from the
codec name by a colon. The bits responsible for the number of channels and
the sampling frequency are set by the plugin with the respect to options
provided by the user (channel mode and sampling frequency bits act as a
the sample rate are set by the plugin with the respect to options
provided by the user (channel mode and sample rate bits act as a
mask). For example:

::
Expand Down
4 changes: 2 additions & 2 deletions doc/bluealsactl.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ info *PCM_PATH*
The list of available A2DP codecs requires BlueZ SEP support
(BlueZ >= 5.52)

codec [-c NUM] [-s NUM] [--force] *PCM_PATH* [*CODEC*\ [:*CONFIG*]]
codec [-c NUM] [-r NUM] [--force] *PCM_PATH* [*CODEC*\ [:*CONFIG*]]
Get or set the Bluetooth codec used by the given PCM.

If *CODEC* is given, change the codec to be used by the given PCM. This
Expand Down Expand Up @@ -223,7 +223,7 @@ open [--hex] *PCM_PATH*
Transfer raw audio frames to or from the given PCM. For sink PCMs
the frames are read from standard input and written to the PCM. For
source PCMs the frames are read from the PCM and written to standard
output. The format, channels and sampling rate must match the properties
output. The format, channels and sample rate must match the properties
of the PCM, as no format conversions are performed by this tool.

With the **--hex** option, the data is read or written as hexadecimal
Expand Down
12 changes: 6 additions & 6 deletions doc/bluealsad.8.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,9 @@ OPTIONS
Force monophonic sound for A2DP profile.

--a2dp-force-audio-cd
Force 44.1 kHz sampling frequency for A2DP profile.
Some Bluetooth devices can handle streams sampled at either 48kHz or
44.1kHz, in which case they normally default to using 48kHz.
Force 44.1 kHz sample rate for A2DP profile.
Some Bluetooth devices can handle streams sampled at either 48 kHz or
44.1kHz, in which case they normally default to using 48 kHz.
With this option, **bluealsad** will request such a device uses only 44.1
kHz sample rate.

Expand Down Expand Up @@ -271,9 +271,9 @@ Profiles
**bluealsad** provides support for Bluetooth Advanced Audio Distribution
Profile (A2DP), Hands-Free Profile (HFP), Headset Profile (HSP) and Bluetooth
Low Energy MIDI (BLE-MIDI).
A2DP profile is dedicated for streaming music (i.e., stereo, 48 kHz or more
sampling frequency), while HFP and HSP for two-way voice transmission (mono, 8
kHz or 16 kHz sampling frequency). BLE-MIDI, on the other hand, is used for
A2DP profile is dedicated for streaming music (i.e., stereo, 48 kHz or higher
sample rates), while HFP and HSP for two-way voice transmission (mono, 8
kHz or 16 kHz sample rate). BLE-MIDI, on the other hand, is used for
transmitting MIDI messages over Bluetooth LE.

The Bluetooth audio profiles are not peer-to-peer; they each have a source or
Expand Down
20 changes: 10 additions & 10 deletions doc/org.bluealsa.PCM1.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ org.bluealsa.PCM1
Bluetooth Audio PCM D-Bus API
-----------------------------

:Date: August 2024
:Date: September 2024
:Manual section: 7
:Manual group: D-Bus Interface
:Version: $VERSION$
Expand Down Expand Up @@ -49,12 +49,12 @@ array{string, dict} GetCodecs()

:array{byte} Capabilities:
A2DP codec capabilities blob.
:array{byte} SupportedChannels:
List of supported number of audio channels.
:array{uint32} SupportedSampling:
List of supported sampling frequency.
:array{byte} Channels:
List of supported channel counts.
:array{array{string}} ChannelMaps:
List of supported channel maps.
:array{uint32} Rates:
List of supported sample rates.

void SelectCodec(string codec, dict props)
Select PCM codec. This call shall be made before PCM stream opening for
Expand All @@ -69,9 +69,9 @@ void SelectCodec(string codec, dict props)
property to true.

In case of codecs which support different number of audio channels or
sampling frequencies, client can select the desired configuration by
providing the "Channels" and "Sampling" properties respectively. These
properties take precedence over the provided codec configuration.
sample rates, client can select the desired configuration by providing the
"Channels" and "Rate" properties respectively. These properties take
precedence over the provided codec configuration.

Possible Errors:
::
Expand Down Expand Up @@ -150,8 +150,8 @@ byte Channels [readonly]
array{string} ChannelMap [readonly]
Channel map for selected codec.

uint32 Sampling [readonly]
Sampling frequency.
uint32 Rate [readonly]
Sample rate in Hz.

string Codec [readonly]
Bluetooth transport codec. This property is available only when transport
Expand Down
48 changes: 24 additions & 24 deletions src/a2dp-aac.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ static const struct a2dp_bit_mapping a2dp_aac_channels[] = {
{ 0 }
};

static const struct a2dp_bit_mapping a2dp_aac_samplings[] = {
static const struct a2dp_bit_mapping a2dp_aac_rates[] = {
{ AAC_SAMPLING_FREQ_8000, { 8000 } },
{ AAC_SAMPLING_FREQ_11025, { 11025 } },
{ AAC_SAMPLING_FREQ_12000, { 12000 } },
Expand Down Expand Up @@ -111,15 +111,15 @@ static int a2dp_aac_caps_foreach_channel_mode(
return -1;
}

static int a2dp_aac_caps_foreach_sampling_freq(
static int a2dp_aac_caps_foreach_sample_rate(
const void *capabilities,
enum a2dp_stream stream,
a2dp_bit_mapping_foreach_func func,
void *userdata) {
const a2dp_aac_t *caps = capabilities;
if (stream == A2DP_MAIN) {
const uint16_t sampling_freq = A2DP_AAC_GET_SAMPLING_FREQ(*caps);
return a2dp_bit_mapping_foreach(a2dp_aac_samplings, sampling_freq, func, userdata);
return a2dp_bit_mapping_foreach(a2dp_aac_rates, sampling_freq, func, userdata);
}
return -1;
}
Expand All @@ -134,14 +134,14 @@ static void a2dp_aac_caps_select_channel_mode(
caps->channel_mode, channels);
}

static void a2dp_aac_caps_select_sampling_freq(
static void a2dp_aac_caps_select_sample_rate(
void *capabilities,
enum a2dp_stream stream,
unsigned int frequency) {
unsigned int rate) {
a2dp_aac_t *caps = capabilities;
if (stream == A2DP_MAIN) {
const uint16_t sampling_freq = a2dp_bit_mapping_lookup_value(a2dp_aac_samplings,
A2DP_AAC_GET_SAMPLING_FREQ(*caps), frequency);
const uint16_t sampling_freq = a2dp_bit_mapping_lookup_value(a2dp_aac_rates,
A2DP_AAC_GET_SAMPLING_FREQ(*caps), rate);
A2DP_AAC_SET_SAMPLING_FREQ(*caps, sampling_freq);
}
}
Expand All @@ -150,9 +150,9 @@ static struct a2dp_caps_helpers a2dp_aac_caps_helpers = {
.intersect = a2dp_aac_caps_intersect,
.has_stream = a2dp_caps_has_main_stream_only,
.foreach_channel_mode = a2dp_aac_caps_foreach_channel_mode,
.foreach_sampling_freq = a2dp_aac_caps_foreach_sampling_freq,
.foreach_sample_rate = a2dp_aac_caps_foreach_sample_rate,
.select_channel_mode = a2dp_aac_caps_select_channel_mode,
.select_sampling_freq = a2dp_aac_caps_select_sampling_freq,
.select_sample_rate = a2dp_aac_caps_select_sample_rate,
};

static unsigned int a2dp_aac_get_fdk_vbr_mode(
Expand Down Expand Up @@ -185,7 +185,7 @@ void *a2dp_aac_enc_thread(struct ba_transport_pcm *t_pcm) {
const a2dp_aac_t *configuration = &t->a2dp.configuration.aac;
const unsigned int bitrate = A2DP_AAC_GET_BITRATE(*configuration);
const unsigned int channels = t_pcm->channels;
const unsigned int samplerate = t_pcm->sampling;
const unsigned int rate = t_pcm->rate;

/* create AAC encoder without the Meta Data module */
if ((err = aacEncOpen(&handle, 0x0F, channels)) != AACENC_OK) {
Expand Down Expand Up @@ -255,8 +255,8 @@ void *a2dp_aac_enc_thread(struct ba_transport_pcm *t_pcm) {
}
}
#endif
if ((err = aacEncoder_SetParam(handle, AACENC_SAMPLERATE, samplerate)) != AACENC_OK) {
error("Couldn't set sampling rate: %s", aacenc_strerror(err));
if ((err = aacEncoder_SetParam(handle, AACENC_SAMPLERATE, rate)) != AACENC_OK) {
error("Couldn't set sample rate: %s", aacenc_strerror(err));
goto fail_init;
}
if ((err = aacEncoder_SetParam(handle, AACENC_CHANNELMODE, channel_mode)) != AACENC_OK) {
Expand Down Expand Up @@ -317,7 +317,7 @@ void *a2dp_aac_enc_thread(struct ba_transport_pcm *t_pcm) {

struct rtp_state rtp = { .synced = false };
/* RTP clock frequency equal to 90kHz */
rtp_state_init(&rtp, samplerate, 90000);
rtp_state_init(&rtp, rate, 90000);

int in_bufferIdentifiers[] = { IN_AUDIO_DATA };
int out_bufferIdentifiers[] = { OUT_BITSTREAM_DATA };
Expand Down Expand Up @@ -459,7 +459,7 @@ void *a2dp_aac_dec_thread(struct ba_transport_pcm *t_pcm) {
pthread_cleanup_push(PTHREAD_CLEANUP(aacDecoder_Close), handle);

const unsigned int channels = t_pcm->channels;
const unsigned int samplerate = t_pcm->sampling;
const unsigned int rate = t_pcm->rate;

#ifdef AACDECODER_LIB_VL0
if ((err = aacDecoder_SetParam(handle, AAC_PCM_MIN_OUTPUT_CHANNELS, channels)) != AAC_DEC_OK) {
Expand Down Expand Up @@ -493,7 +493,7 @@ void *a2dp_aac_dec_thread(struct ba_transport_pcm *t_pcm) {

struct rtp_state rtp = { .synced = false };
/* RTP clock frequency equal to 90kHz */
rtp_state_init(&rtp, samplerate, 90000);
rtp_state_init(&rtp, rate, 90000);

int markbit_quirk = -3;

Expand Down Expand Up @@ -614,11 +614,11 @@ static int a2dp_aac_configuration_select(
}

unsigned int sampling_freq = 0;
if (a2dp_aac_caps_foreach_sampling_freq(caps, A2DP_MAIN,
a2dp_bit_mapping_foreach_get_best_sampling_freq, &sampling_freq) != -1)
if (a2dp_aac_caps_foreach_sample_rate(caps, A2DP_MAIN,
a2dp_bit_mapping_foreach_get_best_sample_rate, &sampling_freq) != -1)
A2DP_AAC_SET_SAMPLING_FREQ(*caps, sampling_freq);
else {
error("AAC: No supported sampling frequencies: %#x", A2DP_AAC_GET_SAMPLING_FREQ(saved));
error("AAC: No supported sample rates: %#x", A2DP_AAC_GET_SAMPLING_FREQ(saved));
return errno = ENOTSUP, -1;
}

Expand Down Expand Up @@ -692,9 +692,9 @@ static int a2dp_aac_configuration_check(
}

const uint16_t conf_sampling_freq = A2DP_AAC_GET_SAMPLING_FREQ(conf_v);
if (a2dp_bit_mapping_lookup(a2dp_aac_samplings, conf_sampling_freq) == -1) {
debug("AAC: Invalid sampling frequency: %#x", A2DP_AAC_GET_SAMPLING_FREQ(*conf));
return A2DP_CHECK_ERR_SAMPLING;
if (a2dp_bit_mapping_lookup(a2dp_aac_rates, conf_sampling_freq) == -1) {
debug("AAC: Invalid sample rate: %#x", A2DP_AAC_GET_SAMPLING_FREQ(*conf));
return A2DP_CHECK_ERR_RATE;
}

if (a2dp_bit_mapping_lookup(a2dp_aac_channels, conf_v.channel_mode) == -1) {
Expand All @@ -712,14 +712,14 @@ static int a2dp_aac_transport_init(struct ba_transport *t) {
t->a2dp.configuration.aac.channel_mode)) == -1)
return -1;

ssize_t sampling_i;
if ((sampling_i = a2dp_bit_mapping_lookup(a2dp_aac_samplings,
ssize_t rate_i;
if ((rate_i = a2dp_bit_mapping_lookup(a2dp_aac_rates,
A2DP_AAC_GET_SAMPLING_FREQ(t->a2dp.configuration.aac))) == -1)
return -1;

t->a2dp.pcm.format = BA_TRANSPORT_PCM_FORMAT_S16_2LE;
t->a2dp.pcm.channels = a2dp_aac_channels[channels_i].value;
t->a2dp.pcm.sampling = a2dp_aac_samplings[sampling_i].value;
t->a2dp.pcm.rate = a2dp_aac_rates[rate_i].value;

memcpy(t->a2dp.pcm.channel_map, a2dp_aac_channels[channels_i].ch.map,
t->a2dp.pcm.channels * sizeof(*t->a2dp.pcm.channel_map));
Expand Down
Loading

0 comments on commit 04e8277

Please sign in to comment.