Update buildtools, revise WAV reading code.
This commit is contained in:
parent
670eed74b4
commit
697b1308d8
@ -1 +1 @@
|
|||||||
Subproject commit 29ab2234e7376807d154a2a06b5d3d49ad50f631
|
Subproject commit 78acb42849b6d8316a2a9de52c4cc41b784d4508
|
@ -45,7 +45,7 @@ u8* convert_to_cwav(const std::string& file, u32* size) {
|
|||||||
cwav.channels = wav->format.numChannels;
|
cwav.channels = wav->format.numChannels;
|
||||||
cwav.sampleRate = wav->format.sampleRate;
|
cwav.sampleRate = wav->format.sampleRate;
|
||||||
cwav.bitsPerSample = wav->format.bitsPerSample;
|
cwav.bitsPerSample = wav->format.bitsPerSample;
|
||||||
cwav.dataSize = wav->data.chunkSize;
|
cwav.dataSize = wav->data.size;
|
||||||
cwav.data = wav->data.data;
|
cwav.data = wav->data.data;
|
||||||
|
|
||||||
ret = cwav_build(cwav, size);
|
ret = cwav_build(cwav, size);
|
||||||
@ -59,10 +59,10 @@ u8* convert_to_cwav(const std::string& file, u32* size) {
|
|||||||
stb_vorbis_info info = stb_vorbis_get_info(vorb);
|
stb_vorbis_info info = stb_vorbis_get_info(vorb);
|
||||||
|
|
||||||
CWAV cwav;
|
CWAV cwav;
|
||||||
cwav.channels = info.channels;
|
cwav.channels = (u32) info.channels;
|
||||||
cwav.sampleRate = info.sample_rate;
|
cwav.sampleRate = info.sample_rate;
|
||||||
cwav.bitsPerSample = 16; // stb_vorbis always outputs 16 bit samples
|
cwav.bitsPerSample = 16; // stb_vorbis always outputs 16 bit samples
|
||||||
int sampleCount = stb_vorbis_stream_length_in_samples(vorb) * info.channels;
|
u32 sampleCount = stb_vorbis_stream_length_in_samples(vorb) * info.channels;
|
||||||
cwav.dataSize = sampleCount * 2;
|
cwav.dataSize = sampleCount * 2;
|
||||||
cwav.data = (u8*) calloc(sampleCount, 2);
|
cwav.data = (u8*) calloc(sampleCount, 2);
|
||||||
stb_vorbis_get_samples_short_interleaved(vorb, info.channels, (short*) cwav.data, sampleCount);
|
stb_vorbis_get_samples_short_interleaved(vorb, info.channels, (short*) cwav.data, sampleCount);
|
||||||
|
@ -4,17 +4,35 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
bool wav_find_chunk(FILE* fd, const char* magic) {
|
typedef struct {
|
||||||
char curr[5] = {0};
|
FILE* fd;
|
||||||
for(long pos = ftell(fd); strcmp(curr, magic) != 0; pos++) {
|
WavChunkHeader currChunk;
|
||||||
fseek(fd, pos, SEEK_SET);
|
long currChunkDataPos;
|
||||||
size_t read = fread(curr, 1, 4, fd);
|
} WavContext;
|
||||||
if(read <= 0) {
|
|
||||||
|
static bool wav_next_chunk(WavContext* context) {
|
||||||
|
if(fseek(context->fd, context->currChunkDataPos + (memcmp(context->currChunk.chunkId, "RIFF", 4) == 0 ? 4 : context->currChunk.chunkSize), SEEK_SET) < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(fread(&context->currChunk, sizeof(WavChunkHeader), 1, context->fd) <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
context->currChunkDataPos = ftell(context->fd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool wav_read_chunk_data(WavContext* context, void* data, size_t maxSize) {
|
||||||
|
if(fseek(context->fd, context->currChunkDataPos, SEEK_SET) < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size = context->currChunk.chunkSize < maxSize ? context->currChunk.chunkSize : maxSize;
|
||||||
|
if(fread(data, size, 1, context->fd) <= 0) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(fd, -4, SEEK_CUR);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,43 +42,48 @@ WAV* wav_read(FILE* fd) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!wav_find_chunk(fd, "RIFF")) {
|
WAV* wav = (WAV*) calloc(1, sizeof(WAV));
|
||||||
printf("ERROR: Could not find WAV RIFF chunk.\n");
|
|
||||||
|
WavContext context;
|
||||||
|
memset(&context, 0, sizeof(context));
|
||||||
|
context.fd = fd;
|
||||||
|
|
||||||
|
u32 foundChunks = 0;
|
||||||
|
while(wav_next_chunk(&context)) {
|
||||||
|
if(memcmp(context.currChunk.chunkId, "RIFF", 4) == 0) {
|
||||||
|
if(wav_read_chunk_data(&context, &wav->riff, sizeof(WavRiffChunk))) {
|
||||||
|
foundChunks++;
|
||||||
|
}
|
||||||
|
} else if(memcmp(context.currChunk.chunkId, "fmt ", 4) == 0) {
|
||||||
|
if(wav_read_chunk_data(&context, &wav->format, sizeof(WavFormatChunk))) {
|
||||||
|
foundChunks++;
|
||||||
|
}
|
||||||
|
} else if(memcmp(context.currChunk.chunkId, "data", 4) == 0) {
|
||||||
|
wav->data.size = context.currChunk.chunkSize;
|
||||||
|
wav->data.data = (u8*) malloc(wav->data.size);
|
||||||
|
if(wav_read_chunk_data(&context, wav->data.data, wav->data.size)) {
|
||||||
|
foundChunks++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(foundChunks != 3) {
|
||||||
|
wav_free(wav);
|
||||||
|
|
||||||
|
printf("ERROR: Failed to read WAV chunks: %s\n", errno != 0 ? strerror(errno) : "Not enough chunks.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Riff riff;
|
|
||||||
fread(&riff, sizeof(Riff), 1, fd);
|
|
||||||
|
|
||||||
if(!wav_find_chunk(fd, "fmt ")) {
|
|
||||||
printf("ERROR: Could not find WAV format chunk.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Format format;
|
|
||||||
fread(&format, sizeof(Format), 1, fd);
|
|
||||||
|
|
||||||
if(!wav_find_chunk(fd, "data")) {
|
|
||||||
printf("ERROR: Could not find WAV data chunk.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Data data;
|
|
||||||
fread(&(data.chunkId), sizeof(data.chunkId), 1, fd);
|
|
||||||
fread(&(data.chunkSize), sizeof(data.chunkSize), 1, fd);
|
|
||||||
data.data = (u8*) malloc(data.chunkSize);
|
|
||||||
fread(data.data, 1, data.chunkSize, fd);
|
|
||||||
|
|
||||||
WAV* wav = (WAV*) malloc(sizeof(WAV));
|
|
||||||
wav->riff = riff;
|
|
||||||
wav->format = format;
|
|
||||||
wav->data = data;
|
|
||||||
return wav;
|
return wav;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wav_free(WAV* wav) {
|
void wav_free(WAV* wav) {
|
||||||
if(wav != NULL) {
|
if(wav != NULL) {
|
||||||
|
if(wav->data.data != NULL) {
|
||||||
free(wav->data.data);
|
free(wav->data.data);
|
||||||
|
wav->data.data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
free(wav);
|
free(wav);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,30 +8,30 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
char chunkId[4];
|
char chunkId[4];
|
||||||
u32 chunkSize;
|
u32 chunkSize;
|
||||||
char format[4];
|
} WavChunkHeader;
|
||||||
} Riff;
|
|
||||||
|
typedef struct {
|
||||||
|
char format[4];
|
||||||
|
} WavRiffChunk;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char chunkId[4];
|
|
||||||
u32 chunkSize;
|
|
||||||
u16 format;
|
u16 format;
|
||||||
u16 numChannels;
|
u16 numChannels;
|
||||||
u32 sampleRate;
|
u32 sampleRate;
|
||||||
u32 byteRate;
|
u32 byteRate;
|
||||||
u16 align;
|
u16 align;
|
||||||
u16 bitsPerSample;
|
u16 bitsPerSample;
|
||||||
} Format;
|
} WavFormatChunk;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char chunkId[4];
|
u32 size;
|
||||||
u32 chunkSize;
|
|
||||||
u8* data;
|
u8* data;
|
||||||
} Data;
|
} WavDataChunk;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Riff riff;
|
WavRiffChunk riff;
|
||||||
Format format;
|
WavFormatChunk format;
|
||||||
Data data;
|
WavDataChunk data;
|
||||||
} WAV;
|
} WAV;
|
||||||
|
|
||||||
WAV* wav_read(FILE* fd);
|
WAV* wav_read(FILE* fd);
|
||||||
|
Loading…
Reference in New Issue
Block a user