Comments (6)
Thanks for the taking the time to investigate this. The MONO, NONE, NONE channel map was a surprise to me. I'll review your findings ASAP and report back.
from miniaudio.
Well mono means 1, so it doesn't make sense to have more than one channel for a mono stream. For example, if a microphone is capturing a monaural stream, why would it ever make sense to report anything more than 1 channel?
What is the specific contents of the channel map? Is it MONO, FRONT_LEFT, FRONT_RIGHT? If so, that makes no sense and will be why that validation is failing.
from miniaudio.
Thank you for your answer, I have tried again and it seems the content of channel map is:
MA_CHANNEL_MONO,
MA_CHANNEL_NONE,
MA_CHANNEL_NONE
After diving into miniaudio code my understanding is:
In function ma_device_init__pulse
:
cmap = sourceInfo.channel_map;
At this point cmap = [1,2,7,0,0,0,0,...]
/* Use a default channel map. */ ((ma_pa_channel_map_init_extend_proc)pDevice->pContext->pulse.pa_channel_map_init_extend)(&cmap, ss.channels, MA_PA_CHANNEL_MAP_DEFAULT);
After this call: cmap = [0,-1,-1,-1,-1,-1,-1,...]
Then descriptorCapture.channelMap = [1,0,0,0,0,0,0,...]
.
Then device->capture.internalChannelMap = descriptorCapture->channelMap
.
Then converterConfig.pChannelMapIn = pDevice->capture.internalChannelMap
.
Then ma_channel_map_is_valid(pConfig->pChannelMapIn, pConfig->channelsIn)
returns false
.
from miniaudio.
I think I have found a problem.
ss.channels
value is 3 but it is overwritten to 1:
/* Use the requested channel count if we have one. */
if (pDescriptorCapture->channels != 0) {
ss.channels = pDescriptorCapture->channels;
}
Then cmap
is overwritten with a default channel map with 1 channel (cmap = [0,-1,-1,-1,-1,-1,-1,...]
):
/* Use a default channel map. */
((ma_pa_channel_map_init_extend_proc)pDevice->pContext->pulse.pa_channel_map_init_extend)(&cmap, ss.channels, MA_PA_CHANNEL_MAP_DEFAULT);
Then ss
is overwritten by pActualSS
, so ss.channels
value changes from 1 to 3:
/* Internal format. */
pActualSS = ((ma_pa_stream_get_sample_spec_proc)pDevice->pContext->pulse.pa_stream_get_sample_spec)((ma_pa_stream*)pDevice->pulse.pStreamCapture);
if (pActualSS != NULL) {
ss = *pActualSS;
Then cmap
is copied in pDescriptorCapture->channelMap
with 3 channels however it maps only 1 channel.
pDescriptorCapture->channels = ss.channels;
...
if (pDescriptorCapture->channels > 2) {
for (iChannel = 0; iChannel < pDescriptorCapture->channels; ++iChannel) {
pDescriptorCapture->channelMap[iChannel] = ma_channel_position_from_pulse(cmap.map[iChannel]);
}
}
from miniaudio.
Sorry for the delay on this one. I've pushed a potential fix for this to the dev branch if you were wanting to try that out. It now queries the channel map after creating the stream and uses that instead of the cmap
channel map that's constructed prior to creating the stream.
from miniaudio.
Hello, thanks for looking at my issue.
I have tested on the dev branch and it works, however after debugging I have found that the issue has been fixed by this commit #701.
Before this commit, the flag MA_PA_STREAM_FIX_CHANNELS
was added (in my case) to streamFlags
and that's why ss.channels
changes back from 1 to 3:
/* Internal format. */
pActualSS = ((ma_pa_stream_get_sample_spec_proc)pDevice->pContext->pulse.pa_stream_get_sample_spec)((ma_pa_stream*)pDevice->pulse.pStreamCapture);
if (pActualSS != NULL) {
ss = *pActualSS;
MA_PA_STREAM_FIX_CHANNELS: Use the number of channels and the channel map of the sink, and possibly ignore the number of channels and the map the sample spec and the passed channel map contain.
ref
After the fix, I was a bit surprised by miniaudio logs:
[PulseAudio] Capture attr: maxlength=6144, tlength=2048, prebuf=-1, minreq=-1, fragsize=2048; periodSizeInFrames=512
[PulseAudio] Capture sample spec: format=32-bit Signed Integer, channels=1, rate=16000
[PulseAudio] Capture actual attr: maxlength=8192, tlength=2048, prebuf=-1, minreq=-1, fragsize=2048; periodSizeInFrames=512
[PulseAudio]
Scarlett 4i4 USB Analog Surround 2.1 (Capture)
Format: 32-bit Signed Integer -> 16-bit Signed Integer
Channels: 1 -> 1
Sample Rate: 16000 -> 16000
Buffer Size: 512*4 (2048)
Conversion:
Pre Format Conversion: NO
Post Format Conversion: YES
Channel Routing: NO
Resampling: NO
Passthrough: NO
Channel Map In: {CHANNEL_MONO}
Channel Map Out: {CHANNEL_MONO}
Channels: 1 -> 1
surprised me at first but I think it is pulseaudio that does the 3->1 channel mapping and not miniaudio so miniaudio does a simple 1->1 mapping.
from miniaudio.
Related Issues (20)
- Add dedicated spatialization example?
- ma_engine_uninit on windows causes Application Verifier breakpoint HOT 1
- [OSX/MacOS] Capture volume out of range ? HOT 10
- iOS: Some phones fail to init AudioUnit when using shared context HOT 3
- Android: Build failure of dev branch due to pthread_attr_setinheritsched HOT 2
- WASM duplicate symbol HOT 3
- Emscripten WASM Thread Problem HOT 2
- Question about Attenuation in Miniaudio. HOT 1
- Javascript error after uninitializing miniaudio HOT 4
- Does miniaudio support encoding PCM sample data into ADPCM sample data? HOT 1
- Uncaught RuntimeError: memory access out of bounds after starting playing the sound. HOT 8
- DELETED HOT 1
- Miniaudio waiting infinitely when calling ma_engine_uninit HOT 1
- Is there a way to gracefully shut down all threads created by miniaudio when the application exits? HOT 1
- Channel Convert Init Access Violation going from 2 channels to >2 channels HOT 2
- Sound system lags when playing sounds quickly and using delay or reverb HOT 1
- ma_device_uninit crash on Android <= 10 HOT 3
- error when compiling on android HOT 1
- "[ALSA] poll() failed" Bug. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from miniaudio.