You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dr_libs/tests/mp3/dr_mp3_playback.c

161 lines
4.8 KiB
C

#include "dr_mp3_common.c"
#define MA_NO_DECODING
#define MA_NO_ENCODING
#define MINIAUDIO_IMPLEMENTATION
#include "../external/miniaudio/miniaudio.h"
void data_callback(ma_device* pDevice, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount)
{
drmp3* pMP3;
pMP3 = (drmp3*)pDevice->pUserData;
DRMP3_ASSERT(pMP3 != NULL);
if (pDevice->playback.format == ma_format_f32) {
drmp3_read_pcm_frames_f32(pMP3, frameCount, pFramesOut);
} else if (pDevice->playback.format == ma_format_s16) {
drmp3_read_pcm_frames_s16(pMP3, frameCount, pFramesOut);
} else {
DRMP3_ASSERT(DRMP3_FALSE); /* Should never get here. */
}
(void)pFramesIn;
}
int do_decoding_validation(const char* pFilePath)
{
int result = 0;
drmp3 mp3Memory;
drmp3 mp3File;
size_t dataSize;
void* pData;
/*
When opening from a memory buffer, dr_mp3 will take a different path for decoding which is optimized to reduce data movement. Since it's
running on a separate path, we need to ensure it's returning consistent results with the other code path which will be used when decoding
from a file.
*/
/* Initialize the memory decoder. */
pData = dr_open_and_read_file(pFilePath, &dataSize);
if (pData == NULL) {
printf("Failed to open file \"%s\"", pFilePath);
return -1;
}
if (!drmp3_init_memory(&mp3Memory, pData, dataSize, NULL)) {
free(pData);
printf("Failed to init MP3 decoder \"%s\"", pFilePath);
return -1;
}
/* Initialize the file decoder. */
if (!drmp3_init_file(&mp3File, pFilePath, NULL)) {
drmp3_uninit(&mp3Memory);
free(pData);
printf("Failed to open file \"%s\"", pFilePath);
return -1;
}
DRMP3_ASSERT(mp3Memory.channels == mp3File.channels);
/* Compare. */
for (;;) {
drmp3_uint64 iSample;
drmp3_uint64 pcmFrameCountMemory;
drmp3_uint64 pcmFrameCountFile;
drmp3_int16 pcmFramesMemory[4096];
drmp3_int16 pcmFramesFile[4096];
pcmFrameCountMemory = drmp3_read_pcm_frames_s16(&mp3Memory, DRMP3_COUNTOF(pcmFramesMemory) / mp3Memory.channels, pcmFramesMemory);
pcmFrameCountFile = drmp3_read_pcm_frames_s16(&mp3File, DRMP3_COUNTOF(pcmFramesFile) / mp3File.channels, pcmFramesFile);
/* Check the frame count first. */
if (pcmFrameCountMemory != pcmFrameCountFile) {
printf("Frame counts differ: memory = %d; file = %d\n", (int)pcmFrameCountMemory, (int)pcmFrameCountFile);
result = -1;
break;
}
/* Check individual frames. */
DRMP3_ASSERT(pcmFrameCountMemory == pcmFrameCountFile);
for (iSample = 0; iSample < pcmFrameCountMemory * mp3Memory.channels; iSample += 1) {
if (pcmFramesMemory[iSample] != pcmFramesFile[iSample]) {
printf("Samples differ: memory = %d; file = %d\n", (int)pcmFramesMemory[iSample], (int)pcmFramesFile[iSample]);
result = -1;
break;
}
}
/* We've reached the end if we didn't return any PCM frames. */
if (pcmFrameCountMemory == 0 || pcmFrameCountFile == 0) {
break;
}
}
drmp3_uninit(&mp3File);
drmp3_uninit(&mp3Memory);
free(pData);
return result;
}
int main(int argc, char** argv)
{
drmp3 mp3;
ma_result resultMA;
ma_device_config deviceConfig;
ma_device device;
const char* pInputFilePath;
if (argc < 2) {
printf("No input file.\n");
return -1;
}
pInputFilePath = argv[1];
/* Quick validation test first. */
if (do_decoding_validation(pInputFilePath) != 0) {
return -1;
}
if (!drmp3_init_file(&mp3, pInputFilePath, NULL)) {
printf("Failed to open file \"%s\"", pInputFilePath);
return -1;
}
deviceConfig = ma_device_config_init(ma_device_type_playback);
deviceConfig.playback.format = ma_format_s16;
deviceConfig.playback.channels = mp3.channels;
deviceConfig.sampleRate = mp3.sampleRate;
deviceConfig.dataCallback = data_callback;
deviceConfig.pUserData = &mp3;
resultMA = ma_device_init(NULL, &deviceConfig, &device);
if (resultMA != MA_SUCCESS) {
drmp3_uninit(&mp3);
printf("Failed to initialize playback device: %s.\n", ma_result_description(resultMA));
return -1;
}
resultMA = ma_device_start(&device);
if (resultMA != MA_SUCCESS) {
ma_device_uninit(&device);
drmp3_uninit(&mp3);
printf("Failed to start playback device: %s.\n", ma_result_description(resultMA));
return -1;
}
printf("Press Enter to quit...");
getchar();
/* We're done. */
ma_device_uninit(&device);
drmp3_uninit(&mp3);
return 0;
}