diff options
author | Paul Adenot <[email protected]> | 2016-01-13 17:16:50 +0100 |
---|---|---|
committer | Paul Adenot <[email protected]> | 2016-01-13 17:36:53 +0100 |
commit | 46e32bdac90233b0a4e59d9b7d4319a28bf496ae (patch) | |
tree | 0e7d58fc9709e8a0d2e59d1a00ea7158e29e9a0c /src | |
parent | 23a17cb4f9ed2de78a0df5ecdfefbbe47dc83c35 (diff) | |
download | cubeb-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.h | 4 | ||||
-rw-r--r-- | src/cubeb.c | 41 | ||||
-rw-r--r-- | src/cubeb_alsa.c | 14 | ||||
-rw-r--r-- | src/cubeb_audiotrack.c | 17 | ||||
-rw-r--r-- | src/cubeb_audiounit.c | 14 | ||||
-rw-r--r-- | src/cubeb_opensl.c | 27 | ||||
-rw-r--r-- | src/cubeb_pulse.c | 13 | ||||
-rw-r--r-- | src/cubeb_resampler.cpp | 22 | ||||
-rw-r--r-- | src/cubeb_resampler.h | 3 | ||||
-rw-r--r-- | src/cubeb_sndio.c | 12 | ||||
-rw-r--r-- | src/cubeb_wasapi.cpp | 12 | ||||
-rw-r--r-- | src/cubeb_winmm.c | 20 |
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, ¶ms, 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; |