Simple Audio program is not making sound

Hi there,
I made a simple test program to output audio, by using callback function, but despite the callback function being called , there is no sound out of the speakers.
Im using sdl2 on windows computer.
I only have 1 output device (realtek (R) audio )

The code should output a noise sound, see for yourself

Here is the code:

using namespace std;

SDL_AudioSpec want, have;
SDL_AudioDeviceID player;

void SDLCALL callback_player( void* userdata, Uint8* stream, int len){

	for (int i = 0; i < len; i ++) {
		auto value = Uint8(sin(i) * 10000);
		stream[i] = value ;
	}	
}

auto setupAudioPlayer() {

	printf("### Device Player ###\n");
	int num = SDL_GetNumAudioDevices(false);
	printf("num: %d\n", num);
	for (int i = 0; i < num; i++) {
		auto name = SDL_GetAudioDeviceName(i, false);
		printf("%d: %s\n", i, name);
	}

	int deviceIndex;
	printf("select device to player audio: ");
	scanf_s("%d", &deviceIndex);
	printf("\n");

	SDL_memset(&want, 0, sizeof(want)); /* or SDL_zero(want) */
	want.freq = 44100;
	want.format = AUDIO_F32;
	want.channels = 2;
	want.samples = 1024;
	want.callback = callback_player;  // you wrote this function elsewhere.
	//want.size = 512;


	SDL_AudioDeviceID player = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(deviceIndex, false), SDL_FALSE, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE);
	if (player == 0) {
		printf("Failed to open player device! SDL Error: %s", SDL_GetError());
		
	}
	else {

		printf("freq %d \nformat %d \nchannels %d \nsamples %d\n", have.freq, have.format, have.channels, have.samples);
	}
	
	return player;
}

void destroyAudio() {
	
	SDL_CloseAudioDevice(player);
	SDL_Quit();
}

int main(int n , char**args) {

	int err = SDL_Init(SDL_INIT_AUDIO);
	printf("error: %d", err);
	if (err < 0) {
		printf("erorr: %d\n", err);
		printf("Failed to init audio! SDL Error: %s", SDL_GetError());
	}
	//recorder = setupAudioRecorder();
	auto player = setupAudioPlayer();
	printf("player: %d\n", player);
	//loadWave();

	printf("playing\n");
	//SDL_PauseAudioDevice(recorder, 0);
	SDL_PauseAudioDevice(player, 0);
	//SDL_SemWait(sem);
	SDL_Delay(10000);
	destroyAudio();
	//system("pause");
	return 0;
}

Can someone please tell me what is wrong with this code, and if its nothing wrong with it , do you have any idea why audio is not outputing from the speakrs.

Thanks !! :smiley:

I’m on a Linux machine, so that may be the difference, but it does play a noise for me. (It sounds like a very harsh square wave or saw wave of some sort.)

Does it work for you if you set the first argument in SDL_OpenAudioDevice to NULL?
Edit: I blamed the SDL_bool in a previous edit, It was not that either.

SDL_AudioDeviceID player = SDL_OpenAudioDevice(NULL, SDL_FALSE, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE);

Thanks for awnsering, but I tried and it doesnt work

Your program works for me too (regardless of what deviceIndex I input). I also use Linux.

When I say it “works” I mean that I hear something. It doesn’t sound like a pure sine wave because you are writing the data as Uint8 but you have specified that the sample format is float.

I have no experience with floating-point audio formats. What is actually considered to be the max amplitude? How will it handle NaN and infinite values? Will it be the same on all platforms? Etc.

Maybe try using a 8-bit or 16-bit integer format (e.g. AUDIO_S16) instead just to see if you can hear something? You might also want to verify that have.format is what you expect.

@ Peter87: Good call. That callback is very likely the issue.

I think you have to treat stream as binary array of floats that are chopped up to fit into an array of Uint8’s.
If I’m reading things correctly, I’m pretty sure 32 bit float audio is even more complicated since it uses one of those bytes to adjust sample volume on the fly.

I’m trying to understand how to use SDL_AudioCVT. I hope it might help, but it’s a bit beyond me at the moment.
SDL2/SDL_AudioCVT - SDL Wiki

I know that Icculus does audio stuff, if they drop by they might take a second to answer how this could be done correctly here?
Here is Iculus’s YT, I’ll link to the callback episode, where they are using the 32bit float sample type. I’m watching it right now for any hints.

I’m sorry. I had to give up for now, AUDIO_F32 has beaten me. There’s no problem in loading or playing audio files in 32 bit float, I just don’t know how to generate that data from scratch.

Instead I converted your code to generate and play a 440hz tone using AUDIO_S16 as Peter87 suggested. It’s also what I am most comfortable working in. I also swapped to single channel audio (Mono) to make it just that little bit simpler to load data in the callback.

(It’s set to play at max volume for a signed int16_t (0x8000), so check your master volume before playing.)


#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <SDL2/SDL.h>

using namespace std;

SDL_AudioSpec want, have;
SDL_AudioDeviceID player;

double time = 0.0f;
double step = 1.0f/44100.0f;
double freq = 440.0f * 2.0f * M_PI;

void SDLCALL callback_player( void* userdata, Uint8* stream, int len){

	for (int i = 0; i < len; i += sizeof(int16_t)) {
		time += step;
		int16_t value = 0x8000 * SDL_sin(time * freq);
		memcpy(&stream[i], &value, sizeof(int16_t));
	}
}

auto setupAudioPlayer() {

	printf("### Device Player ###\n");
	int num = SDL_GetNumAudioDevices(false);
	printf("num: %d\n", num);
	for (int i = 0; i < num; i++) {
		auto name = SDL_GetAudioDeviceName(i, false);
		printf("%d: %s\n", i, name);
	}

	int deviceIndex;
	printf("select device to player audio: ");
	scanf("%d", &deviceIndex);
	printf("\n");

	SDL_memset(&want, 0, sizeof(want)); /* or SDL_zero(want) */
	want.freq = 44100;
	want.format = AUDIO_S16;
	want.channels = 1;
	want.samples = 1024;
	want.callback = callback_player;  // you wrote this function elsewhere.
	//want.size = 512;


	SDL_AudioDeviceID player = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(deviceIndex, false), 0, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE);
	if (player == 0) {
		printf("Failed to open player device! SDL Error: %s", SDL_GetError());

	}
	else {

		printf("freq %d \nformat %d \nchannels %d \nsamples %d\n", have.freq, have.format, have.channels, have.samples);
	}

	return player;
}

void destroyAudio() {

	SDL_CloseAudioDevice(player);
	SDL_Quit();
}

int main(int n , char**args) {

	int err = SDL_Init(SDL_INIT_AUDIO);
	printf("error: %d", err);
	if (err < 0) {
		printf("erorr: %d\n", err);
		printf("Failed to init audio! SDL Error: %s", SDL_GetError());
	}
	//recorder = setupAudioRecorder();
	auto player = setupAudioPlayer();
	printf("player: %d\n", player);
	//loadWave();

	printf("playing\n");
	//SDL_PauseAudioDevice(recorder, 0);
	SDL_PauseAudioDevice(player, 0);
	//SDL_SemWait(sem);
	SDL_Delay(3000);
	destroyAudio();
	//system("pause");
	return 0;
}