Support WavPack in st_audiofile
This commit is contained in:
parent
bca192de54
commit
a35110c706
4 changed files with 84 additions and 0 deletions
77
external/st_audiofile/src/st_audiofile.c
vendored
77
external/st_audiofile/src/st_audiofile.c
vendored
|
|
@ -17,12 +17,14 @@ struct st_audio_file {
|
||||||
AIFF_Ref aiff;
|
AIFF_Ref aiff;
|
||||||
drmp3 *mp3;
|
drmp3 *mp3;
|
||||||
stb_vorbis* ogg;
|
stb_vorbis* ogg;
|
||||||
|
WavpackContext* wv;
|
||||||
};
|
};
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct { uint32_t channels; float sample_rate; uint64_t frames; } aiff;
|
struct { uint32_t channels; float sample_rate; uint64_t frames; } aiff;
|
||||||
struct { uint64_t frames; } mp3;
|
struct { uint64_t frames; } mp3;
|
||||||
struct { uint32_t channels; float sample_rate; uint64_t frames; } ogg;
|
struct { uint32_t channels; float sample_rate; uint64_t frames; } ogg;
|
||||||
|
struct { uint32_t channels; float sample_rate; uint64_t frames; int bitrate; int mode; } wv;
|
||||||
} cache;
|
} cache;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
|
@ -173,6 +175,25 @@ static st_audio_file* st_generic_open_file(const void* filename, int widepath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try WV
|
||||||
|
{
|
||||||
|
af->wv =
|
||||||
|
#if defined(_WIN32)
|
||||||
|
WavpackOpenFileInput((const char*)filename, NULL, OPEN_FILE_UTF8, 0);
|
||||||
|
#else
|
||||||
|
WavpackOpenFileInput((const char*)filename, NULL, 0, 0);
|
||||||
|
#endif
|
||||||
|
if (af->wv) {
|
||||||
|
af->cache.wv.channels = (uint32_t)WavpackGetNumChannels(af->wv);
|
||||||
|
af->cache.wv.sample_rate = (float)WavpackGetSampleRate(af->wv);
|
||||||
|
af->cache.wv.frames = (uint64_t)WavpackGetNumSamples64(af->wv);
|
||||||
|
af->cache.wv.bitrate = WavpackGetBitsPerSample(af->wv);
|
||||||
|
af->cache.wv.mode = WavpackGetMode(af->wv);
|
||||||
|
af->type = st_audio_file_wv;
|
||||||
|
return af;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(af);
|
free(af);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -278,6 +299,17 @@ st_audio_file* st_open_memory(const void* memory, size_t length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try WV
|
||||||
|
{
|
||||||
|
af->wv =
|
||||||
|
WavpackOpenRawDecoder((void*)memory, (int32_t)length, NULL, 0,
|
||||||
|
WAVPACK_MEMORY_ASSUMED_VERSION, NULL, 0, 0);
|
||||||
|
if (af->wv) {
|
||||||
|
af->type = st_audio_file_wv;
|
||||||
|
return af;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(af);
|
free(af);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -315,6 +347,9 @@ void st_close(st_audio_file* af)
|
||||||
drmp3_uninit(af->mp3);
|
drmp3_uninit(af->mp3);
|
||||||
free(af->mp3);
|
free(af->mp3);
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_wv:
|
||||||
|
WavpackCloseFile(af->wv);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(af);
|
free(af);
|
||||||
|
|
@ -345,6 +380,9 @@ uint32_t st_get_channels(st_audio_file* af)
|
||||||
case st_audio_file_mp3:
|
case st_audio_file_mp3:
|
||||||
channels = af->mp3->channels;
|
channels = af->mp3->channels;
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_wv:
|
||||||
|
channels = af->cache.wv.channels;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return channels;
|
return channels;
|
||||||
|
|
@ -370,6 +408,9 @@ float st_get_sample_rate(st_audio_file* af)
|
||||||
case st_audio_file_mp3:
|
case st_audio_file_mp3:
|
||||||
sample_rate = af->mp3->sampleRate;
|
sample_rate = af->mp3->sampleRate;
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_wv:
|
||||||
|
sample_rate = af->cache.wv.sample_rate;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sample_rate;
|
return sample_rate;
|
||||||
|
|
@ -395,6 +436,9 @@ uint64_t st_get_frame_count(st_audio_file* af)
|
||||||
case st_audio_file_mp3:
|
case st_audio_file_mp3:
|
||||||
frames = af->cache.mp3.frames;
|
frames = af->cache.mp3.frames;
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_wv:
|
||||||
|
frames = af->cache.wv.frames;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return frames;
|
return frames;
|
||||||
|
|
@ -420,6 +464,9 @@ bool st_seek(st_audio_file* af, uint64_t frame)
|
||||||
case st_audio_file_mp3:
|
case st_audio_file_mp3:
|
||||||
success = drmp3_seek_to_pcm_frame(af->mp3, frame);
|
success = drmp3_seek_to_pcm_frame(af->mp3, frame);
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_wv:
|
||||||
|
success = WavpackSeekSample64(af->wv, (int64_t)frame);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
|
@ -449,6 +496,24 @@ uint64_t st_read_s16(st_audio_file* af, int16_t* buffer, uint64_t count)
|
||||||
case st_audio_file_mp3:
|
case st_audio_file_mp3:
|
||||||
count = drmp3_read_pcm_frames_s16(af->mp3, count, buffer);
|
count = drmp3_read_pcm_frames_s16(af->mp3, count, buffer);
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_wv:
|
||||||
|
{
|
||||||
|
int32_t* buf_i32 = (int32_t*)malloc(4 * count);
|
||||||
|
if (!buf_i32) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
count = WavpackUnpackSamples(af->wv, buf_i32, (uint32_t)count);
|
||||||
|
if (af->cache.wv.mode & MODE_FLOAT) {
|
||||||
|
drwav_f32_to_s16((drwav_int16*)buffer, (float*)buf_i32, (size_t)count);
|
||||||
|
} else {
|
||||||
|
int d = af->cache.wv.bitrate - 16;
|
||||||
|
for (uint64_t i = 0; i < count; i++) {
|
||||||
|
buffer[i] = (int16_t)(buf_i32[i] >> d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(buf_i32);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
|
@ -478,6 +543,18 @@ uint64_t st_read_f32(st_audio_file* af, float* buffer, uint64_t count)
|
||||||
case st_audio_file_mp3:
|
case st_audio_file_mp3:
|
||||||
count = drmp3_read_pcm_frames_f32(af->mp3, count, buffer);
|
count = drmp3_read_pcm_frames_f32(af->mp3, count, buffer);
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_wv:
|
||||||
|
count = WavpackUnpackSamples(af->wv, (int32_t*)buffer, (uint32_t)count);
|
||||||
|
if (!(af->cache.wv.mode & MODE_FLOAT)) {
|
||||||
|
if (af->cache.wv.bitrate < 32) {
|
||||||
|
int d = 32 - af->cache.wv.bitrate;
|
||||||
|
for (uint64_t i = 0; i < count; i++) {
|
||||||
|
((int32_t*)buffer)[i] <<= d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drwav_s32_to_f32(buffer, (drwav_int32*)buffer, (size_t)count);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
|
|
||||||
3
external/st_audiofile/src/st_audiofile.h
vendored
3
external/st_audiofile/src/st_audiofile.h
vendored
|
|
@ -19,6 +19,8 @@
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define WAVPACK_MEMORY_ASSUMED_VERSION 5
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -31,6 +33,7 @@ typedef enum st_audio_file_type {
|
||||||
st_audio_file_aiff,
|
st_audio_file_aiff,
|
||||||
st_audio_file_ogg,
|
st_audio_file_ogg,
|
||||||
st_audio_file_mp3,
|
st_audio_file_mp3,
|
||||||
|
st_audio_file_wv,
|
||||||
st_audio_file_other,
|
st_audio_file_other,
|
||||||
} st_audio_file_type;
|
} st_audio_file_type;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ const char* st_type_string(int type)
|
||||||
case st_audio_file_mp3:
|
case st_audio_file_mp3:
|
||||||
type_string = "MP3";
|
type_string = "MP3";
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_wv:
|
||||||
|
type_string = "WV";
|
||||||
|
break;
|
||||||
case st_audio_file_other:
|
case st_audio_file_other:
|
||||||
type_string = "other";
|
type_string = "other";
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include "stb_vorbis.c"
|
#include "stb_vorbis.c"
|
||||||
#include "libaiff/libaiff.h"
|
#include "libaiff/libaiff.h"
|
||||||
|
#include "wavpack.h"
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue