Getting real / physical / hardware samplig rate of sound card - c++

I need to get real / physical / hardware (don't know the word) samplig rate of my soundcard.
I'm generating High frequency square sound wave and playing it using DirectSound.
I need to match DirectSound sampling rate with the sound-card.
I don't want windows mixer to re sample my sound because output wave will be totally unusable.
In short: How to get sound-card native sample rate?

Related

phytec phyBOARD iMX-6 performed poorly when running qt5 opengles application from flash instead of sd card (fps halved)

I'm developing a graphics application(Racing Game) on phytec phyBOARD iMX-6, with Qt 5.9 and
OpenGLESv2. I create OpenGL context through Qt modules. My problem is my game gets 40 fps when running on sd card. And gets 20 fps when running on Flash. Why opengles frame rate is so low on flash? The operating systems in the flash and sd card are identical.
My first thought was that the performance decreased due to the low read / write ability of the flash. But my game only reads data from disk during the boot phase. In the remaining stages, it exchanges data with the disk in a very limited way. Therefore, It isn't very likely that low performance is caused by disk read and write speeds.
Have you ever encountered such a problem where the opengles frame rate is low when application working on flash? Maybe a similar solution can contribute to me.
I managed to solve it with pure luck. I added the line
PREFERRED_VERSION_mesa = "git"
in the Local.conf file. And now I get the same fps on flash(40 fps) and sd card(40 fps).

MP3-encoding: Does CBR 320 cost more CPU than a lower bitrate?

I have an Android-app which uses LAME to encode an audio live-stream to MP3.
Right now, I'm using a constant bitrate (CBR) of 128 for this.
Now I wonder, if I switch over to a bitrate of eg. 320, will this cost more CPU/take longer?
This is a mandatory part of the app as it's as mentioned a live-stream.. therefor I won't risk a higher CPU-usage or so.
MP3 encoders/decoders usually need more processing power for higher bit rates. I could find two data points, MP3 encoder datasheet and MP3 decoder datasheet to support this.
On a modern phone, the difference in the CPU loading should be insignificant, as MP3 decoding/encoding is less CPU intensive.

WAV files at any rate except 44.1kHz have messed up sound

I'm using ALSA on Ubuntu to try to play a WAV file. Presently, I'm able to read the wav header to figure out the file's sampling rate and such then set the parameters on ALSA to correspond. This works perfectly for files with a 44.1kHz sampling rate, but other files with rates at ~11kHz or ~22kHz do not play correctly. I'm not sure that I am setting the sampling rate correctly.
val = realSampleRate;
//Sampling rate to given sampling rate
snd_pcm_hw_params_set_rate_max(handle, params, &val, &dir);
cout << "sampling at " << val << " Hz \n";
This gives the correct output ("sampling at 22050 Hz") but if I follow it with this:
val = realSampleRate;
snd_pcm_hw_params_set_rate_min(handle, params, &val, &dir);
cout << "sampling at " << val << " Hz \n";
the output proceeds to say "sampling at 44100 Hz" which is obviously contradictory. I also tried using snd_pcm_hw_params_set_rate_near but that doesn't work either, it says sampling at 44100 Hz on a 22050 file, and the audio throughout all of those were very messed up.
EDIT: One issue is incorrect sampling rates, which will speed up the playing, but the real issue comes from mono tracks. Mono tracks sound really distorted and very off.
EDIT: 8 Bit files are off too
Looks to me like your hardware is not capable of handling a 22.05Khz sampling rate for playback. The fact that the API function returns a different value is a clue.
ALSA is just an API. It can only do what your current underlying hardware is capable of supporting. Low-end, bottom-of-the-barrel, el-cheapo audio playback hardware will support a handful of sampling frequencies, and that's about it.
I had some custom-written audio recording and playback software, that was sampling and recording audio at a particular rate, then playing it back using ALSA's aplay. When I got some new hardware, I found that the new hardware was still capable of supporting my sampling rate for recording, for playback it didn't, and aplay simply proceeded to play back the previously recorded audio at the nearest supportable playback level, with hillarious results. I had to change my custom-written stuff to record and playback at the supported rate.
If the hardware does not support your requested playback rate, ALSA won't resample your raw audio data. It's up to you to resample it, for playback.
snd_pcm_hw_params_set_rate_max() sets the maximum sample rate, i.e., when this functions succeeds, the device's sample rate will not be larger than what you've specified.
snd_pcm_hw_params_set_rate_min() sets the minimum sample rate.
snd_pcm_hw_params_set_rate_near() searches for the nearest sample rate that is actually supported by the device, sets it, and returns it.
If you have audio data with a specific sample rate, and cannot do resampling, you must use snd_pcm_hw_params_set_rate().
Using "default" instead of "hw:0,0" solves this, including the sampling rate being too slow. "plughw:0,0" works as well, and it's better because you can select the different devices/cards programmatically whereas default just uses the default.

How can I get the frequency value at given time with XAudio2?

I've already loaded the .wav audio to the buffer with XAudio2 (Windows 8.1) and to play it I just have to use:
//start consuming audio in the source voice
/* IXAudio2SourceVoice* */ g_source->Start();
//play the sound
g_source->SubmitSourceBuffer(buffer.xaBuffer());
I wonder, how can I get the frequency value at given time with XAudio2?
The question does not make much sense, a .wav file contains a great many frequencies. It is the blend of them that makes it sound like music to your ears, instead of just an artificial generated tone. A blend that's constantly changing.
A signal processing step is required to convert the samples in the .wav file from the time domain to the frequency domain. Generally known as spectrum analysis, the Fast Fourier Transform (FFT) is the standard technique.
A random Google hit on "xaudio2 fft" produced this code sample. No idea how good it is, but something to play with to get the lay of the land. You'll find more about it in this gamedev question.

Sampling rate deviation and sound playing position

When you set soundcard rate to, for example, 44100, you cannot guarantee actual rate be equal 44100. In my case traffic measurements between application and ALSA (in samples/sec) gave me value of 44066...44084.
This should not be related to resampling issues: even only-48000 hardware must "eat" data at 44100 rate in "44100" mode.
The problem occurs when i try to draw a cursor over waveform while this waveform is playing. I calculate cursor position using "ideal" sampling rate read from WAV-file (22050, ..., 44100, ..., 48000) and the milliseconds spent after playing start, using following C++ function:
long long getCurrentTimeMs(void)
{
boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
boost::posix_time::ptime epoch_start(boost::gregorian::date(1970,1,1));
boost::posix_time::time_duration dur = now - epoch_start;
return dur.total_milliseconds();
}
QTimer is used to generate frames for cursor animation, but i do not depend on QTimer precision, because i ask time by getCurrentTimeMs() (assiming it is precise enough) every frame, so i can work with varying framerate.
After 2-3 minutes of playing i see a little difference between what i hear and what i see - the cursor position is greater than playing position for something like 1/20 of second or so.
When i measure traffic that go through ALSA's callback i get mean value of 44083.7 samples/sec. Then i use this value in the screen drawing function as an actual rate. Now the problem disappears. The program is cross-platform, so i will test this measurements on windows and another soundcard later.
But is there a better way to sync sound and screen? Is there some not very CPU-consuming way of asking soundcard about actual playing sample number, for example?
This is a known effect, which is for example in Windows addressed by Rate Matching, described here Live Sources.
On playback, the effect is typically addressed by using audio hardware as "clock" and synchronizing to audio playback instead of "real" clock. That is, for example, with audio sampling rate 44100, next video frame of 25 fps video is presented in sync with 44100/25 sample playback rather than using 1/25 system time increment. This compensates for the imprecise effective playback rate.
On capture, the hardware itself acts as if it is delivering data at exactly requested rate. I think the best you can do is to measure effective rate and resample audio from effecive to correct sampling rate.