From 3547d7a189f852641768b217d988484b56a37fc5 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Wed, 23 Jul 2025 11:56:50 +0300
Subject: [PATCH] update to latest dr_mp3.h from mainstream
---
src/SDL12_compat.c | 9 ++---
src/dr_mp3.h | 96 +++++++++++++++++++++++-----------------------
2 files changed, 51 insertions(+), 54 deletions(-)
diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c
index 1c30e521d..02b787e22 100644
--- a/src/SDL12_compat.c
+++ b/src/SDL12_compat.c
@@ -8882,15 +8882,15 @@ mp3_sdlrwops_read(void *data, void *buf, size_t bytesToRead)
static drmp3_bool32
mp3_sdlrwops_seek(void *data, int offset, drmp3_seek_origin origin)
{
- int whence = (origin == drmp3_seek_origin_start) ? RW_SEEK_SET : RW_SEEK_CUR;
+ int whence;
switch (origin) {
- case drmp3_seek_origin_start:
+ case DRMP3_SEEK_SET:
whence = RW_SEEK_SET;
break;
- case drmp3_seek_origin_current:
+ case DRMP3_SEEK_CUR:
whence = RW_SEEK_CUR;
break;
- case drmp3_seek_origin_end:
+ case DRMP3_SEEK_END:
whence = RW_SEEK_END;
break;
default:
@@ -8906,7 +8906,6 @@ mp3_sdlrwops_tell(void *data, drmp3_int64 *pos)
return (*pos != -1) ? DRMP3_TRUE : DRMP3_FALSE;
}
-
static SDL_bool OpenSDL2AudioDevice(SDL_AudioSpec *want);
static int CloseSDL2AudioDevice(void);
static SDL_bool ResetAudioStream(SDL_AudioStream **_stream, SDL_AudioSpec *spec, const SDL_AudioSpec *to, const SDL_AudioFormat fromfmt, const Uint8 fromchannels, const int fromfreq);
diff --git a/src/dr_mp3.h b/src/dr_mp3.h
index e5c9aee67..b2bc1fc92 100644
--- a/src/dr_mp3.h
+++ b/src/dr_mp3.h
@@ -1,6 +1,6 @@
/*
MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
-dr_mp3 - v0.7.0 - TBD
+dr_mp3 - v0.7.0 - 2025-07-23
David Reid - mackron@gmail.com
@@ -293,9 +293,9 @@ Main API (Pull API)
*/
typedef enum
{
- drmp3_seek_origin_start,
- drmp3_seek_origin_current,
- drmp3_seek_origin_end
+ DRMP3_SEEK_SET,
+ DRMP3_SEEK_CUR,
+ DRMP3_SEEK_END
} drmp3_seek_origin;
typedef struct
@@ -2676,13 +2676,13 @@ static size_t drmp3__on_read_clamped(drmp3* pMP3, void* pBufferOut, size_t bytes
static drmp3_bool32 drmp3__on_seek(drmp3* pMP3, int offset, drmp3_seek_origin origin)
{
DRMP3_ASSERT(offset >= 0);
- DRMP3_ASSERT(origin == drmp3_seek_origin_start || origin == drmp3_seek_origin_current);
+ DRMP3_ASSERT(origin == DRMP3_SEEK_SET || origin == DRMP3_SEEK_CUR);
if (!pMP3->onSeek(pMP3->pUserData, offset, origin)) {
return DRMP3_FALSE;
}
- if (origin == drmp3_seek_origin_start) {
+ if (origin == DRMP3_SEEK_SET) {
pMP3->streamCursor = (drmp3_uint64)offset;
} else{
pMP3->streamCursor += offset;
@@ -2698,19 +2698,19 @@ static drmp3_bool32 drmp3__on_seek_64(drmp3* pMP3, drmp3_uint64 offset, drmp3_se
}
/* Getting here "offset" is too large for a 32-bit integer. We just keep seeking forward until we hit the offset. */
- if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_start)) {
+ if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, DRMP3_SEEK_SET)) {
return DRMP3_FALSE;
}
offset -= 0x7FFFFFFF;
while (offset > 0) {
if (offset <= 0x7FFFFFFF) {
- if (!drmp3__on_seek(pMP3, (int)offset, drmp3_seek_origin_current)) {
+ if (!drmp3__on_seek(pMP3, (int)offset, DRMP3_SEEK_CUR)) {
return DRMP3_FALSE;
}
offset = 0;
} else {
- if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_current)) {
+ if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, DRMP3_SEEK_CUR)) {
return DRMP3_FALSE;
}
offset -= 0x7FFFFFFF;
@@ -2977,7 +2977,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
/* We'll first check for any ID3v1 or APE tags. */
#if 1
if (onSeek != NULL && onTell != NULL) {
- if (onSeek(pUserData, 0, drmp3_seek_origin_end)) {
+ if (onSeek(pUserData, 0, DRMP3_SEEK_END)) {
drmp3_int64 streamLen;
int streamEndOffset = 0;
@@ -2986,7 +2986,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
/* ID3v1 */
if (streamLen > 128) {
char id3[3];
- if (onSeek(pUserData, streamEndOffset - 128, drmp3_seek_origin_end)) {
+ if (onSeek(pUserData, streamEndOffset - 128, DRMP3_SEEK_END)) {
if (onRead(pUserData, id3, 3) == 3 && id3[0] == 'T' && id3[1] == 'A' && id3[2] == 'G') {
/* We have an ID3v1 tag. */
streamEndOffset -= 128;
@@ -3014,7 +3014,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
/* APE */
if (streamLen > 32) {
char ape[32]; /* The footer. */
- if (onSeek(pUserData, streamEndOffset - 32, drmp3_seek_origin_end)) {
+ if (onSeek(pUserData, streamEndOffset - 32, DRMP3_SEEK_END)) {
if (onRead(pUserData, ape, 32) == 32 && ape[0] == 'A' && ape[1] == 'P' && ape[2] == 'E' && ape[3] == 'T' && ape[4] == 'A' && ape[5] == 'G' && ape[6] == 'E' && ape[7] == 'X') {
/* We have an APE tag. */
drmp3_uint32 tagSize =
@@ -3029,7 +3029,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
/* Fire a metadata callback for the APE data. Must include both the main content and footer. */
if (onMeta != NULL) {
/* We first need to seek to the start of the APE tag. */
- if (onSeek(pUserData, streamEndOffset, drmp3_seek_origin_end)) {
+ if (onSeek(pUserData, streamEndOffset, DRMP3_SEEK_END)) {
size_t apeTagSize = (size_t)tagSize + 32;
drmp3_uint8* pTagData = (drmp3_uint8*)drmp3_malloc(apeTagSize, pAllocationCallbacks);
if (pTagData != NULL) {
@@ -3048,7 +3048,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
}
/* Seek back to the start. */
- if (!onSeek(pUserData, 0, drmp3_seek_origin_start)) {
+ if (!onSeek(pUserData, 0, DRMP3_SEEK_SET)) {
return DRMP3_FALSE; /* Failed to seek back to the start. */
}
@@ -3059,7 +3059,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
}
} else {
/* Failed to get the length of the stream. ID3v1 and APE tags cannot be skipped. */
- if (!onSeek(pUserData, 0, drmp3_seek_origin_start)) {
+ if (!onSeek(pUserData, 0, DRMP3_SEEK_SET)) {
return DRMP3_FALSE; /* Failed to seek back to the start. */
}
}
@@ -3105,7 +3105,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
} else {
/* Don't have a metadata callback, so just skip the tag. */
if (onSeek != NULL) {
- if (!onSeek(pUserData, tagSize, drmp3_seek_origin_current)) {
+ if (!onSeek(pUserData, tagSize, DRMP3_SEEK_CUR)) {
return DRMP3_FALSE; /* Failed to seek past the ID3v2 tag. */
}
} else {
@@ -3132,7 +3132,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
} else {
/* Not an ID3v2 tag. Seek back to the start. */
if (onSeek != NULL) {
- if (!onSeek(pUserData, 0, drmp3_seek_origin_start)) {
+ if (!onSeek(pUserData, 0, DRMP3_SEEK_SET)) {
return DRMP3_FALSE; /* Failed to seek back to the start. */
}
} else {
@@ -3321,40 +3321,34 @@ static size_t drmp3__on_read_memory(void* pUserData, void* pBufferOut, size_t by
static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3_seek_origin origin)
{
drmp3* pMP3 = (drmp3*)pUserData;
+ drmp3_int64 newCursor;
DRMP3_ASSERT(pMP3 != NULL);
- if (origin == drmp3_seek_origin_current) {
- if (byteOffset > 0) {
- if (pMP3->memory.currentReadPos + byteOffset > pMP3->memory.dataSize) {
- return DRMP3_FALSE; /* Trying to seek too far forward. */
- }
- } else {
- if (pMP3->memory.currentReadPos < (size_t)-byteOffset) {
- return DRMP3_FALSE; /* Trying to seek too far backwards. */
- }
- }
+ newCursor = pMP3->memory.currentReadPos;
- /* This will never underflow thanks to the clamps above. */
- pMP3->memory.currentReadPos += byteOffset;
- } else if (origin == drmp3_seek_origin_start) {
- if ((drmp3_uint32)byteOffset <= pMP3->memory.dataSize) {
- pMP3->memory.currentReadPos = byteOffset;
- } else {
- return DRMP3_FALSE; /* Trying to seek too far forward. */
- }
- } else if (origin == drmp3_seek_origin_end) {
- if (byteOffset > 0) {
- return DRMP3_FALSE; /* Trying to seek beyond the end of the buffer. */
- }
+ if (origin == DRMP3_SEEK_SET) {
+ newCursor = 0;
+ } else if (origin == DRMP3_SEEK_CUR) {
+ newCursor = (drmp3_int64)pMP3->memory.currentReadPos;
+ } else if (origin == DRMP3_SEEK_END) {
+ newCursor = (drmp3_int64)pMP3->memory.dataSize;
+ } else {
+ DRMP3_ASSERT(!"Invalid seek origin");
+ return DRMP3_FALSE;
+ }
- if ((size_t)(-byteOffset) > pMP3->memory.dataSize) {
- return DRMP3_FALSE; /* Trying to seek too far back. */
- }
+ newCursor += byteOffset;
- pMP3->memory.currentReadPos = pMP3->memory.dataSize - (size_t)(-byteOffset);
+ if (newCursor < 0) {
+ return DRMP3_FALSE; /* Trying to seek prior to the start of the buffer. */
+ }
+ if ((size_t)newCursor > pMP3->memory.dataSize) {
+ return DRMP3_FALSE; /* Trying to seek beyond the end of the buffer. */
}
+ pMP3->memory.currentReadPos = (size_t)newCursor;
+
return DRMP3_TRUE;
}
@@ -3987,9 +3981,9 @@ static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t byt
static drmp3_bool32 drmp3__on_seek_stdio(void* pUserData, int offset, drmp3_seek_origin origin)
{
int whence = SEEK_SET;
- if (origin == drmp3_seek_origin_current) {
+ if (origin == DRMP3_SEEK_CUR) {
whence = SEEK_CUR;
- } else if (origin == drmp3_seek_origin_end) {
+ } else if (origin == DRMP3_SEEK_END) {
whence = SEEK_END;
}
@@ -4330,7 +4324,7 @@ static drmp3_bool32 drmp3_seek_to_start_of_stream(drmp3* pMP3)
DRMP3_ASSERT(pMP3->onSeek != NULL);
/* Seek to the start of the stream to begin with. */
- if (!drmp3__on_seek_64(pMP3, pMP3->streamStartOffset, drmp3_seek_origin_start)) {
+ if (!drmp3__on_seek_64(pMP3, pMP3->streamStartOffset, DRMP3_SEEK_SET)) {
return DRMP3_FALSE;
}
@@ -4430,7 +4424,7 @@ static drmp3_bool32 drmp3_seek_to_pcm_frame__seek_table(drmp3* pMP3, drmp3_uint6
}
/* First thing to do is seek to the first byte of the relevant MP3 frame. */
- if (!drmp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, drmp3_seek_origin_start)) {
+ if (!drmp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, DRMP3_SEEK_SET)) {
return DRMP3_FALSE; /* Failed to seek. */
}
@@ -5014,9 +5008,13 @@ DIFFERENCES BETWEEN minimp3 AND dr_mp3
/*
REVISION HISTORY
================
-v0.7.0 - TBD
+v0.7.0 - 2025-07-23
- The old `DRMP3_IMPLEMENTATION` has been removed. Use `DR_MP3_IMPLEMENTATION` instead. The reason for this change is that in the future everything will eventually be using the underscored naming convention in the future, so `drmp3` will become `dr_mp3`.
- - API CHANGE: Add drmp3_seek_origin_end as a seek origin for the seek callback. This is required for detection of ID3v1 and APE tags.
+ - API CHANGE: Seek origins have been renamed to match the naming convention used by dr_wav and my other libraries.
+ - drmp3_seek_origin_start -> DRMP3_SEEK_SET
+ - drmp3_seek_origin_current -> DRMP3_SEEK_CUR
+ - DRMP3_SEEK_END (new)
+ - API CHANGE: Add DRMP3_SEEK_END as a seek origin for the seek callback. This is required for detection of ID3v1 and APE tags.
- API CHANGE: Add onTell callback to `drmp3_init()`. This is needed in order to track the location of ID3v1 and APE tags.
- API CHANGE: Add onMeta callback to `drmp3_init()`. This is used for reporting tag data back to the caller. Currently this only reports the raw tag data which means applications need to parse the data themselves.
- API CHANGE: Rename `drmp3dec_frame_info.hz` to `drmp3dec_frame_info.sample_rate`.