-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Strange sound in the first seconds of streaming audio #12059
Comments
Sorry, forgot to mention I'm on SDL3.1.9 |
For additional information, I just checked out the 3.2.0 commit and rebuilt. Same issue. |
@renebarto, same for me using Debian GNU/Linux. |
Hello, I took a quick look in this in case it was related to another issue in audio I was investigating. It turned out it is not, but I observed in your callback function: int16_t sampleL = static_cast<int16_t>(32768.0F * sin(phaseL) + 0.5F);
int16_t sampleR = static_cast<int16_t>(32768.0F * sin(phaseR) + 0.5F); This definitely overflows, since int16_t range is [-32,768 .. 32,767] and this is responsible, at least partially, for the initial distortion. By trying a lower value it improves the situation. |
You right there, but that does not explain the noise at the start that
disappeared later
…On Wed, Jan 29, 2025, 02:49 Manuel ***@***.***> wrote:
Hello, I took a quick look in this in case it was related to with another
issue in audio I was investigating. It turned out it is not, but I observed
in your callback function:
int16_t sampleL = static_cast<int16_t>(32768.0F * sin(phaseL) + 0.5F);
int16_t sampleR = static_cast<int16_t>(32768.0F * sin(phaseR) + 0.5F);
This definitely overflows, since int16_t range is [-32,768 .. 32,767] and
this is responsible, at least partially, for the initial distortion. By
trying a lower value it improves the situation.
—
Reply to this email directly, view it on GitHub
<#12059 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAQY5NOEL2Y6UPZRHRTINET2NAXSJAVCNFSM6AAAAABVVYQ4FGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMMRQGQ2TSOBTGQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
It does, actually. Here's what the code generates (top), vs the same thing multiplying by 32700.0F instead of 32768.0F (bottom): When it overflows, you get exactly one totally wrong sample in the wave. As for why the noise disappeared later? Here's the original code, around 2.89 seconds in: Something goes just enough out of step to stop hitting an overflow value at the top of each wave. I'm guessing it's accumulating floating point precision problems from the repeated addition of stepR, but I could be totally wrong. Here's the complete program, which is mostly the posted code with a mainline so it'll compile. Feel free to play with SAMPLE_MULTIPLIER at the top. The pictures were generated by running the program with the SDL_AUDIO_DRIVER=disk environment variable set, and then loading the resulting sdlaudio.raw file into Audacity. #include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#define SAMPLE_MULTIPLIER 32700.0F
//#define SAMPLE_MULTIPLIER 32768.0F
static uint8_t audioBuffer[65536];
float phaseL = 0.0F;
float phaseR = 0.0F;
float sampleFreq = 48000.0F;
float freqL = 1000.0F;
float freqR = 2000.0F;
float twoPI = 2 * SDL_PI_D;
float stepL = freqL / sampleFreq * twoPI;
float stepR = freqR / sampleFreq * twoPI;
static void SDLCALL audio_callback(void */*userdata*/, SDL_AudioStream *stream, int additional_amount, int total_amount)
{
size_t offset{};
int sampleFrames = additional_amount / 4;
for (int i = 0; i < sampleFrames; ++i)
{
int16_t sampleL = static_cast<int16_t>(SAMPLE_MULTIPLIER * SDL_sin(phaseL) + 0.5F);
int16_t sampleR = static_cast<int16_t>(SAMPLE_MULTIPLIER * SDL_sin(phaseR) + 0.5F);
memcpy(audioBuffer + offset, &sampleL, 2);
offset += 2;
memcpy(audioBuffer + offset, &sampleR, 2);
offset += 2;
phaseL += stepL;
phaseR += stepR;
if (phaseL > twoPI)
phaseL -= twoPI;
if (phaseR > twoPI)
phaseR -= twoPI;
}
// Put the audio data into the stream
//std::cout << "Get audio, size " << additional_amount << "\r\n";
SDL_PutAudioStreamData(stream, audioBuffer, sampleFrames * 4);
}
int main(int argc, char **argv)
{
SDL_Init(SDL_INIT_AUDIO);
SDL_AudioSpec spec { SDL_AUDIO_S16LE, 2, 48000 };
SDL_AudioStream *m_stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, audio_callback, nullptr);
SDL_ResumeAudioStreamDevice(m_stream);
SDL_Delay(10000);
SDL_DestroyAudioStream(m_stream);
SDL_Quit();
return 0;
} At any rate, I'm confident this is not an SDL bug at this point, so I'm closing this. If there's more to examine, let me know and I'll reopen it, though! |
I have an issue similar to #11724 on Windows.
I'm placing two sine waves of different frequencies on each channel of a stereo pair.
When I create the stream (16 bit setero) I get callbacks for 1920 bytes per call, and fill up the buffer then add 480 sample frames of 4 bytes each with sine wave (using a continuing phase to make sure the audio is smooth).
In the first seconds I hear a strange deformation on both channels, which disappears after a few seconds, first on the left, and a few seconds later on the right channel. After that the sounds is what I'd expect.
I tried clearing the buffer first, but that does not help.
I have the feeling either SDL_PutAudioStreamData writes more or less data to the buffer than specified, or that later on something else messes up the audio.
To be clear, I do not open a device first, I just create as stream:
Callback:
I play sound for about 10 secs, then pause and destroy the stream.
After about 2 seconds the left channel sounds normal, after about 4 seconds the right is also normal.
The text was updated successfully, but these errors were encountered: