mirror of https://github.com/bjornbytes/lovr.git
Rename SourceData to AudioStream;
This commit is contained in:
parent
82ca82862d
commit
9cd47faf05
|
@ -248,7 +248,7 @@ set(LOVR_SRC
|
|||
src/data/font.c
|
||||
src/data/material.c
|
||||
src/data/model.c
|
||||
src/data/source.c
|
||||
src/data/audioStream.c
|
||||
src/data/texture.c
|
||||
src/event/event.c
|
||||
src/filesystem/blob.c
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "api.h"
|
||||
#include "audio/audio.h"
|
||||
#include "audio/source.h"
|
||||
#include "data/source.h"
|
||||
#include "data/audioStream.h"
|
||||
|
||||
map_int_t TimeUnits;
|
||||
|
||||
|
@ -63,8 +63,8 @@ int l_lovrAudioIsSpatialized(lua_State* L) {
|
|||
|
||||
int l_lovrAudioNewSource(lua_State* L) {
|
||||
Blob* blob = luax_readblob(L, 1, "Source");
|
||||
SourceData* sourceData = lovrSourceDataCreate(blob);
|
||||
Source* source = lovrSourceCreate(sourceData);
|
||||
AudioStream* stream = lovrAudioStreamCreate(blob);
|
||||
Source* source = lovrSourceCreate(stream);
|
||||
luax_pushtype(L, Source, source);
|
||||
lovrRelease(&source->ref);
|
||||
lovrRelease(&blob->ref);
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#include "audio/source.h"
|
||||
#include "data/source.h"
|
||||
#include "data/audioStream.h"
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static ALenum lovrSourceGetFormat(Source* source) {
|
||||
int channelCount = source->sourceData->channelCount;
|
||||
int bitDepth = source->sourceData->bitDepth;
|
||||
int channelCount = source->stream->channelCount;
|
||||
int bitDepth = source->stream->bitDepth;
|
||||
|
||||
if (bitDepth == 8 && channelCount == 1) {
|
||||
return AL_FORMAT_MONO8;
|
||||
|
@ -27,11 +27,11 @@ static ALenum lovrSourceGetState(Source* source) {
|
|||
return state;
|
||||
}
|
||||
|
||||
Source* lovrSourceCreate(SourceData* sourceData) {
|
||||
Source* lovrSourceCreate(AudioStream* stream) {
|
||||
Source* source = lovrAlloc(sizeof(Source), lovrSourceDestroy);
|
||||
if (!source) return NULL;
|
||||
|
||||
source->sourceData = sourceData;
|
||||
source->stream = stream;
|
||||
source->isLooping = false;
|
||||
alGenSources(1, &source->id);
|
||||
alGenBuffers(SOURCE_BUFFERS, source->buffers);
|
||||
|
@ -43,12 +43,12 @@ void lovrSourceDestroy(const Ref* ref) {
|
|||
Source* source = containerof(ref, Source);
|
||||
alDeleteSources(1, &source->id);
|
||||
alDeleteBuffers(SOURCE_BUFFERS, source->buffers);
|
||||
lovrSourceDataDestroy(source->sourceData);
|
||||
lovrAudioStreamDestroy(source->stream);
|
||||
free(source);
|
||||
}
|
||||
|
||||
int lovrSourceGetBitDepth(Source* source) {
|
||||
return source->sourceData->bitDepth;
|
||||
return source->stream->bitDepth;
|
||||
}
|
||||
|
||||
void lovrSourceGetCone(Source* source, float* innerAngle, float* outerAngle, float* outerGain) {
|
||||
|
@ -60,7 +60,7 @@ void lovrSourceGetCone(Source* source, float* innerAngle, float* outerAngle, flo
|
|||
}
|
||||
|
||||
int lovrSourceGetChannelCount(Source* source) {
|
||||
return source->sourceData->channelCount;
|
||||
return source->stream->channelCount;
|
||||
}
|
||||
|
||||
void lovrSourceGetDirection(Source* source, float* x, float* y, float* z) {
|
||||
|
@ -72,7 +72,7 @@ void lovrSourceGetDirection(Source* source, float* x, float* y, float* z) {
|
|||
}
|
||||
|
||||
int lovrSourceGetDuration(Source* source) {
|
||||
return source->sourceData->samples;
|
||||
return source->stream->samples;
|
||||
}
|
||||
|
||||
void lovrSourceGetFalloff(Source* source, float* reference, float* max, float* rolloff) {
|
||||
|
@ -96,7 +96,7 @@ void lovrSourceGetPosition(Source* source, float* x, float* y, float* z) {
|
|||
}
|
||||
|
||||
int lovrSourceGetSampleRate(Source* source) {
|
||||
return source->sourceData->sampleRate;
|
||||
return source->stream->sampleRate;
|
||||
}
|
||||
|
||||
void lovrSourceGetVelocity(Source* source, float* x, float* y, float* z) {
|
||||
|
@ -181,7 +181,7 @@ void lovrSourceRewind(Source* source) {
|
|||
void lovrSourceSeek(Source* source, int sample) {
|
||||
bool wasPaused = lovrSourceIsPaused(source);
|
||||
lovrSourceStop(source);
|
||||
lovrSourceDataSeek(source->sourceData, sample);
|
||||
lovrAudioStreamSeek(source->stream, sample);
|
||||
lovrSourcePlay(source);
|
||||
if (wasPaused) {
|
||||
lovrSourcePause(source);
|
||||
|
@ -250,34 +250,34 @@ void lovrSourceStop(Source* source) {
|
|||
alSourcei(source->id, AL_BUFFER, AL_NONE);
|
||||
|
||||
// Rewind the decoder
|
||||
lovrSourceDataRewind(source->sourceData);
|
||||
lovrAudioStreamRewind(source->stream);
|
||||
}
|
||||
|
||||
// Fills buffers with data and queues them, called once initially and over time to stream more data
|
||||
void lovrSourceStream(Source* source, ALuint* buffers, int count) {
|
||||
SourceData* sourceData = source->sourceData;
|
||||
AudioStream* stream = source->stream;
|
||||
ALenum format = lovrSourceGetFormat(source);
|
||||
int frequency = sourceData->sampleRate;
|
||||
int frequency = stream->sampleRate;
|
||||
int samples = 0;
|
||||
int n = 0;
|
||||
|
||||
// Keep decoding until there is nothing left to decode or all the buffers are filled
|
||||
while (n < count && (samples = lovrSourceDataDecode(sourceData)) != 0) {
|
||||
alBufferData(buffers[n++], format, sourceData->buffer, samples * sizeof(ALshort), frequency);
|
||||
while (n < count && (samples = lovrAudioStreamDecode(stream)) != 0) {
|
||||
alBufferData(buffers[n++], format, stream->buffer, samples * sizeof(ALshort), frequency);
|
||||
}
|
||||
|
||||
alSourceQueueBuffers(source->id, n, buffers);
|
||||
|
||||
if (samples == 0 && source->isLooping && n < count) {
|
||||
lovrSourceDataRewind(sourceData);
|
||||
lovrAudioStreamRewind(stream);
|
||||
lovrSourceStream(source, buffers + n, count - n);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int lovrSourceTell(Source* source) {
|
||||
int decoderOffset = lovrSourceDataTell(source->sourceData);
|
||||
int samplesPerBuffer = source->sourceData->bufferSize / source->sourceData->channelCount / sizeof(ALshort);
|
||||
int decoderOffset = lovrAudioStreamTell(source->stream);
|
||||
int samplesPerBuffer = source->stream->bufferSize / source->stream->channelCount / sizeof(ALshort);
|
||||
int queuedBuffers, sampleOffset;
|
||||
alGetSourcei(source->id, AL_BUFFERS_QUEUED, &queuedBuffers);
|
||||
alGetSourcei(source->id, AL_SAMPLE_OFFSET, &sampleOffset);
|
||||
|
@ -285,7 +285,7 @@ int lovrSourceTell(Source* source) {
|
|||
int offset = decoderOffset - queuedBuffers * samplesPerBuffer + sampleOffset;
|
||||
|
||||
if (offset < 0) {
|
||||
return offset + source->sourceData->samples;
|
||||
return offset + source->stream->samples;
|
||||
} else {
|
||||
return offset;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "data/source.h"
|
||||
#include "data/audioStream.h"
|
||||
#include "util.h"
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
|
@ -15,13 +15,13 @@ typedef enum {
|
|||
|
||||
typedef struct {
|
||||
Ref ref;
|
||||
SourceData* sourceData;
|
||||
AudioStream* stream;
|
||||
ALuint id;
|
||||
ALuint buffers[SOURCE_BUFFERS];
|
||||
bool isLooping;
|
||||
} Source;
|
||||
|
||||
Source* lovrSourceCreate(SourceData* sourceData);
|
||||
Source* lovrSourceCreate(AudioStream* stream);
|
||||
void lovrSourceDestroy(const Ref* ref);
|
||||
int lovrSourceGetBitDepth(Source* source);
|
||||
int lovrSourceGetChannelCount(Source* source);
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
#include "data/audioStream.h"
|
||||
#include "lib/stb/stb_vorbis.h"
|
||||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
AudioStream* lovrAudioStreamCreate(Blob* blob) {
|
||||
AudioStream* stream = malloc(sizeof(AudioStream));
|
||||
if (!stream) return NULL;
|
||||
|
||||
stb_vorbis* decoder = stb_vorbis_open_memory(blob->data, blob->size, NULL, NULL);
|
||||
|
||||
if (!decoder) {
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stb_vorbis_info info = stb_vorbis_get_info(decoder);
|
||||
|
||||
stream->bitDepth = 16;
|
||||
stream->channelCount = info.channels;
|
||||
stream->sampleRate = info.sample_rate;
|
||||
stream->samples = stb_vorbis_stream_length_in_samples(decoder);
|
||||
stream->decoder = decoder;
|
||||
stream->bufferSize = stream->channelCount * 4096 * sizeof(short);
|
||||
stream->buffer = malloc(stream->bufferSize);
|
||||
stream->blob = blob;
|
||||
lovrRetain(&blob->ref);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
void lovrAudioStreamDestroy(AudioStream* stream) {
|
||||
stb_vorbis_close(stream->decoder);
|
||||
lovrRelease(&stream->blob->ref);
|
||||
free(stream->buffer);
|
||||
free(stream);
|
||||
}
|
||||
|
||||
int lovrAudioStreamDecode(AudioStream* stream) {
|
||||
stb_vorbis* decoder = (stb_vorbis*) stream->decoder;
|
||||
short* buffer = (short*) stream->buffer;
|
||||
int channelCount = stream->channelCount;
|
||||
int capacity = stream->bufferSize / sizeof(short);
|
||||
int samples = 0;
|
||||
|
||||
while (samples < capacity) {
|
||||
int count = stb_vorbis_get_samples_short_interleaved(decoder, channelCount, buffer + samples, capacity - samples);
|
||||
if (count == 0) break;
|
||||
samples += count * channelCount;
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
void lovrAudioStreamRewind(AudioStream* stream) {
|
||||
stb_vorbis* decoder = (stb_vorbis*) stream->decoder;
|
||||
stb_vorbis_seek_start(decoder);
|
||||
}
|
||||
|
||||
void lovrAudioStreamSeek(AudioStream* stream, int sample) {
|
||||
stb_vorbis* decoder = (stb_vorbis*) stream->decoder;
|
||||
stb_vorbis_seek(decoder, sample);
|
||||
}
|
||||
|
||||
int lovrAudioStreamTell(AudioStream* stream) {
|
||||
stb_vorbis* decoder = (stb_vorbis*) stream->decoder;
|
||||
return stb_vorbis_get_sample_offset(decoder);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#include "filesystem/blob.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct {
|
||||
int bitDepth;
|
||||
int channelCount;
|
||||
int sampleRate;
|
||||
int samples;
|
||||
int bufferSize;
|
||||
void* buffer;
|
||||
void* decoder;
|
||||
Blob* blob;
|
||||
} AudioStream;
|
||||
|
||||
AudioStream* lovrAudioStreamCreate(Blob* blob);
|
||||
void lovrAudioStreamDestroy(AudioStream* stream);
|
||||
int lovrAudioStreamDecode(AudioStream* stream);
|
||||
void lovrAudioStreamRewind(AudioStream* stream);
|
||||
void lovrAudioStreamSeek(AudioStream* stream, int sample);
|
||||
int lovrAudioStreamTell(AudioStream* stream);
|
|
@ -1,68 +0,0 @@
|
|||
#include "data/source.h"
|
||||
#include "lib/stb/stb_vorbis.h"
|
||||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
SourceData* lovrSourceDataCreate(Blob* blob) {
|
||||
SourceData* sourceData = malloc(sizeof(SourceData));
|
||||
if (!sourceData) return NULL;
|
||||
|
||||
stb_vorbis* decoder = stb_vorbis_open_memory(blob->data, blob->size, NULL, NULL);
|
||||
|
||||
if (!decoder) {
|
||||
free(sourceData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stb_vorbis_info info = stb_vorbis_get_info(decoder);
|
||||
|
||||
sourceData->bitDepth = 16;
|
||||
sourceData->channelCount = info.channels;
|
||||
sourceData->sampleRate = info.sample_rate;
|
||||
sourceData->samples = stb_vorbis_stream_length_in_samples(decoder);
|
||||
sourceData->decoder = decoder;
|
||||
sourceData->bufferSize = sourceData->channelCount * 4096 * sizeof(short);
|
||||
sourceData->buffer = malloc(sourceData->bufferSize);
|
||||
sourceData->blob = blob;
|
||||
lovrRetain(&blob->ref);
|
||||
|
||||
return sourceData;
|
||||
}
|
||||
|
||||
void lovrSourceDataDestroy(SourceData* sourceData) {
|
||||
stb_vorbis_close(sourceData->decoder);
|
||||
lovrRelease(&sourceData->blob->ref);
|
||||
free(sourceData->buffer);
|
||||
free(sourceData);
|
||||
}
|
||||
|
||||
int lovrSourceDataDecode(SourceData* sourceData) {
|
||||
stb_vorbis* decoder = (stb_vorbis*) sourceData->decoder;
|
||||
short* buffer = (short*) sourceData->buffer;
|
||||
int channelCount = sourceData->channelCount;
|
||||
int capacity = sourceData->bufferSize / sizeof(short);
|
||||
int samples = 0;
|
||||
|
||||
while (samples < capacity) {
|
||||
int count = stb_vorbis_get_samples_short_interleaved(decoder, channelCount, buffer + samples, capacity - samples);
|
||||
if (count == 0) break;
|
||||
samples += count * channelCount;
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
void lovrSourceDataRewind(SourceData* sourceData) {
|
||||
stb_vorbis* decoder = (stb_vorbis*) sourceData->decoder;
|
||||
stb_vorbis_seek_start(decoder);
|
||||
}
|
||||
|
||||
void lovrSourceDataSeek(SourceData* sourceData, int sample) {
|
||||
stb_vorbis* decoder = (stb_vorbis*) sourceData->decoder;
|
||||
stb_vorbis_seek(decoder, sample);
|
||||
}
|
||||
|
||||
int lovrSourceDataTell(SourceData* sourceData) {
|
||||
stb_vorbis* decoder = (stb_vorbis*) sourceData->decoder;
|
||||
return stb_vorbis_get_sample_offset(decoder);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
#include "filesystem/blob.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct {
|
||||
int bitDepth;
|
||||
int channelCount;
|
||||
int sampleRate;
|
||||
int samples;
|
||||
int bufferSize;
|
||||
void* buffer;
|
||||
void* decoder;
|
||||
Blob* blob;
|
||||
} SourceData;
|
||||
|
||||
SourceData* lovrSourceDataCreate(Blob* blob);
|
||||
void lovrSourceDataDestroy(SourceData* sourceData);
|
||||
int lovrSourceDataDecode(SourceData* sourceData);
|
||||
void lovrSourceDataRewind(SourceData* sourceData);
|
||||
void lovrSourceDataSeek(SourceData* sourceData, int sample);
|
||||
int lovrSourceDataTell(SourceData* sourceData);
|
Loading…
Reference in New Issue