This is best done by the host application, and had very little
implementation anyways.
This commit is contained in:
Paul Adenot 2019-08-21 17:34:40 +02:00 коммит произвёл Matthew Gregan
Родитель 323ced8019
Коммит 8c3e32bd24
19 изменённых файлов: 7 добавлений и 223 удалений

Просмотреть файл

@ -67,7 +67,6 @@ add_library(cubeb
src/cubeb.c
src/cubeb_mixer.cpp
src/cubeb_resampler.cpp
src/cubeb_panner.cpp
src/cubeb_log.cpp
src/cubeb_strings.c
src/cubeb_utils.cpp

Просмотреть файл

@ -568,20 +568,6 @@ CUBEB_EXPORT int cubeb_stream_get_latency(cubeb_stream * stream, uint32_t * late
@retval CUBEB_ERROR_NOT_SUPPORTED */
CUBEB_EXPORT int cubeb_stream_set_volume(cubeb_stream * stream, float volume);
/** If the stream is stereo, set the left/right panning. If the stream is mono,
this has no effect.
@param stream the stream for which to change the panning
@param panning a number from -1.0 to 1.0. -1.0 means that the stream is
fully mixed in the left channel, 1.0 means the stream is fully
mixed in the right channel. 0.0 is equal power in the right and
left channel (default).
@retval CUBEB_OK
@retval CUBEB_ERROR_INVALID_PARAMETER if stream is null or if panning is
outside the [-1.0, 1.0] range.
@retval CUBEB_ERROR_NOT_SUPPORTED
@retval CUBEB_ERROR stream is not mono nor stereo */
CUBEB_EXPORT int cubeb_stream_set_panning(cubeb_stream * stream, float panning);
/** Get the current output device for this stream.
@param stm the stream for which to query the current output device
@param device a pointer in which the current output device will be stored.

Просмотреть файл

@ -64,7 +64,6 @@ struct cubeb_ops {
int (* stream_get_position)(cubeb_stream * stream, uint64_t * position);
int (* stream_get_latency)(cubeb_stream * stream, uint32_t * latency);
int (* stream_set_volume)(cubeb_stream * stream, float volumes);
int (* stream_set_panning)(cubeb_stream * stream, float panning);
int (* stream_get_current_device)(cubeb_stream * stream,
cubeb_device ** const device);
int (* stream_device_destroy)(cubeb_stream * stream,

Просмотреть файл

@ -434,19 +434,6 @@ cubeb_stream_set_volume(cubeb_stream * stream, float volume)
return stream->context->ops->stream_set_volume(stream, volume);
}
int cubeb_stream_set_panning(cubeb_stream * stream, float panning)
{
if (!stream || panning < -1.0 || panning > 1.0) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
if (!stream->context->ops->stream_set_panning) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
return stream->context->ops->stream_set_panning(stream, panning);
}
int cubeb_stream_get_current_device(cubeb_stream * stream,
cubeb_device ** const device)
{

Просмотреть файл

@ -1369,7 +1369,6 @@ static struct cubeb_ops const alsa_ops = {
.stream_get_position = alsa_stream_get_position,
.stream_get_latency = alsa_stream_get_latency,
.stream_set_volume = alsa_stream_set_volume,
.stream_set_panning = NULL,
.stream_get_current_device = NULL,
.stream_device_destroy = NULL,
.stream_register_device_changed_callback = NULL,

Просмотреть файл

@ -434,7 +434,6 @@ static struct cubeb_ops const audiotrack_ops = {
.stream_get_position = audiotrack_stream_get_position,
.stream_get_latency = audiotrack_stream_get_latency,
.stream_set_volume = audiotrack_stream_set_volume,
.stream_set_panning = NULL,
.stream_get_current_device = NULL,
.stream_device_destroy = NULL,
.stream_register_device_changed_callback = NULL,

Просмотреть файл

@ -23,7 +23,6 @@
#include "cubeb/cubeb.h"
#include "cubeb-internal.h"
#include "cubeb_mixer.h"
#include "cubeb_panner.h"
#if !TARGET_OS_IPHONE
#include "cubeb_osx_run_loop.h"
#endif
@ -242,7 +241,6 @@ struct cubeb_stream {
uint32_t latency_frames = 0;
atomic<uint32_t> current_latency_frames{ 0 };
atomic<uint32_t> total_output_latency_frames { 0 };
atomic<float> panning{ 0 };
unique_ptr<cubeb_resampler, decltype(&cubeb_resampler_destroy)> resampler;
/* This is true if a device change callback is currently running. */
atomic<bool> switching_device{ false };
@ -692,10 +690,6 @@ audiounit_output_callback(void * user_ptr,
stm->frames_played = stm->frames_queued;
stm->frames_queued += outframes;
AudioFormatFlags outaff = stm->output_desc.mFormatFlags;
float panning = (stm->output_desc.mChannelsPerFrame == 2) ?
stm->panning.load(memory_order_relaxed) : 0.0f;
/* Post process output samples. */
if (stm->draining) {
size_t outbpf = cubeb_sample_size(stm->output_stream_params.format);
@ -711,16 +705,6 @@ audiounit_output_callback(void * user_ptr,
stm->temp_buffer_size,
outBufferList->mBuffers[0].mData,
outBufferList->mBuffers[0].mDataByteSize);
} else {
/* Pan stereo. */
if (panning != 0.0f) {
if (outaff & kAudioFormatFlagIsFloat) {
cubeb_pan_stereo_buffer_float(
(float*)output_buffer, outframes, panning);
} else if (outaff & kAudioFormatFlagIsSignedInteger) {
cubeb_pan_stereo_buffer_int((short*)output_buffer, outframes, panning);
}
}
}
return noErr;
@ -3021,16 +3005,6 @@ audiounit_stream_set_volume(cubeb_stream * stm, float volume)
return CUBEB_OK;
}
int audiounit_stream_set_panning(cubeb_stream * stm, float panning)
{
if (stm->output_desc.mChannelsPerFrame > 2) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
stm->panning.store(panning, memory_order_relaxed);
return CUBEB_OK;
}
unique_ptr<char[]> convert_uint32_into_string(UInt32 data)
{
// Simply create an empty string if no data.
@ -3632,7 +3606,6 @@ cubeb_ops const audiounit_ops = {
/*.stream_get_position =*/ audiounit_stream_get_position,
/*.stream_get_latency =*/ audiounit_stream_get_latency,
/*.stream_set_volume =*/ audiounit_stream_set_volume,
/*.stream_set_panning =*/ audiounit_stream_set_panning,
/*.stream_get_current_device =*/ audiounit_stream_get_current_device,
/*.stream_device_destroy =*/ audiounit_stream_device_destroy,
/*.stream_register_device_changed_callback =*/ audiounit_stream_register_device_changed_callback,

Просмотреть файл

@ -130,7 +130,6 @@ static struct cubeb_ops const cbjack_ops = {
.stream_get_position = cbjack_stream_get_position,
.stream_get_latency = cbjack_get_latency,
.stream_set_volume = cbjack_stream_set_volume,
.stream_set_panning = NULL,
.stream_get_current_device = cbjack_stream_get_current_device,
.stream_device_destroy = cbjack_stream_device_destroy,
.stream_register_device_changed_callback = NULL,

Просмотреть файл

@ -362,7 +362,6 @@ static struct cubeb_ops const kai_ops = {
/*.stream_get_position =*/ kai_stream_get_position,
/*.stream_get_latency = */ kai_stream_get_latency,
/*.stream_set_volume =*/ kai_stream_set_volume,
/*.stream_set_panning =*/ NULL,
/*.stream_get_current_device =*/ NULL,
/*.stream_device_destroy =*/ NULL,
/*.stream_register_device_changed_callback=*/ NULL,

Просмотреть файл

@ -1673,7 +1673,6 @@ static struct cubeb_ops const opensl_ops = {
.stream_get_position = opensl_stream_get_position,
.stream_get_latency = NULL,
.stream_set_volume = opensl_stream_set_volume,
.stream_set_panning = NULL,
.stream_get_current_device = NULL,
.stream_device_destroy = NULL,
.stream_register_device_changed_callback = NULL,

Просмотреть файл

@ -1,60 +0,0 @@
/*
* Copyright © 2014 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#define _USE_MATH_DEFINES
#include <math.h>
#include <stdint.h>
#include "cubeb_panner.h"
#ifndef M_PI
#define M_PI 3.14159263
#endif
/**
* We use a cos/sin law.
*/
namespace {
template<typename T>
void cubeb_pan_stereo_buffer(T * buf, uint32_t frames, float pan)
{
if (pan == 0.0) {
return;
}
/* rescale in [0; 1] */
pan += 1;
pan /= 2;
float left_gain = float(cos(pan * M_PI * 0.5));
float right_gain = float(sin(pan * M_PI * 0.5));
/* In we are panning on the left, pan the right channel into the left one and
* vice-versa. */
if (pan < 0.5) {
for (uint32_t i = 0; i < frames * 2; i+=2) {
buf[i] = T(buf[i] + buf[i + 1] * left_gain);
buf[i + 1] = T(buf[i + 1] * right_gain);
}
} else {
for (uint32_t i = 0; i < frames * 2; i+=2) {
buf[i] = T(buf[i] * left_gain);
buf[i + 1] = T(buf[i + 1] + buf[i] * right_gain);
}
}
}
}
void cubeb_pan_stereo_buffer_float(float * buf, uint32_t frames, float pan)
{
cubeb_pan_stereo_buffer(buf, frames, pan);
}
void cubeb_pan_stereo_buffer_int(short * buf, uint32_t frames, float pan)
{
cubeb_pan_stereo_buffer(buf, frames, pan);
}

Просмотреть файл

@ -1,28 +0,0 @@
/*
* Copyright © 2014 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#if !defined(CUBEB_PANNER)
#define CUBEB_PANNER
#if defined(__cplusplus)
extern "C" {
#endif
/**
* Pan an integer or an float stereo buffer according to a cos/sin pan law
* @param buf the buffer to pan
* @param frames the number of frames in `buf`
* @param pan a float in [-1.0; 1.0]
*/
void cubeb_pan_stereo_buffer_float(float * buf, uint32_t frames, float pan);
void cubeb_pan_stereo_buffer_int(short* buf, uint32_t frames, float pan);
#if defined(__cplusplus)
}
#endif
#endif

Просмотреть файл

@ -1184,53 +1184,6 @@ sink_input_info_cb(pa_context * c, pa_sink_input_info const * i, int eol, void *
WRAP(pa_threaded_mainloop_signal)(r->mainloop, 0);
}
static int
pulse_stream_set_panning(cubeb_stream * stm, float panning)
{
const pa_channel_map * map;
pa_cvolume cvol;
uint32_t index;
pa_operation * op;
if (!stm->output_stream) {
return CUBEB_ERROR;
}
WRAP(pa_threaded_mainloop_lock)(stm->context->mainloop);
map = WRAP(pa_stream_get_channel_map)(stm->output_stream);
if (!WRAP(pa_channel_map_can_balance)(map)) {
WRAP(pa_threaded_mainloop_unlock)(stm->context->mainloop);
return CUBEB_ERROR;
}
index = WRAP(pa_stream_get_index)(stm->output_stream);
struct sink_input_info_result r = { &cvol, stm->context->mainloop };
op = WRAP(pa_context_get_sink_input_info)(stm->context->context,
index,
sink_input_info_cb,
&r);
if (op) {
operation_wait(stm->context, stm->output_stream, op);
WRAP(pa_operation_unref)(op);
}
WRAP(pa_cvolume_set_balance)(&cvol, map, panning);
op = WRAP(pa_context_set_sink_input_volume)(stm->context->context,
index, &cvol, volume_success,
stm);
if (op) {
operation_wait(stm->context, stm->output_stream, op);
WRAP(pa_operation_unref)(op);
}
WRAP(pa_threaded_mainloop_unlock)(stm->context->mainloop);
return CUBEB_OK;
}
typedef struct {
char * default_sink_name;
char * default_source_name;
@ -1637,7 +1590,6 @@ static struct cubeb_ops const pulse_ops = {
.stream_get_position = pulse_stream_get_position,
.stream_get_latency = pulse_stream_get_latency,
.stream_set_volume = pulse_stream_set_volume,
.stream_set_panning = pulse_stream_set_panning,
.stream_get_current_device = pulse_stream_get_current_device,
.stream_device_destroy = pulse_stream_device_destroy,
.stream_register_device_changed_callback = NULL,

Просмотреть файл

@ -572,7 +572,6 @@ static struct cubeb_ops const sndio_ops = {
.stream_get_position = sndio_stream_get_position,
.stream_get_latency = sndio_stream_get_latency,
.stream_set_volume = sndio_stream_set_volume,
.stream_set_panning = NULL,
.stream_get_current_device = NULL,
.stream_device_destroy = NULL,
.stream_register_device_changed_callback = NULL,

Просмотреть файл

@ -745,7 +745,6 @@ static struct cubeb_ops const sun_ops = {
.stream_get_position = sun_stream_get_position,
.stream_get_latency = sun_stream_get_latency,
.stream_set_volume = sun_stream_set_volume,
.stream_set_panning = NULL,
.stream_get_current_device = sun_get_current_device,
.stream_device_destroy = sun_stream_device_destroy,
.stream_register_device_changed_callback = NULL,

Просмотреть файл

@ -2951,7 +2951,6 @@ cubeb_ops const wasapi_ops = {
/*.stream_get_position =*/ wasapi_stream_get_position,
/*.stream_get_latency =*/ wasapi_stream_get_latency,
/*.stream_set_volume =*/ wasapi_stream_set_volume,
/*.stream_set_panning =*/ NULL,
/*.stream_get_current_device =*/ NULL,
/*.stream_device_destroy =*/ NULL,
/*.stream_register_device_changed_callback =*/ NULL,

Просмотреть файл

@ -1060,7 +1060,6 @@ static struct cubeb_ops const winmm_ops = {
/*.stream_get_position =*/ winmm_stream_get_position,
/*.stream_get_latency = */ winmm_stream_get_latency,
/*.stream_set_volume =*/ winmm_stream_set_volume,
/*.stream_set_panning =*/ NULL,
/*.stream_get_current_device =*/ NULL,
/*.stream_device_destroy =*/ NULL,
/*.stream_register_device_changed_callback=*/ NULL,

Просмотреть файл

@ -148,7 +148,7 @@ int run_test(int num_channels, int sampling_rate, int is_float)
return r;
}
int run_panning_volume_test(int is_float)
int run_volume_test(int is_float)
{
int r = CUBEB_OK;
@ -203,29 +203,17 @@ int run_panning_volume_test(int is_float)
delay(100);
}
fprintf(stderr, "Testing: panning\n");
for(int i=-4;i <= 4; ++i)
{
fprintf(stderr, "Panning: %.2f\n", i/4.0f);
cubeb_stream_set_panning(stream, i/4.0f);
cubeb_stream_start(stream);
delay(400);
cubeb_stream_stop(stream);
delay(100);
}
return r;
}
TEST(cubeb, run_panning_volume_test_short)
TEST(cubeb, run_volume_test_short)
{
ASSERT_EQ(run_panning_volume_test(0), CUBEB_OK);
ASSERT_EQ(run_volume_test(0), CUBEB_OK);
}
TEST(cubeb, run_panning_volume_test_float)
TEST(cubeb, run_volume_test_float)
{
ASSERT_EQ(run_panning_volume_test(1), CUBEB_OK);
ASSERT_EQ(run_volume_test(1), CUBEB_OK);
}
TEST(cubeb, run_channel_rate_test)

Просмотреть файл

@ -215,7 +215,7 @@ TEST(cubeb, configure_stream)
params.format = STREAM_FORMAT;
params.rate = STREAM_RATE;
params.channels = 2; // panning
params.channels = 2;
params.layout = CUBEB_LAYOUT_STEREO;
params.prefs = CUBEB_STREAM_PREF_NONE;
@ -227,9 +227,6 @@ TEST(cubeb, configure_stream)
r = cubeb_stream_set_volume(stream, 1.0f);
ASSERT_TRUE(r == 0 || r == CUBEB_ERROR_NOT_SUPPORTED);
r = cubeb_stream_set_panning(stream, 0.0f);
ASSERT_TRUE(r == 0 || r == CUBEB_ERROR_NOT_SUPPORTED);
cubeb_stream_destroy(stream);
cubeb_destroy(ctx);
}
@ -247,7 +244,7 @@ TEST(cubeb, configure_stream_undefined_layout)
params.format = STREAM_FORMAT;
params.rate = STREAM_RATE;
params.channels = 2; // panning
params.channels = 2;
params.layout = CUBEB_LAYOUT_UNDEFINED;
params.prefs = CUBEB_STREAM_PREF_NONE;