mirror of https://github.com/mackron/dr_libs
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.
161 lines
4.8 KiB
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;
|
|
} |