For some reason, if I use SDL_MixAudioFormat, it completely makes a mess of my audio. Crackly, etc.
No idea why. Here’s my code:
int VIDEO_ReadSmackerFile(char* dir, char* filename)
{
char filepath[256];
int failed = 0;
// Build a string for the path name
sprintf(filepath, "%s\\%s", dir, filename);
FILE* file = fopen(filepath, "rb");
if (file == NULL)
return 0;
smk smkData = smk_open_filepointer(file, SMK_MODE_DISK);
// Video data
unsigned char* palette_data;
unsigned char* image_data;
unsigned char y_scale_mode;
unsigned long width;
unsigned long height;
unsigned long currentFrame;
unsigned long frameCount;
double microSecPerFrame;
// Audio data
unsigned char* audio_data;
unsigned char a_trackmask, a_channels[7], a_depth[7];
unsigned long a_rate[7];
unsigned long audio_size;
smk_info_all(smkData, ¤tFrame, &frameCount, µSecPerFrame);
smk_info_video(smkData, &width, &height, &y_scale_mode);
smk_info_audio(smkData, &a_trackmask, a_channels, a_depth, a_rate);
smk_enable_video(smkData, 1);
smk_enable_audio(smkData, 0, 1);
SDL_AudioSpec audioFormat;
SDL_zero(audioFormat);
audioFormat.freq = a_rate[0];
audioFormat.format = a_depth[0] == 16 ? AUDIO_S16 : AUDIO_U8;
audioFormat.channels = a_channels[0];
SDL_AudioSpec audioFormatObtained;
SDL_AudioDeviceID deviceId = SDL_OpenAudioDevice(NULL, 0, &audioFormat, &audioFormatObtained, 0);
if (deviceId == 0)
{
SDL_Log("SDL_OpenAudioDevice: %s\n", SDL_GetError());
goto die;
}
else
{
SDL_PauseAudioDevice(deviceId, 0);
}
SDL_Log("Smacker Info - Res: %dx%d, Y Scale Mode: %d, Frame Count: %d, FPS: %lf, Sample Depth: %d, Sample Rate: %d", width, height, y_scale_mode, frameCount, 1000000.0 / microSecPerFrame, a_depth[0], a_rate[0]);
smk_first(smkData);
palette_data = (unsigned char*)smk_get_palette(smkData);
image_data = (unsigned char*)smk_get_video(smkData);
int videoTex = RENDER_GenTextureFromRAWData("VIDYA.RAW", width, height, image_data, palette_data);
double lastFrameTime = 0;
#if 1
while (1)
{
if ((getMicroseconds() - lastFrameTime) < microSecPerFrame)
{
if (INPUT_CheckAction(INPUT_FIRE))
{
INPUT_ClearAction(INPUT_FIRE);
break;
}
idleCheck();
continue;
}
smk_info_all(smkData, ¤tFrame, NULL, NULL);
palette_data = (unsigned char*)smk_get_palette(smkData);
image_data = (unsigned char*)smk_get_video(smkData);
audio_data = (unsigned char*)smk_get_audio(smkData, 0);
audio_size = smk_get_audio_size(smkData, 0);
unsigned char* audio_mixed = malloc(audio_size);
memset(audio_mixed, 0, audio_size);
SDL_MixAudioFormat(audio_mixed, audio_data, audioFormatObtained.format, audio_size, remapVolume(soundVolume));
if (deviceId && SDL_QueueAudio(deviceId, audio_mixed, audio_size) == -1)
{
SDL_Log("SDL_QueueAudio: %s\n", SDL_GetError());
failed = 1;
goto die;
}
free(audio_mixed);
RENDER_ClearAll();
updateTextureData("VIDYA.RAW", image_data, palette_data);
RENDER_DrawHUDTexture("VIDYA.RAW", width, height, HUDTEXF_ASPECTCORRECT, 0, 0, width, height, width, height);
toggle();
lastFrameTime = getMicroseconds();
if (currentFrame == frameCount-1)
break;
else
smk_next(smkData);
}
#endif
die: // Free resources and die.
if (deviceId)
{
SDL_ClearQueuedAudio(deviceId);
SDL_CloseAudioDevice(deviceId);
deviceId = 0;
}
RENDER_FreeTexture(&textures[videoTex], 1);
smk_close(smkData);
fclose(file);
return (!failed);
}
If I use audio_data directly, it sounds perfect, but I need to adjust the volume, so I’m using this function. But, if I use it, the result is a garbage pile.
Here’s a video of what happens: