aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorPaul Adenot <[email protected]>2016-01-13 17:16:50 +0100
committerPaul Adenot <[email protected]>2016-01-13 17:36:53 +0100
commit46e32bdac90233b0a4e59d9b7d4319a28bf496ae (patch)
tree0e7d58fc9709e8a0d2e59d1a00ea7158e29e9a0c /src
parent23a17cb4f9ed2de78a0df5ecdfefbbe47dc83c35 (diff)
downloadcubeb-46e32bdac90233b0a4e59d9b7d4319a28bf496ae.tar.gz
cubeb-46e32bdac90233b0a4e59d9b7d4319a28bf496ae.zip
Preparatory work for the input and duplex code
This is changing all the signatures of the `cubeb_stream_init` implementations, the signature of the `data_callback` type, so that cubeb can support audio input. `cubeb_stream_init` now has two `cubeb_stream_params` pointers, one for input, one for output. If two pointers are passed, a "duplex" stream is opened. If only one pointer is passed, an input-only or output-only stream is created. Duplex streams have the same sample rate, and sample type. They don't have to have the same number of channels. `data_callback` now has two pointers to audio buffers: an input buffer (`NULL` if this is an output-only stream) containing input data (e.g. a microphone), and an output buffer, to be filled, as usual, with the audio frames to play. The two buffers always have the exact same number of audio frames, and are temporally correlated in a way that ensures the minimal loop-back latency on the system if one directly copies the input buffer to the output buffer. No functionnal changes are present in this patch, just signature changes. Asserts have been added to prevent users to try to use the input code path for now. Actual implementations with the input code for different platforms will follow. Green `mozilla-central` push: <https://treeherder.mozilla.org/#/jobs?repo=try&revision=15b4dd3cbbe8>
Diffstat (limited to 'src')
-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
12 files changed, 128 insertions, 71 deletions
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;