early-access version 2840

This commit is contained in:
pineappleEA
2022-07-17 09:10:25 +02:00
parent b866bff3f2
commit e8706a3c92
77 changed files with 2720 additions and 1054 deletions

View File

@@ -935,8 +935,7 @@ aaudio_stream_init_impl(cubeb_stream * stm, cubeb_devid input_device,
stm->resampler = cubeb_resampler_create(
stm, input_stream_params ? &in_params : NULL,
output_stream_params ? &out_params : NULL, target_sample_rate,
stm->data_callback, stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DEFAULT,
CUBEB_RESAMPLER_RECLOCK_NONE);
stm->data_callback, stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DEFAULT);
if (!stm->resampler) {
LOG("Failed to create resampler");

View File

@@ -541,13 +541,6 @@ audiounit_input_callback(void * user_ptr, AudioUnitRenderActionFlags * flags,
long outframes = cubeb_resampler_fill(stm->resampler.get(),
stm->input_linear_buffer->data(),
&total_input_frames, NULL, 0);
if (outframes < 0) {
stm->shutdown = true;
OSStatus r = AudioOutputUnitStop(stm->input_unit);
assert(r == 0);
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
return noErr;
}
stm->draining = outframes < total_input_frames;
// Reset input buffer
@@ -1449,13 +1442,6 @@ audiounit_destroy(cubeb * ctx)
audiounit_active_streams(ctx));
}
// Destroying a cubeb context with device collection callbacks registered
// is misuse of the API, assert then attempt to clean up.
assert(!ctx->input_collection_changed_callback &&
!ctx->input_collection_changed_user_ptr &&
!ctx->output_collection_changed_callback &&
!ctx->output_collection_changed_user_ptr);
/* Unregister the callback if necessary. */
if (ctx->input_collection_changed_callback) {
audiounit_remove_device_listener(ctx, CUBEB_DEVICE_TYPE_INPUT);
@@ -2714,8 +2700,7 @@ audiounit_setup_stream(cubeb_stream * stm)
stm->resampler.reset(cubeb_resampler_create(
stm, has_input(stm) ? &input_unconverted_params : NULL,
has_output(stm) ? &stm->output_stream_params : NULL, target_sample_rate,
stm->data_callback, stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP,
CUBEB_RESAMPLER_RECLOCK_NONE));
stm->data_callback, stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP));
if (!stm->resampler) {
LOG("(%p) Could not create resampler.", stm);
return CUBEB_ERROR;

View File

@@ -925,18 +925,15 @@ cbjack_stream_init(cubeb * context, cubeb_stream ** stream,
if (stm->devs == DUPLEX) {
stm->resampler = cubeb_resampler_create(
stm, &stm->in_params, &stm->out_params, stream_actual_rate,
stm->data_callback, stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP,
CUBEB_RESAMPLER_RECLOCK_NONE);
stm->data_callback, stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP);
} else if (stm->devs == IN_ONLY) {
stm->resampler = cubeb_resampler_create(
stm, &stm->in_params, nullptr, stream_actual_rate, stm->data_callback,
stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP,
CUBEB_RESAMPLER_RECLOCK_NONE);
stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP);
} else if (stm->devs == OUT_ONLY) {
stm->resampler = cubeb_resampler_create(
stm, nullptr, &stm->out_params, stream_actual_rate, stm->data_callback,
stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP,
CUBEB_RESAMPLER_RECLOCK_NONE);
stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP);
}
if (!stm->resampler) {

View File

@@ -123,7 +123,7 @@ cubeb_async_log(char const * fmt, ...)
}
void
cubeb_async_log_reset_threads(void)
cubeb_async_log_reset_threads()
{
if (!g_cubeb_log_callback) {
return;

View File

@@ -35,7 +35,7 @@ extern cubeb_log_callback g_cubeb_log_callback PRINTF_FORMAT(1, 2);
void
cubeb_async_log(const char * fmt, ...);
void
cubeb_async_log_reset_threads(void);
cubeb_async_log_reset_threads();
#ifdef __cplusplus
}

View File

@@ -1479,8 +1479,7 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream,
stm->resampler = cubeb_resampler_create(
stm, input_stream_params ? &input_params : NULL,
output_stream_params ? &output_params : NULL, target_sample_rate,
data_callback, user_ptr, CUBEB_RESAMPLER_QUALITY_DEFAULT,
CUBEB_RESAMPLER_RECLOCK_NONE);
data_callback, user_ptr, CUBEB_RESAMPLER_QUALITY_DEFAULT);
if (!stm->resampler) {
LOG("Failed to create resampler");
opensl_stream_destroy(stm);

View File

@@ -96,8 +96,9 @@ struct oss_stream {
oss_devnode_t name;
int fd;
void * buf;
unsigned int nfr; /* Number of frames allocated */
unsigned int nfrags;
unsigned int bufframes;
unsigned int maxframes;
struct stream_info {
int channels;
@@ -823,9 +824,9 @@ retry:
pfds[0].fd = s->play.fd;
pfds[1].fd = -1;
goto retry;
} else if (tnfr > (long)s->play.maxframes) {
} else if (tnfr > (long)s->play.bufframes) {
/* too many frames available - limit */
tnfr = (long)s->play.maxframes;
tnfr = (long)s->play.bufframes;
}
if (nfr > tnfr) {
nfr = tnfr;
@@ -841,9 +842,9 @@ retry:
pfds[0].fd = -1;
pfds[1].fd = s->record.fd;
goto retry;
} else if (tnfr > (long)s->record.maxframes) {
} else if (tnfr > (long)s->record.bufframes) {
/* too many frames available - limit */
tnfr = (long)s->record.maxframes;
tnfr = (long)s->record.bufframes;
}
if (nfr > tnfr) {
nfr = tnfr;
@@ -1060,8 +1061,6 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
}
if (input_stream_params != NULL) {
unsigned int nb_channels;
uint32_t minframes;
if (input_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
LOG("Loopback not supported");
ret = CUBEB_ERROR_NOT_SUPPORTED;
@@ -1090,17 +1089,18 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
(input_stream_params->format == CUBEB_SAMPLE_FLOAT32NE);
s->record.frame_size =
s->record.info.channels * (s->record.info.precision / 8);
s->record.bufframes = latency_frames;
oss_get_min_latency(context, *input_stream_params, &minframes);
if (s->record.bufframes < minframes) {
s->record.bufframes = minframes;
s->record.nfrags = OSS_NFRAGS;
s->record.nfr = latency_frames / OSS_NFRAGS;
s->record.bufframes = s->record.nfrags * s->record.nfr;
uint32_t minnfr;
oss_get_min_latency(context, *input_stream_params, &minnfr);
if (s->record.nfr < minnfr) {
s->record.nfr = minnfr;
s->record.nfrags = latency_frames / minnfr;
}
}
if (output_stream_params != NULL) {
unsigned int nb_channels;
uint32_t minframes;
if (output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
LOG("Loopback not supported");
ret = CUBEB_ERROR_NOT_SUPPORTED;
@@ -1128,16 +1128,19 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
}
s->play.floating = (output_stream_params->format == CUBEB_SAMPLE_FLOAT32NE);
s->play.frame_size = s->play.info.channels * (s->play.info.precision / 8);
s->play.bufframes = latency_frames;
oss_get_min_latency(context, *output_stream_params, &minframes);
if (s->play.bufframes < minframes) {
s->play.bufframes = minframes;
s->play.nfrags = OSS_NFRAGS;
s->play.nfr = latency_frames / OSS_NFRAGS;
uint32_t minnfr;
oss_get_min_latency(context, *output_stream_params, &minnfr);
if (s->play.nfr < minnfr) {
s->play.nfr = minnfr;
s->play.nfrags = latency_frames / minnfr;
}
s->play.bufframes = s->play.nfrags * s->play.nfr;
}
if (s->play.fd != -1) {
int frag = oss_get_frag_params(
oss_calc_frag_shift(s->play.bufframes, s->play.frame_size));
oss_calc_frag_shift(s->play.nfr, s->play.frame_size));
if (ioctl(s->play.fd, SNDCTL_DSP_SETFRAGMENT, &frag))
LOG("Failed to set play fd with SNDCTL_DSP_SETFRAGMENT. frag: 0x%x",
frag);
@@ -1145,28 +1148,19 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
if (ioctl(s->play.fd, SNDCTL_DSP_GETOSPACE, &bi))
LOG("Failed to get play fd's buffer info.");
else {
s->play.bufframes = (bi.fragsize * bi.fragstotal) / s->play.frame_size;
s->play.nfr = bi.fragsize / s->play.frame_size;
s->play.nfrags = bi.fragments;
s->play.bufframes = s->play.nfr * s->play.nfrags;
}
int lw;
/*
* Force 32 ms service intervals at most, or when recording is
* active, use the recording service intervals as a reference.
*/
s->play.maxframes = (32 * output_stream_params->rate) / 1000;
if (s->record.fd != -1 || s->play.maxframes >= s->play.bufframes) {
lw = s->play.frame_size; /* Feed data when possible. */
s->play.maxframes = s->play.bufframes;
} else {
lw = (s->play.bufframes - s->play.maxframes) * s->play.frame_size;
}
int lw = s->play.frame_size;
if (ioctl(s->play.fd, SNDCTL_DSP_LOW_WATER, &lw))
LOG("Audio device \"%s\" (play) could not set trigger threshold",
s->play.name);
}
if (s->record.fd != -1) {
int frag = oss_get_frag_params(
oss_calc_frag_shift(s->record.bufframes, s->record.frame_size));
oss_calc_frag_shift(s->record.nfr, s->record.frame_size));
if (ioctl(s->record.fd, SNDCTL_DSP_SETFRAGMENT, &frag))
LOG("Failed to set record fd with SNDCTL_DSP_SETFRAGMENT. frag: 0x%x",
frag);
@@ -1174,11 +1168,11 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
if (ioctl(s->record.fd, SNDCTL_DSP_GETISPACE, &bi))
LOG("Failed to get record fd's buffer info.");
else {
s->record.bufframes =
(bi.fragsize * bi.fragstotal) / s->record.frame_size;
s->record.nfr = bi.fragsize / s->record.frame_size;
s->record.nfrags = bi.fragments;
s->record.bufframes = s->record.nfr * s->record.nfrags;
}
s->record.maxframes = s->record.bufframes;
int lw = s->record.frame_size;
if (ioctl(s->record.fd, SNDCTL_DSP_LOW_WATER, &lw))
LOG("Audio device \"%s\" (record) could not set trigger threshold",

View File

@@ -280,7 +280,6 @@ trigger_user_callback(pa_stream * s, void const * input_data, size_t nbytes,
if (got < 0) {
WRAP(pa_stream_cancel_write)(s);
stm->shutdown = 1;
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
return;
}
// If more iterations move offset of read buffer
@@ -393,9 +392,6 @@ stream_read_callback(pa_stream * s, size_t nbytes, void * u)
if (got < 0 || (size_t)got != read_frames) {
WRAP(pa_stream_cancel_write)(s);
stm->shutdown = 1;
if (got < 0) {
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
}
break;
}
}
@@ -787,10 +783,6 @@ pulse_context_destroy(cubeb * ctx)
static void
pulse_destroy(cubeb * ctx)
{
assert(!ctx->input_collection_changed_callback &&
!ctx->input_collection_changed_user_ptr &&
!ctx->output_collection_changed_callback &&
!ctx->output_collection_changed_user_ptr);
free(ctx->context_name);
if (ctx->context) {
pulse_context_destroy(ctx);

View File

@@ -323,8 +323,7 @@ cubeb_resampler_create(cubeb_stream * stream,
cubeb_stream_params * input_params,
cubeb_stream_params * output_params,
unsigned int target_rate, cubeb_data_callback callback,
void * user_ptr, cubeb_resampler_quality quality,
cubeb_resampler_reclock reclock)
void * user_ptr, cubeb_resampler_quality quality)
{
cubeb_sample_format format;
@@ -338,13 +337,13 @@ cubeb_resampler_create(cubeb_stream * stream,
switch (format) {
case CUBEB_SAMPLE_S16NE:
return cubeb_resampler_create_internal<short>(
stream, input_params, output_params, target_rate, callback, user_ptr,
quality, reclock);
return cubeb_resampler_create_internal<short>(stream, input_params,
output_params, target_rate,
callback, user_ptr, quality);
case CUBEB_SAMPLE_FLOAT32NE:
return cubeb_resampler_create_internal<float>(
stream, input_params, output_params, target_rate, callback, user_ptr,
quality, reclock);
return cubeb_resampler_create_internal<float>(stream, input_params,
output_params, target_rate,
callback, user_ptr, quality);
default:
assert(false);
return nullptr;

View File

@@ -21,11 +21,6 @@ typedef enum {
CUBEB_RESAMPLER_QUALITY_DESKTOP
} cubeb_resampler_quality;
typedef enum {
CUBEB_RESAMPLER_RECLOCK_NONE,
CUBEB_RESAMPLER_RECLOCK_INPUT
} cubeb_resampler_reclock;
/**
* Create a resampler to adapt the requested sample rate into something that
* is accepted by the audio backend.
@@ -49,8 +44,7 @@ cubeb_resampler_create(cubeb_stream * stream,
cubeb_stream_params * input_params,
cubeb_stream_params * output_params,
unsigned int target_rate, cubeb_data_callback callback,
void * user_ptr, cubeb_resampler_quality quality,
cubeb_resampler_reclock reclock);
void * user_ptr, cubeb_resampler_quality quality);
/**
* Fill the buffer with frames acquired using the data callback. Resampling will

View File

@@ -496,8 +496,7 @@ cubeb_resampler_create_internal(cubeb_stream * stream,
cubeb_stream_params * output_params,
unsigned int target_rate,
cubeb_data_callback callback, void * user_ptr,
cubeb_resampler_quality quality,
cubeb_resampler_reclock reclock)
cubeb_resampler_quality quality)
{
std::unique_ptr<cubeb_resampler_speex_one_way<T>> input_resampler = nullptr;
std::unique_ptr<cubeb_resampler_speex_one_way<T>> output_resampler = nullptr;

View File

@@ -110,8 +110,8 @@ public:
assert_correct_thread(producer_id);
#endif
int rd_idx = read_index_.load(std::memory_order_relaxed);
int wr_idx = write_index_.load(std::memory_order_relaxed);
int rd_idx = read_index_.load(std::memory_order_acquire);
if (full_internal(rd_idx, wr_idx)) {
return 0;
@@ -154,8 +154,8 @@ public:
assert_correct_thread(consumer_id);
#endif
int rd_idx = read_index_.load(std::memory_order_relaxed);
int wr_idx = write_index_.load(std::memory_order_acquire);
int rd_idx = read_index_.load(std::memory_order_relaxed);
if (empty_internal(rd_idx, wr_idx)) {
return 0;
@@ -172,7 +172,7 @@ public:
}
read_index_.store(increment_index(rd_idx, to_read),
std::memory_order_release);
std::memory_order_relaxed);
return to_read;
}
@@ -190,7 +190,7 @@ public:
#endif
return available_read_internal(
read_index_.load(std::memory_order_relaxed),
write_index_.load(std::memory_order_acquire));
write_index_.load(std::memory_order_relaxed));
}
/**
* Get the number of available elements for consuming.
@@ -205,7 +205,7 @@ public:
assert_correct_thread(producer_id);
#endif
return available_write_internal(
read_index_.load(std::memory_order_acquire),
read_index_.load(std::memory_order_relaxed),
write_index_.load(std::memory_order_relaxed));
}
/**

View File

@@ -11,23 +11,24 @@
#include "cubeb-internal.h"
#include <windows.h>
/* This wraps an SRWLock to track the owner in debug mode, adapted from
/* This wraps a critical section to track the owner in debug mode, adapted from
NSPR and http://blogs.msdn.com/b/oldnewthing/archive/2013/07/12/10433554.aspx
*/
class owned_critical_section {
public:
owned_critical_section()
: srwlock(SRWLOCK_INIT)
#ifndef NDEBUG
,
owner(0)
: owner(0)
#endif
{
InitializeCriticalSection(&critical_section);
}
~owned_critical_section() { DeleteCriticalSection(&critical_section); }
void lock()
{
AcquireSRWLockExclusive(&srwlock);
EnterCriticalSection(&critical_section);
#ifndef NDEBUG
XASSERT(owner != GetCurrentThreadId() && "recursive locking");
owner = GetCurrentThreadId();
@@ -40,7 +41,7 @@ public:
/* GetCurrentThreadId cannot return 0: it is not a the valid thread id */
owner = 0;
#endif
ReleaseSRWLockExclusive(&srwlock);
LeaveCriticalSection(&critical_section);
}
/* This is guaranteed to have the good behaviour if it succeeds. The behaviour
@@ -54,12 +55,12 @@ public:
}
private:
SRWLOCK srwlock;
CRITICAL_SECTION critical_section;
#ifndef NDEBUG
DWORD owner;
#endif
// Disallow copy and assignment because SRWLock cannot be copied.
// Disallow copy and assignment because CRICICAL_SECTION cannot be copied.
owned_critical_section(const owned_critical_section &);
owned_critical_section & operator=(const owned_critical_section &);
};

File diff suppressed because it is too large Load Diff

View File

@@ -73,6 +73,17 @@
#define CUBEB_STREAM_MAX 32
#define NBUFS 4
const GUID KSDATAFORMAT_SUBTYPE_PCM = {
0x00000001,
0x0000,
0x0010,
{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = {
0x00000003,
0x0000,
0x0010,
{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
struct cubeb_stream_item {
SLIST_ENTRY head;
cubeb_stream * stream;