OpenAL. MACOS. Capture and rendering from the same device (bluetooth headset) - c++

Good day!
Our application should play the sound that came from the network from the server and collect sound from the user through a microphone and send it back to the server. For these purposes (render and capture) we use OpenAL. Everything works fine when we use the equipment built into the Mac. When we use bluetooth headphones that have microphone, problems arise. For example, Apple Airpods or Meizu POP.
If we use OpenAL implementation that Apple provides, there is no sound rendering at all. Device doesn't process sound data and alGetSourcei(/*our source*/, AL_BUFFERS_PROCESSED, &buffersProcessed) always set buffersProcessed in 0.
If we use OpenAL-Soft implementation, device process incoming data and we hear the sound. But this sound is muffled, with noises, like the sound from an old VHS video cassette.
Rendering and capture run in separate threads and device access is not synchronized. The logic for capturing and rendering is standard and done according to the OpenAL documentation.
Maybe someone has encountered such incorrect behavior? I will be glad of any help and questions.
Thanks!

Related

Getting audio output stream in C++ [duplicate]

Does anyone know how to programmatically capture the sound that is being played (that is, everything that is coming from the sound card, not the input devices such as a microphone).
Assuming that you are talking about Windows, there are essentially three ways to do this.
The first is to open the audio device's main output as a recording source. This is only possible when the driver supports it, although most do these days. Common names for the virtual device are "What You Hear" or "Wave Out". You will need to use a suitable API (see WaveIn or DirectSound in MSDN) to do the capturing.
The second way is to write a filter driver that can intercept the audio stream before it reaches the physical device. Again, this technique will only work for devices that have a suitable driver topology and it's certainly not for the faint-hearted.
This means that neither of these options will be guaranteed to work on a PC with arbitrary hardware.
The last alternative is to use a virtual audio device, such as Virtual Audio Cable. If this device is set as the defualt playback device in Windows then all well-behaved apps will play through it. You can then record from the same device to capture the summed output. As long as you have control over the device that the application you want to record uses then this option will always work.
All of these techniques have their pros and cons - it's up to you to decide which would be the most suitable for your needs.
You can use the Waveform Audio Interface, there is an MSDN article on how to access it per PInvoke.
In order to capture the sound that is being played, you just need to open the playback device instead of the microphone. Open for input, of course, not for output ;-)
If you were using OSX, Audio Hijack Pro from Rogue Amoeba probably is the easiest way to go.
Anyway, why not just looping your audio back into your line in and recording that? This is a very simple solution. Just plug a cable in your audio output jack and your line in jack and start recordung.
You have to enable device stero mix. if you do this, direct sound find this device.

No audio output from one of two streams when rendering directly to WASAPI

I've been stuck on this problem for weeks now and Google is no help, so hopefully some here can help me.
I am programming a software sound mixer in C++, getting audio packets from the network and Windows microphones, mixing them together as PCM, and then sending them back out over the network and to speakers/USB headsets. This works. I have a working setup using the PortAudio library to handle the interface with Windows. However, my supervisors think the latency could be reduced between this software and our system, so in an attempt to lower latency (and better handle USB headset disconnects) I'm now rewriting the Windows interface layer to directly use WASAPI. I can eliminate some buffers and callbacks doing this, and theoretically use the super low latency interface if that's still not fast enough for the higher ups.
I have it only partially working now, and the partially part is what is killing me here. Our system has the speaker and headphones as three separate mono audio streams. The speaker is mono, and the headset is combined from two streams to be stereo. I'm outputting this to windows as two streams, one for a device of the user's choice for speaker, and one of another device of the user's choice for headset. For testing, they're both outputting to the default general stereo mix on my system.
I can hear the speaker perfectly fine, but I cannot hear the headset, no matter what I try. They both use the same code path, they both go through a WMF resampler to convert to 2 channel audio at the sample rate Windows wants. But I can hear the speaker, but never the headset stream.
It's not an exclusive mode problem: I'm using shared mode on all streams, and I've even specifically tried cutting down the streams to only the headset, in case one was stomping the other or something, and still the headset has no audio output.
It's not a mixer problem upstream, as I haven't modified any code from when it worked with PortAudio streams. I can see the audio passing through the mixer and to the output via my debug visualizers.
I can see the data going into the buffer I get from the system, when the system calls back to ask for audio. I should be hearing something, static even, but I'm getting nothing. (At one point, I bypassed the ring buffer entirely and put random numbers directly into the buffer in the callback and I still got no sound.)
What am I doing wrong here? It seems like Windows itself is the problem or something, but I don't have the expertise on Windows APIs to know what, and I'm apparently the most expert for this stuff in my company. I haven't even looked yet as to why the microphone input isn't working, and I've been stuck on this for weeks now. If anyone has any suggestions, it'd be much appreciated.
Check the re-sampled streams: output the stereo stream to the speaker, and output the mono stream to the handset.
Use IAudioClient::IsFormatSupported to check supported formats for the handset.
Verify your code using an mp3 file. Use two media players to play different files with different devices simultaneously.

Performance issue using a bluetooth loudspeaker on Android NDK app

In my Android app, I use Android NDK to play music by doing the following:
extract audio samples from an OGG file using the Vorbis library
process the audio samples
redirect the processed samples to the audio output using the Oboe library
In order to avoid underruns, I do the first 2 steps in a separate thread, to extract and process the sound a little bit in advance (it adds a bit of latency, but this is not a problem for my app). That solution works great on every device I've tested so far.
But for some reason, when I pair my device with a bluetooth speaker and when I play music, I have what seems to be underruns on some devices like Samsung S7 or Nokia 1 (but not on every device).
This bug looks so random to me that I don't know where to start. It acts like the bluetooth connection is using quite a lot of CPU so my app doesn't have enough resource to run properly.
Does anyone have experienced something similar? Should I do anything in my code to handle the bluetooth connection so it doesn't use CPU (for example to avoid audio resampling)?
Thanks for your help.
Android + Bluetooth audio is a world of pain. The major thing to appreciate about Bluetooth is the audio sink runs at a rate independent of other audio devices, which is why the native mediaplayer will do things like display video in accordance with whatever rate the attached audio device consumes samples, essentially slaving itself to the clock of the BT audio device. If you want to drive the speed from Android (i.e. SystemClock timebase) you'll need to use a timestretching AudioTrack. (This can be done, but driver support is erratic and overall system stability tanks).
Firstly, you want to eliminate the devices themselves being problems. Can you play the ogg files in a media player to a Bluetooth speaker from the S7 or Nokia 1 without problems? If so, it's your code!
It sounds to me like the speaker is consuming samples faster than the device is producing them, for whatever reason. Basically check your callbacks to make sure whenever the audio subsystem requests more data you are actually providing it. Be sure to drive your decoding pipeline according to the callbacks being made and not the system clock or any other assumptions about timing.
Finally, Bluetooth audio, at least A2DP, as opposed to directly streaming MP3, is going to require some processing to recompress the audio as it is sent out, but those devices should have plenty of headroom for this, maybe even special DSPs. I've done it with 1080P video playback at the same time before, and it starts to fall apart with two videos at once!

Is it possible to play a sound though the audio driver with Rtmidi?

I am currently on linux and I am playing around with rtmidi. Now I was able to play a sound though my digital piano but I am wondering if I can also output the sound though my speakers?
When my digital piano is not connected I still get one device with getPortCount(); I assumed that is my audio driver. The device name is Midi Through:0 which is somewhat strange.
But I don't hear any sound and I am not sure if that is the intended behavior. Can I play midi sounds though my audio driver with rtmidi? Or do I need another library for this?
To convert MIDI commands into real sounds, you need a synthesizer.
Sound cards stopped having a built-in hardware synthesizer in the last millenium.
You need a software synthesizer, such as Fluidsynth or Timidity.
RtMidi is, as quoted from this website, a realtime midi input/output API. It does not say it is an audio API or library therefore it probably isn't. So yes, you will need another library or API for this, I recommend OpenAL.

Capturing Audio Out

I want to capture all audio that is played to the user (all sounds together). Currently I'm working on Windows but it would be nice if the code was cross-platform (but not necessarily). Is it possible to do it with OpenAL? How? Code examples would be great.
Language: C++
The only way to do this I believe is to create a replacement audio device driver that receives all audio requests, and then forwards them to the original device driver. There are a number of existing applications that work in this way including Freecorder, MP3myMP3 Recorder, SoundTap and Wondershare to name but a few (Google "Streaming Audio Recorder").
As for cross-platform, I would say not a chance since it is OS driver model dependent.
Depending on what you have in your system, some (not all) sound cards offer a "Stereo Mix" feature, which can be used like any other recording device. This is basically exactly what you want, as it is literally a mix of all stereo sounds being played.