aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/cubeb/cubeb.h21
-rw-r--r--src/cubeb-internal.h4
-rw-r--r--src/cubeb.c41
-rw-r--r--src/cubeb_alsa.c14
-rw-r--r--src/cubeb_audiotrack.c17
-rw-r--r--src/cubeb_audiounit.c14
-rw-r--r--src/cubeb_opensl.c27
-rw-r--r--src/cubeb_pulse.c13
-rw-r--r--src/cubeb_resampler.cpp22
-rw-r--r--src/cubeb_resampler.h3
-rw-r--r--src/cubeb_sndio.c12
-rw-r--r--src/cubeb_wasapi.cpp12
-rw-r--r--src/cubeb_winmm.c20
-rw-r--r--test/test_audio.cpp12
-rw-r--r--test/test_sanity.cpp31
-rw-r--r--test/test_tone.cpp8
16 files changed, 167 insertions, 104 deletions
diff --git a/include/cubeb/cubeb.h b/include/cubeb/cubeb.h
index 4c016e0..4a716a7 100644
--- a/include/cubeb/cubeb.h
+++ b/include/cubeb/cubeb.h
@@ -221,17 +221,21 @@ typedef struct {
} cubeb_device_collection;
/** User supplied data callback.
- @param stream
- @param user_ptr
- @param buffer
- @param nframes
- @retval Number of frames written to buffer, which must equal nframes except
- at end of stream.
+ @param stream The stream for which this callback fired
+ @param user_ptr The pointer passed to cubeb_stream_create
+ @param input_buffer A pointer containing the input data, or nullptr
+ if this is an output-only stream.
+ @param output_buffer A pointer containing the output data, or nullptr
+ if this is an input -only stream.
+ @param nframes The number of frames of the two buffer.
+ @retval Number of frames written to the output buffer, which must equal
+ nframes except at end of stream.
@retval CUBEB_ERROR on error, in which case the data callback will stop
and the stream will enter a shutdown state. */
typedef long (* cubeb_data_callback)(cubeb_stream * stream,
void * user_ptr,
- void * buffer,
+ void * input_buffer,
+ void * output_buffer,
long nframes);
/** User supplied state callback.
@@ -319,7 +323,8 @@ void cubeb_destroy(cubeb * context);
int cubeb_stream_init(cubeb * context,
cubeb_stream ** stream,
char const * stream_name,
- cubeb_stream_params stream_params,
+ cubeb_stream_params * input_stream_params,
+ cubeb_stream_params * output_stream_params,
unsigned int latency,
cubeb_data_callback data_callback,
cubeb_state_callback state_callback,
diff --git a/src/cubeb-internal.h b/src/cubeb-internal.h
index 3235107..15d3b47 100644
--- a/src/cubeb-internal.h
+++ b/src/cubeb-internal.h
@@ -23,7 +23,9 @@ struct cubeb_ops {
cubeb_device_collection ** collection);
void (* destroy)(cubeb * context);
int (* stream_init)(cubeb * context, cubeb_stream ** stream, char const * stream_name,
- cubeb_stream_params stream_params, unsigned int latency,
+ cubeb_stream_params * input_stream_params,
+ cubeb_stream_params * output_stream_params,
+ unsigned int latency,
cubeb_data_callback data_callback,
cubeb_state_callback state_callback,
void * user_ptr);
diff --git a/src/cubeb.c b/src/cubeb.c
index f22e8a9..9fc3196 100644
--- a/src/cubeb.c
+++ b/src/cubeb.c
@@ -61,15 +61,36 @@ int audiotrack_init(cubeb ** context, char const * context_name);
int kai_init(cubeb ** context, char const * context_name);
#endif
+
int
-validate_stream_params(cubeb_stream_params stream_params)
+validate_stream_params(cubeb_stream_params * input_stream_params,
+ cubeb_stream_params * output_stream_params)
{
- if (stream_params.rate < 1000 || stream_params.rate > 192000 ||
- stream_params.channels < 1 || stream_params.channels > 8) {
- return CUBEB_ERROR_INVALID_FORMAT;
+ if (output_stream_params) {
+ if (output_stream_params->rate < 1000 || output_stream_params->rate > 192000 ||
+ output_stream_params->channels < 1 || output_stream_params->channels > 8) {
+ return CUBEB_ERROR_INVALID_FORMAT;
+ }
}
+ if (input_stream_params) {
+ if (input_stream_params->rate < 1000 || input_stream_params->rate > 192000 ||
+ input_stream_params->channels < 1 || input_stream_params->channels > 8) {
+ return CUBEB_ERROR_INVALID_FORMAT;
+ }
+ }
+ // Rate and sample format must be the same for input and output, if using a
+ // duplex stream
+ if (input_stream_params && output_stream_params) {
+ if (input_stream_params->rate != output_stream_params->rate ||
+ input_stream_params->format != output_stream_params->format) {
+ return CUBEB_ERROR_INVALID_FORMAT;
+ }
+ }
+
+ cubeb_stream_params * params = input_stream_params ?
+ input_stream_params : output_stream_params;
- switch (stream_params.format) {
+ switch (params->format) {
case CUBEB_SAMPLE_S16LE:
case CUBEB_SAMPLE_S16BE:
case CUBEB_SAMPLE_FLOAT32LE:
@@ -80,6 +101,8 @@ validate_stream_params(cubeb_stream_params stream_params)
return CUBEB_ERROR_INVALID_FORMAT;
}
+
+
int
validate_latency(int latency)
{
@@ -218,7 +241,9 @@ cubeb_destroy(cubeb * context)
int
cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name,
- cubeb_stream_params stream_params, unsigned int latency,
+ cubeb_stream_params * input_stream_params,
+ cubeb_stream_params * output_stream_params,
+ unsigned int latency,
cubeb_data_callback data_callback,
cubeb_state_callback state_callback,
void * user_ptr)
@@ -229,13 +254,13 @@ cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n
return CUBEB_ERROR_INVALID_PARAMETER;
}
- if ((r = validate_stream_params(stream_params)) != CUBEB_OK ||
+ if ((r = validate_stream_params(input_stream_params, output_stream_params)) != CUBEB_OK ||
(r = validate_latency(latency)) != CUBEB_OK) {
return r;
}
return context->ops->stream_init(context, stream, stream_name,
- stream_params, latency,
+ input_stream_params, output_stream_params, latency,
data_callback,
state_callback,
user_ptr);
diff --git a/src/cubeb_alsa.c b/src/cubeb_alsa.c
index 5e8dab0..5482769 100644
--- a/src/cubeb_alsa.c
+++ b/src/cubeb_alsa.c
@@ -306,7 +306,7 @@ alsa_refill_stream(cubeb_stream * stm)
assert(p);
pthread_mutex_unlock(&stm->mutex);
- got = stm->data_callback(stm, stm->user_ptr, p, avail);
+ got = stm->data_callback(stm, stm->user_ptr, NULL, p, avail);
pthread_mutex_lock(&stm->mutex);
if (got < 0) {
pthread_mutex_unlock(&stm->mutex);
@@ -781,7 +781,9 @@ static void alsa_stream_destroy(cubeb_stream * stm);
static int
alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
- cubeb_stream_params stream_params, unsigned int latency,
+ cubeb_stream_params * input_stream_params,
+ cubeb_stream_params * output_stream_params,
+ unsigned int latency,
cubeb_data_callback data_callback, cubeb_state_callback state_callback,
void * user_ptr)
{
@@ -792,9 +794,11 @@ alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
assert(ctx && stream);
+ assert(!input_stream_params && "not supported.");
+
*stream = NULL;
- switch (stream_params.format) {
+ switch (output_stream_params->format) {
case CUBEB_SAMPLE_S16LE:
format = SND_PCM_FORMAT_S16_LE;
break;
@@ -826,7 +830,7 @@ alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
stm->data_callback = data_callback;
stm->state_callback = state_callback;
stm->user_ptr = user_ptr;
- stm->params = stream_params;
+ stm->params = *output_stream_params;
stm->state = INACTIVE;
stm->volume = 1.0;
@@ -933,7 +937,7 @@ alsa_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
assert(ctx);
- r = alsa_stream_init(ctx, &stm, "", params, 100, NULL, NULL, NULL);
+ r = alsa_stream_init(ctx, &stm, "", NULL, &params, 100, NULL, NULL, NULL);
if (r != CUBEB_OK) {
return CUBEB_ERROR;
}
diff --git a/src/cubeb_audiotrack.c b/src/cubeb_audiotrack.c
index bf85bb8..07851c2 100644
--- a/src/cubeb_audiotrack.c
+++ b/src/cubeb_audiotrack.c
@@ -99,12 +99,11 @@ audiotrack_refill(int event, void* user, void* info)
return;
}
- got = stream->data_callback(stream, stream->user_ptr, b->raw, b->frameCount);
+ got = stream->data_callback(stream, stream->user_ptr, NULL, b->raw, b->frameCount);
stream->written += got;
if (got != (long)b->frameCount) {
- uint32_t p;
stream->draining = 1;
/* set a marker so we are notified when the are done draining, that is,
* when every frame has been played by android. */
@@ -279,7 +278,9 @@ audiotrack_destroy(cubeb * context)
int
audiotrack_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
- cubeb_stream_params stream_params, unsigned int latency,
+ cubeb_stream_params * input_stream_params,
+ cubeb_stream_params * output_stream_params,
+ unsigned int latency,
cubeb_data_callback data_callback,
cubeb_state_callback state_callback,
void * user_ptr)
@@ -290,12 +291,14 @@ audiotrack_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_
assert(ctx && stream);
- if (stream_params.format == CUBEB_SAMPLE_FLOAT32LE ||
- stream_params.format == CUBEB_SAMPLE_FLOAT32BE) {
+ assert(!input_stream_params && "not supported");
+
+ if (output_stream_params->format == CUBEB_SAMPLE_FLOAT32LE ||
+ output_stream_params->format == CUBEB_SAMPLE_FLOAT32BE) {
return CUBEB_ERROR_INVALID_FORMAT;
}
- if (audiotrack_get_min_frame_count(ctx, &stream_params, (int *)&min_frame_count)) {
+ if (audiotrack_get_min_frame_count(ctx, output_stream_params, (int *)&min_frame_count)) {
return CUBEB_ERROR;
}
@@ -306,7 +309,7 @@ audiotrack_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_
stm->data_callback = data_callback;
stm->state_callback = state_callback;
stm->user_ptr = user_ptr;
- stm->params = stream_params;
+ stm->params = *output_stream_params;
stm->instance = calloc(SIZE_AUDIOTRACK_INSTANCE, 1);
(*(uint32_t*)((intptr_t)stm->instance + SIZE_AUDIOTRACK_INSTANCE - 4)) = 0xbaadbaad;
diff --git a/src/cubeb_audiounit.c b/src/cubeb_audiounit.c
index 7506107..4d59637 100644
--- a/src/cubeb_audiounit.c
+++ b/src/cubeb_audiounit.c
@@ -136,7 +136,7 @@ audiounit_output_callback(void * user_ptr, AudioUnitRenderActionFlags * flags,
}
pthread_mutex_unlock(&stm->mutex);
- got = stm->data_callback(stm, stm->user_ptr, buf, nframes);
+ got = stm->data_callback(stm, stm->user_ptr, NULL, buf, nframes);
pthread_mutex_lock(&stm->mutex);
if (got < 0) {
/* XXX handle this case. */
@@ -539,7 +539,9 @@ static void audiounit_stream_destroy(cubeb_stream * stm);
static int
audiounit_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name,
- cubeb_stream_params stream_params, unsigned int latency,
+ cubeb_stream_params * input_stream_params,
+ cubeb_stream_params * output_stream_params,
+ unsigned int latency,
cubeb_data_callback data_callback, cubeb_state_callback state_callback,
void * user_ptr)
{
@@ -558,13 +560,15 @@ audiounit_stream_init(cubeb * context, cubeb_stream ** stream, char const * stre
UInt32 size;
AudioValueRange latency_range;
+ assert(!input_stream_params && "not supported");
+
assert(context);
*stream = NULL;
memset(&ss, 0, sizeof(ss));
ss.mFormatFlags = 0;
- switch (stream_params.format) {
+ switch (output_stream_params->format) {
case CUBEB_SAMPLE_S16LE:
ss.mBitsPerChannel = 16;
ss.mFormatFlags |= kAudioFormatFlagIsSignedInteger;
@@ -589,8 +593,8 @@ audiounit_stream_init(cubeb * context, cubeb_stream ** stream, char const * stre
ss.mFormatID = kAudioFormatLinearPCM;
ss.mFormatFlags |= kLinearPCMFormatFlagIsPacked;
- ss.mSampleRate = stream_params.rate;
- ss.mChannelsPerFrame = stream_params.channels;
+ ss.mSampleRate = output_stream_params->rate;
+ ss.mChannelsPerFrame = output_stream_params->channels;
ss.mBytesPerFrame = (ss.mBitsPerChannel / 8) * ss.mChannelsPerFrame;
ss.mFramesPerPacket = 1;
diff --git a/src/cubeb_opensl.c b/src/cubeb_opensl.c
index 526aef0..cf721f6 100644
--- a/src/cubeb_opensl.c
+++ b/src/cubeb_opensl.c
@@ -120,7 +120,7 @@ bufferqueue_callback(SLBufferQueueItf caller, void * user_ptr)
pthread_mutex_unlock(&stm->mutex);
if (!draining) {
- written = cubeb_resampler_fill(stm->resampler, buf,
+ written = cubeb_resampler_fill(stm->resampler, NULL, buf,
stm->queuebuf_len / stm->framesize);
if (written < 0 || written * stm->framesize > stm->queuebuf_len) {
(*stm->play)->SetPlayState(stm->play, SL_PLAYSTATE_PAUSED);
@@ -465,17 +465,20 @@ static void opensl_stream_destroy(cubeb_stream * stm);
static int
opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
- cubeb_stream_params stream_params, unsigned int latency,
+ cubeb_stream_params * input_stream_params,
+ cubeb_stream_params * output_stream_params,
+ unsigned int latency,
cubeb_data_callback data_callback, cubeb_state_callback state_callback,
void * user_ptr)
{
cubeb_stream * stm;
assert(ctx);
+ assert(!input_stream_params && "not supported");
*stream = NULL;
- if (stream_params.channels < 1 || stream_params.channels > 32 ||
+ if (output_stream_params->channels < 1 || output_stream_params->channels > 32 ||
latency < 1 || latency > 2000) {
return CUBEB_ERROR_INVALID_FORMAT;
}
@@ -483,16 +486,16 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name
SLDataFormat_PCM format;
format.formatType = SL_DATAFORMAT_PCM;
- format.numChannels = stream_params.channels;
+ format.numChannels = output_stream_params->channels;
// samplesPerSec is in milliHertz
- format.samplesPerSec = stream_params.rate * 1000;
+ format.samplesPerSec = output_stream_params->rate * 1000;
format.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
format.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
- format.channelMask = stream_params.channels == 1 ?
+ format.channelMask = output_stream_params->channels == 1 ?
SL_SPEAKER_FRONT_CENTER :
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
- switch (stream_params.format) {
+ switch (output_stream_params->format) {
case CUBEB_SAMPLE_S16LE:
format.endianness = SL_BYTEORDER_LITTLEENDIAN;
break;
@@ -511,10 +514,10 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name
stm->state_callback = state_callback;
stm->user_ptr = user_ptr;
- stm->inputrate = stream_params.rate;
+ stm->inputrate = output_stream_params->rate;
stm->latency = latency;
- stm->stream_type = stream_params.stream_type;
- stm->framesize = stream_params.channels * sizeof(int16_t);
+ stm->stream_type = output_stream_params->stream_type;
+ stm->framesize = output_stream_params->channels * sizeof(int16_t);
stm->lastPosition = -1;
stm->lastPositionTimeStamp = 0;
stm->lastCompensativePosition = -1;
@@ -575,7 +578,7 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name
stm->queuebuf_len += stm->framesize - (stm->queuebuf_len % stm->framesize);
}
- stm->resampler = cubeb_resampler_create(stm, stream_params,
+ stm->resampler = cubeb_resampler_create(stm, *output_stream_params,
preferred_sampling_rate,
data_callback,
stm->queuebuf_len / stm->framesize,
@@ -594,7 +597,7 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name
}
#if defined(__ANDROID__)
- SLuint32 stream_type = convert_stream_type_to_sl_stream(stream_params.stream_type);
+ SLuint32 stream_type = convert_stream_type_to_sl_stream(output_stream_params->stream_type);
if (stream_type != 0xFFFFFFFF) {
SLAndroidConfigurationItf playerConfig;
res = (*stm->playerObj)->GetInterface(stm->playerObj,
diff --git a/src/cubeb_pulse.c b/src/cubeb_pulse.c
index ef35661..1fd997e 100644
--- a/src/cubeb_pulse.c
+++ b/src/cubeb_pulse.c
@@ -198,7 +198,7 @@ stream_request_callback(pa_stream * s, size_t nbytes, void * u)
assert(size > 0);
assert(size % frame_size == 0);
- got = stm->data_callback(stm, stm->user_ptr, buffer, size / frame_size);
+ got = stm->data_callback(stm, stm->user_ptr, NULL, buffer, size / frame_size);
if (got < 0) {
WRAP(pa_stream_cancel_write)(s);
stm->shutdown = 1;
@@ -487,7 +487,9 @@ static void pulse_stream_destroy(cubeb_stream * stm);
static int
pulse_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name,
- cubeb_stream_params stream_params, unsigned int latency,
+ cubeb_stream_params * input_stream_params,
+ cubeb_stream_params * output_stream_params,
+ unsigned int latency,
cubeb_data_callback data_callback, cubeb_state_callback state_callback,
void * user_ptr)
{
@@ -498,10 +500,11 @@ pulse_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n
int r;
assert(context);
+ assert(!input_stream_params && "not supported.");
*stream = NULL;
- switch (stream_params.format) {
+ switch (output_stream_params->format) {
case CUBEB_SAMPLE_S16LE:
ss.format = PA_SAMPLE_S16LE;
break;
@@ -523,8 +526,8 @@ pulse_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n
return CUBEB_ERROR;
}
- ss.rate = stream_params.rate;
- ss.channels = stream_params.channels;
+ ss.rate = output_stream_params->rate;
+ ss.channels = output_stream_params->channels;
stm = calloc(1, sizeof(*stm));
assert(stm);
diff --git a/src/cubeb_resampler.cpp b/src/cubeb_resampler.cpp
index 682650a..e8fd7a1 100644
--- a/src/cubeb_resampler.cpp
+++ b/src/cubeb_resampler.cpp
@@ -72,7 +72,7 @@ to_speex_quality(cubeb_resampler_quality q)
} // end of anonymous namespace
struct cubeb_resampler {
- virtual long fill(void * buffer, long frames_needed) = 0;
+ virtual long fill(void * input_buffer, void * output_buffer, long frames_needed) = 0;
virtual ~cubeb_resampler() {}
};
@@ -87,9 +87,9 @@ public:
{
}
- virtual long fill(void * buffer, long frames_needed)
+ virtual long fill(void * input_buffer, void * output_buffer, long frames_needed)
{
- long got = data_callback(stream, user_ptr, buffer, frames_needed);
+ long got = data_callback(stream, user_ptr, input_buffer, output_buffer, frames_needed);
assert(got <= frames_needed);
return got;
}
@@ -109,7 +109,7 @@ public:
virtual ~cubeb_resampler_speex();
- virtual long fill(void * buffer, long frames_needed);
+ virtual long fill(void * input_buffer, void * output_buffer, long frames_needed);
private:
SpeexResamplerState * const speex_resampler;
@@ -164,7 +164,7 @@ cubeb_resampler_speex::~cubeb_resampler_speex()
}
long
-cubeb_resampler_speex::fill(void * buffer, long frames_needed)
+cubeb_resampler_speex::fill(void * input_buffer, void * output_buffer, long frames_needed)
{
// Use more input frames than strictly necessary, so in the worst case,
// we have leftover unresampled frames at the end, that we can use
@@ -178,7 +178,7 @@ cubeb_resampler_speex::fill(void * buffer, long frames_needed)
memcpy(resampling_src_buffer.get(), leftover_frames_buffer.get(), leftover_bytes);
uint8_t * buffer_start = resampling_src_buffer.get() + leftover_bytes;
- long got = data_callback(stream, user_ptr, buffer_start, frames_requested);
+ long got = data_callback(stream, user_ptr, NULL, buffer_start, frames_requested);
assert(got <= frames_requested);
if (got < 0) {
@@ -191,12 +191,12 @@ cubeb_resampler_speex::fill(void * buffer, long frames_needed)
if (stream_params.format == CUBEB_SAMPLE_FLOAT32NE) {
float * in_buffer = reinterpret_cast<float *>(resampling_src_buffer.get());
- float * out_buffer = reinterpret_cast<float *>(buffer);
+ float * out_buffer = reinterpret_cast<float *>(output_buffer);
speex_resampler_process_interleaved_float(speex_resampler, in_buffer, &in_frames,
out_buffer, &out_frames);
} else {
short * in_buffer = reinterpret_cast<short *>(resampling_src_buffer.get());
- short * out_buffer = reinterpret_cast<short *>(buffer);
+ short * out_buffer = reinterpret_cast<short *>(output_buffer);
speex_resampler_process_interleaved_int(speex_resampler, in_buffer, &in_frames,
out_buffer, &out_frames);
}
@@ -242,9 +242,11 @@ cubeb_resampler_create(cubeb_stream * stream,
long
cubeb_resampler_fill(cubeb_resampler * resampler,
- void * buffer, long frames_needed)
+ void * input_buffer,
+ void * output_buffer,
+ long frames_needed)
{
- return resampler->fill(buffer, frames_needed);
+ return resampler->fill(input_buffer, output_buffer, frames_needed);
}
void
diff --git a/src/cubeb_resampler.h b/src/cubeb_resampler.h
index e63c2c1..64f5d58 100644
--- a/src/cubeb_resampler.h
+++ b/src/cubeb_resampler.h
@@ -53,7 +53,8 @@ cubeb_resampler * cubeb_resampler_create(cubeb_stream * stream,
* @retval CUBEB_ERROR on error.
*/
long cubeb_resampler_fill(cubeb_resampler * resampler,
- void * buffer, long frames_needed);
+ void * input_buffer,
+ void * output_buffer, long frames_needed);
/**
* Destroy a cubeb_resampler.
diff --git a/src/cubeb_sndio.c b/src/cubeb_sndio.c
index 94f9961..c0e3427 100644
--- a/src/cubeb_sndio.c
+++ b/src/cubeb_sndio.c
@@ -173,7 +173,9 @@ static int
sndio_stream_init(cubeb *context,
cubeb_stream **stream,
char const *stream_name,
- cubeb_stream_params stream_params, unsigned int latency,
+ cubeb_stream_params * input_stream_params,
+ cubeb_stream_params * output_stream_params,
+ unsigned int latency,
cubeb_data_callback data_callback,
cubeb_state_callback state_callback,
void *user_ptr)
@@ -196,7 +198,7 @@ sndio_stream_init(cubeb *context,
sio_initpar(&wpar);
wpar.sig = 1;
wpar.bits = 16;
- switch (stream_params.format) {
+ switch (output_stream_params->format) {
case CUBEB_SAMPLE_S16LE:
wpar.le = 1;
break;
@@ -210,8 +212,8 @@ sndio_stream_init(cubeb *context,
DPR("sndio_stream_init() unsupported format\n");
return CUBEB_ERROR_INVALID_FORMAT;
}
- wpar.rate = stream_params.rate;
- wpar.pchan = stream_params.channels;
+ wpar.rate = output_stream_params->rate;
+ wpar.pchan = output_stream_params->channels;
wpar.appbufsz = latency * wpar.rate / 1000;
if (!sio_setpar(s->hdl, &wpar) || !sio_getpar(s->hdl, &rpar)) {
sio_close(s->hdl);
@@ -237,7 +239,7 @@ sndio_stream_init(cubeb *context,
s->arg = user_ptr;
s->mtx = PTHREAD_MUTEX_INITIALIZER;
s->rdpos = s->wrpos = 0;
- if (stream_params.format == CUBEB_SAMPLE_FLOAT32LE) {
+ if (output_stream_params->format == CUBEB_SAMPLE_FLOAT32LE) {
s->conv = 1;
size = rpar.round * rpar.pchan * sizeof(float);
} else {
diff --git a/src/cubeb_wasapi.cpp b/src/cubeb_wasapi.cpp
index 3c780e6..d81343c 100644
--- a/src/cubeb_wasapi.cpp
+++ b/src/cubeb_wasapi.cpp
@@ -472,7 +472,7 @@ refill(cubeb_stream * stm, float * data, long frames_needed)
dest = data;
}
- long out_frames = cubeb_resampler_fill(stm->resampler, dest, frames_needed);
+ long out_frames = cubeb_resampler_fill(stm->resampler, NULL, dest, frames_needed);
/* TODO: Report out_frames < 0 as an error via the API. */
XASSERT(out_frames >= 0);
@@ -1201,7 +1201,9 @@ int setup_wasapi_stream(cubeb_stream * stm)
int
wasapi_stream_init(cubeb * context, cubeb_stream ** stream,
- char const * stream_name, cubeb_stream_params stream_params,
+ char const * stream_name,
+ cubeb_stream_params * input_stream_params,
+ cubeb_stream_params * output_stream_params,
unsigned int latency, cubeb_data_callback data_callback,
cubeb_state_callback state_callback, void * user_ptr)
{
@@ -1212,9 +1214,11 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream,
return CUBEB_ERROR;
}
+ XASSERT(!input_stream_params && "not supported.");
+
XASSERT(context && stream);
- if (stream_params.format != CUBEB_SAMPLE_FLOAT32NE) {
+ if (output_stream_params->format != CUBEB_SAMPLE_FLOAT32NE) {
return CUBEB_ERROR_INVALID_FORMAT;
}
@@ -1226,7 +1230,7 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream,
stm->data_callback = data_callback;
stm->state_callback = state_callback;
stm->user_ptr = user_ptr;
- stm->stream_params = stream_params;
+ stm->stream_params = *output_stream_params;
stm->draining = false;
stm->latency = latency;
stm->volume = 1.0;
diff --git a/src/cubeb_winmm.c b/src/cubeb_winmm.c
index da5828f..8fe73fb 100644
--- a/src/cubeb_winmm.c
+++ b/src/cubeb_winmm.c
@@ -179,7 +179,7 @@ winmm_refill_stream(cubeb_stream * stm)
/* It is assumed that the caller is holding this lock. It must be dropped
during the callback to avoid deadlocks. */
LeaveCriticalSection(&stm->lock);
- got = stm->data_callback(stm, stm->user_ptr, hdr->lpData, wanted);
+ got = stm->data_callback(stm, stm->user_ptr, NULL, NULL, hdr->lpData, wanted);
EnterCriticalSection(&stm->lock);
if (got < 0) {
LeaveCriticalSection(&stm->lock);
@@ -380,7 +380,9 @@ static void winmm_stream_destroy(cubeb_stream * stm);
static int
winmm_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name,
- cubeb_stream_params stream_params, unsigned int latency,
+ cubeb_stream_params * input_stream_params,
+ cubeb_stream_params * output_stream_params,
+ unsigned int latency,
cubeb_data_callback data_callback,
cubeb_state_callback state_callback,
void * user_ptr)
@@ -394,26 +396,28 @@ winmm_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n
XASSERT(context);
XASSERT(stream);
+ XASSERT(input_stream_params && "not supported.");
+
*stream = NULL;
memset(&wfx, 0, sizeof(wfx));
- if (stream_params.channels > 2) {
+ if (output_stream_params->channels > 2) {
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.cbSize = sizeof(wfx) - sizeof(wfx.Format);
} else {
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
- if (stream_params.format == CUBEB_SAMPLE_FLOAT32LE) {
+ if (output_stream_params->format == CUBEB_SAMPLE_FLOAT32LE) {
wfx.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
}
wfx.Format.cbSize = 0;
}
- wfx.Format.nChannels = stream_params.channels;
- wfx.Format.nSamplesPerSec = stream_params.rate;
+ wfx.Format.nChannels = output_stream_params->channels;
+ wfx.Format.nSamplesPerSec = output_stream_params->rate;
/* XXX fix channel mappings */
wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
- switch (stream_params.format) {
+ switch (output_stream_params->format) {
case CUBEB_SAMPLE_S16LE:
wfx.Format.wBitsPerSample = 16;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
@@ -446,7 +450,7 @@ winmm_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n
stm->context = context;
- stm->params = stream_params;
+ stm->params = *output_stream_params;
stm->data_callback = data_callback;
stm->state_callback = state_callback;
diff --git a/test/test_audio.cpp b/test/test_audio.cpp
index 6a6ebf5..c6b143f 100644
--- a/test/test_audio.cpp
+++ b/test/test_audio.cpp
@@ -73,10 +73,10 @@ void synth_run_float(synth_state* synth, float* audiobuffer, long nframes)
}
}
-long data_cb_float(cubeb_stream *stream, void *user, void *buffer, long nframes)
+long data_cb_float(cubeb_stream *stream, void *user, void * inputbuffer, void *outputbuffer, long nframes)
{
synth_state *synth = (synth_state *)user;
- synth_run_float(synth, (float*)buffer, nframes);
+ synth_run_float(synth, (float*)outputbuffer, nframes);
return nframes;
}
@@ -92,10 +92,10 @@ void synth_run_16bit(synth_state* synth, short* audiobuffer, long nframes)
}
}
-long data_cb_short(cubeb_stream *stream, void *user, void *buffer, long nframes)
+long data_cb_short(cubeb_stream *stream, void *user, void * inputbuffer, void *outputbuffer, long nframes)
{
synth_state *synth = (synth_state *)user;
- synth_run_16bit(synth, (short*)buffer, nframes);
+ synth_run_16bit(synth, (short*)outputbuffer, nframes);
return nframes;
}
@@ -160,7 +160,7 @@ int run_test(int num_channels, int sampling_rate, int is_float)
goto cleanup;
}
- r = cubeb_stream_init(ctx, &stream, "test tone", params,
+ r = cubeb_stream_init(ctx, &stream, "test tone", nullptr, &params,
100, is_float ? data_cb_float : data_cb_short, state_cb, synth);
if (r != CUBEB_OK) {
fprintf(stderr, "Error initializing cubeb stream: %d\n", r);
@@ -212,7 +212,7 @@ int run_panning_volume_test(int is_float)
goto cleanup;
}
- r = cubeb_stream_init(ctx, &stream, "test tone", params,
+ r = cubeb_stream_init(ctx, &stream, "test tone", NULL, &params,
100, is_float ? data_cb_float : data_cb_short, state_cb, synth);
if (r != CUBEB_OK) {
fprintf(stderr, "Error initializing cubeb stream: %d\n", r);
diff --git a/test/test_sanity.cpp b/test/test_sanity.cpp
index ca9ca1b..f04be32 100644
--- a/test/test_sanity.cpp
+++ b/test/test_sanity.cpp
@@ -40,13 +40,14 @@ static uint64_t total_frames_written;
static int delay_callback;
static long
-test_data_callback(cubeb_stream * stm, void * user_ptr, void * p, long nframes)
+test_data_callback(cubeb_stream * stm, void * user_ptr, void * inputbuffer, void * outputbuffer, long nframes)
{
- assert(stm && user_ptr == &dummy && p && nframes > 0);
+ assert(stm && user_ptr == &dummy && outputbuffer && nframes > 0);
+ memset(outputbuffer, 0, nframes * sizeof(short));
#if (defined(_WIN32) || defined(__WIN32__))
- memset(p, 0, nframes * sizeof(float));
+ memset(outputbuffer, 0, nframes * sizeof(float));
#else
- memset(p, 0, nframes * sizeof(short));
+ memset(outputbuffer, 0, nframes * sizeof(short));
#endif
total_frames_written += nframes;
@@ -158,7 +159,7 @@ test_init_destroy_stream(void)
params.rate = STREAM_RATE;
params.channels = STREAM_CHANNELS;
- r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY,
+ r = cubeb_stream_init(ctx, &stream, "test", nullptr, &params, STREAM_LATENCY,
test_data_callback, test_state_callback, &dummy);
assert(r == 0 && stream);
@@ -187,7 +188,7 @@ test_init_destroy_multiple_streams(void)
params.channels = STREAM_CHANNELS;
for (i = 0; i < ARRAY_LENGTH(stream); ++i) {
- r = cubeb_stream_init(ctx, &stream[i], "test", params, STREAM_LATENCY,
+ r = cubeb_stream_init(ctx, &stream[i], "test", NULL, &params, STREAM_LATENCY,
test_data_callback, test_state_callback, &dummy);
assert(r == 0);
assert(stream[i]);
@@ -219,7 +220,7 @@ test_configure_stream(void)
params.rate = STREAM_RATE;
params.channels = 2; // panning
- r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY,
+ r = cubeb_stream_init(ctx, &stream, "test", NULL, &params, STREAM_LATENCY,
test_data_callback, test_state_callback, &dummy);
assert(r == 0 && stream);
@@ -253,7 +254,7 @@ test_init_start_stop_destroy_multiple_streams(int early, int delay_ms)
params.channels = STREAM_CHANNELS;
for (i = 0; i < ARRAY_LENGTH(stream); ++i) {
- r = cubeb_stream_init(ctx, &stream[i], "test", params, STREAM_LATENCY,
+ r = cubeb_stream_init(ctx, &stream[i], "test", NULL, &params, STREAM_LATENCY,
test_data_callback, test_state_callback, &dummy);
assert(r == 0);
assert(stream[i]);
@@ -317,7 +318,7 @@ test_init_destroy_multiple_contexts_and_streams(void)
assert(r == 0 && ctx[i]);
for (j = 0; j < streams_per_ctx; ++j) {
- r = cubeb_stream_init(ctx[i], &stream[i * streams_per_ctx + j], "test", params, STREAM_LATENCY,
+ r = cubeb_stream_init(ctx[i], &stream[i * streams_per_ctx + j], "test", NULL, &params, STREAM_LATENCY,
test_data_callback, test_state_callback, &dummy);
assert(r == 0);
assert(stream[i * streams_per_ctx + j]);
@@ -352,7 +353,7 @@ test_basic_stream_operations(void)
params.rate = STREAM_RATE;
params.channels = STREAM_CHANNELS;
- r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY,
+ r = cubeb_stream_init(ctx, &stream, "test", NULL, &params, STREAM_LATENCY,
test_data_callback, test_state_callback, &dummy);
assert(r == 0 && stream);
@@ -401,7 +402,7 @@ test_stream_position(void)
params.rate = STREAM_RATE;
params.channels = STREAM_CHANNELS;
- r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY,
+ r = cubeb_stream_init(ctx, &stream, "test", NULL, &params, STREAM_LATENCY,
test_data_callback, test_state_callback, &dummy);
assert(r == 0 && stream);
@@ -474,16 +475,16 @@ static int do_drain;
static int got_drain;
static long
-test_drain_data_callback(cubeb_stream * stm, void * user_ptr, void * p, long nframes)
+test_drain_data_callback(cubeb_stream * stm, void * user_ptr, void * inputbuffer, void * outputbuffer, long nframes)
{
- assert(stm && user_ptr == &dummy && p && nframes > 0);
+ assert(stm && user_ptr == &dummy && outputbuffer && nframes > 0);
if (do_drain == 1) {
do_drain = 2;
return 0;
}
/* once drain has started, callback must never be called again */
assert(do_drain != 2);
- memset(p, 0, nframes * sizeof(short));
+ memset(outputbuffer, 0, nframes * sizeof(short));
total_frames_written += nframes;
return nframes;
}
@@ -517,7 +518,7 @@ test_drain(void)
params.rate = STREAM_RATE;
params.channels = STREAM_CHANNELS;
- r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY,
+ r = cubeb_stream_init(ctx, &stream, "test", NULL, &params, STREAM_LATENCY,
test_drain_data_callback, test_drain_state_callback, &dummy);
assert(r == 0 && stream);
diff --git a/test/test_tone.cpp b/test/test_tone.cpp
index d0cee22..59362f6 100644
--- a/test/test_tone.cpp
+++ b/test/test_tone.cpp
@@ -34,13 +34,13 @@ struct cb_user_data {
long position;
};
-long data_cb(cubeb_stream *stream, void *user, void *buffer, long nframes)
+long data_cb(cubeb_stream *stream, void *user, void* inputbuffer, void *outputbuffer, long nframes)
{
struct cb_user_data *u = (struct cb_user_data *)user;
#if (defined(_WIN32) || defined(__WIN32__))
- float *b = (float *)buffer;
+ float *b = (float *)outputbuffer;
#else
- short *b = (short *)buffer;
+ short *b = (short *)outputbuffer;
#endif
float t1, t2;
int i;
@@ -127,7 +127,7 @@ int main(int argc, char *argv[])
}
user_data->position = 0;
- r = cubeb_stream_init(ctx, &stream, "Cubeb tone (mono)", params,
+ r = cubeb_stream_init(ctx, &stream, "Cubeb tone (mono)", nullptr, &params,
250, data_cb, state_cb, user_data);
if (r != CUBEB_OK) {
fprintf(stderr, "Error initializing cubeb stream\n");