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/font.c
|
||||||
src/data/material.c
|
src/data/material.c
|
||||||
src/data/model.c
|
src/data/model.c
|
||||||
src/data/source.c
|
src/data/audioStream.c
|
||||||
src/data/texture.c
|
src/data/texture.c
|
||||||
src/event/event.c
|
src/event/event.c
|
||||||
src/filesystem/blob.c
|
src/filesystem/blob.c
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
#include "audio/audio.h"
|
#include "audio/audio.h"
|
||||||
#include "audio/source.h"
|
#include "audio/source.h"
|
||||||
#include "data/source.h"
|
#include "data/audioStream.h"
|
||||||
|
|
||||||
map_int_t TimeUnits;
|
map_int_t TimeUnits;
|
||||||
|
|
||||||
|
@ -63,8 +63,8 @@ int l_lovrAudioIsSpatialized(lua_State* L) {
|
||||||
|
|
||||||
int l_lovrAudioNewSource(lua_State* L) {
|
int l_lovrAudioNewSource(lua_State* L) {
|
||||||
Blob* blob = luax_readblob(L, 1, "Source");
|
Blob* blob = luax_readblob(L, 1, "Source");
|
||||||
SourceData* sourceData = lovrSourceDataCreate(blob);
|
AudioStream* stream = lovrAudioStreamCreate(blob);
|
||||||
Source* source = lovrSourceCreate(sourceData);
|
Source* source = lovrSourceCreate(stream);
|
||||||
luax_pushtype(L, Source, source);
|
luax_pushtype(L, Source, source);
|
||||||
lovrRelease(&source->ref);
|
lovrRelease(&source->ref);
|
||||||
lovrRelease(&blob->ref);
|
lovrRelease(&blob->ref);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#include "audio/source.h"
|
#include "audio/source.h"
|
||||||
#include "data/source.h"
|
#include "data/audioStream.h"
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
static ALenum lovrSourceGetFormat(Source* source) {
|
static ALenum lovrSourceGetFormat(Source* source) {
|
||||||
int channelCount = source->sourceData->channelCount;
|
int channelCount = source->stream->channelCount;
|
||||||
int bitDepth = source->sourceData->bitDepth;
|
int bitDepth = source->stream->bitDepth;
|
||||||
|
|
||||||
if (bitDepth == 8 && channelCount == 1) {
|
if (bitDepth == 8 && channelCount == 1) {
|
||||||
return AL_FORMAT_MONO8;
|
return AL_FORMAT_MONO8;
|
||||||
|
@ -27,11 +27,11 @@ static ALenum lovrSourceGetState(Source* source) {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
Source* lovrSourceCreate(SourceData* sourceData) {
|
Source* lovrSourceCreate(AudioStream* stream) {
|
||||||
Source* source = lovrAlloc(sizeof(Source), lovrSourceDestroy);
|
Source* source = lovrAlloc(sizeof(Source), lovrSourceDestroy);
|
||||||
if (!source) return NULL;
|
if (!source) return NULL;
|
||||||
|
|
||||||
source->sourceData = sourceData;
|
source->stream = stream;
|
||||||
source->isLooping = false;
|
source->isLooping = false;
|
||||||
alGenSources(1, &source->id);
|
alGenSources(1, &source->id);
|
||||||
alGenBuffers(SOURCE_BUFFERS, source->buffers);
|
alGenBuffers(SOURCE_BUFFERS, source->buffers);
|
||||||
|
@ -43,12 +43,12 @@ void lovrSourceDestroy(const Ref* ref) {
|
||||||
Source* source = containerof(ref, Source);
|
Source* source = containerof(ref, Source);
|
||||||
alDeleteSources(1, &source->id);
|
alDeleteSources(1, &source->id);
|
||||||
alDeleteBuffers(SOURCE_BUFFERS, source->buffers);
|
alDeleteBuffers(SOURCE_BUFFERS, source->buffers);
|
||||||
lovrSourceDataDestroy(source->sourceData);
|
lovrAudioStreamDestroy(source->stream);
|
||||||
free(source);
|
free(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lovrSourceGetBitDepth(Source* source) {
|
int lovrSourceGetBitDepth(Source* source) {
|
||||||
return source->sourceData->bitDepth;
|
return source->stream->bitDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrSourceGetCone(Source* source, float* innerAngle, float* outerAngle, float* outerGain) {
|
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) {
|
int lovrSourceGetChannelCount(Source* source) {
|
||||||
return source->sourceData->channelCount;
|
return source->stream->channelCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrSourceGetDirection(Source* source, float* x, float* y, float* z) {
|
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) {
|
int lovrSourceGetDuration(Source* source) {
|
||||||
return source->sourceData->samples;
|
return source->stream->samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrSourceGetFalloff(Source* source, float* reference, float* max, float* rolloff) {
|
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) {
|
int lovrSourceGetSampleRate(Source* source) {
|
||||||
return source->sourceData->sampleRate;
|
return source->stream->sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrSourceGetVelocity(Source* source, float* x, float* y, float* z) {
|
void lovrSourceGetVelocity(Source* source, float* x, float* y, float* z) {
|
||||||
|
@ -181,7 +181,7 @@ void lovrSourceRewind(Source* source) {
|
||||||
void lovrSourceSeek(Source* source, int sample) {
|
void lovrSourceSeek(Source* source, int sample) {
|
||||||
bool wasPaused = lovrSourceIsPaused(source);
|
bool wasPaused = lovrSourceIsPaused(source);
|
||||||
lovrSourceStop(source);
|
lovrSourceStop(source);
|
||||||
lovrSourceDataSeek(source->sourceData, sample);
|
lovrAudioStreamSeek(source->stream, sample);
|
||||||
lovrSourcePlay(source);
|
lovrSourcePlay(source);
|
||||||
if (wasPaused) {
|
if (wasPaused) {
|
||||||
lovrSourcePause(source);
|
lovrSourcePause(source);
|
||||||
|
@ -250,34 +250,34 @@ void lovrSourceStop(Source* source) {
|
||||||
alSourcei(source->id, AL_BUFFER, AL_NONE);
|
alSourcei(source->id, AL_BUFFER, AL_NONE);
|
||||||
|
|
||||||
// Rewind the decoder
|
// 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
|
// 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) {
|
void lovrSourceStream(Source* source, ALuint* buffers, int count) {
|
||||||
SourceData* sourceData = source->sourceData;
|
AudioStream* stream = source->stream;
|
||||||
ALenum format = lovrSourceGetFormat(source);
|
ALenum format = lovrSourceGetFormat(source);
|
||||||
int frequency = sourceData->sampleRate;
|
int frequency = stream->sampleRate;
|
||||||
int samples = 0;
|
int samples = 0;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
// Keep decoding until there is nothing left to decode or all the buffers are filled
|
// Keep decoding until there is nothing left to decode or all the buffers are filled
|
||||||
while (n < count && (samples = lovrSourceDataDecode(sourceData)) != 0) {
|
while (n < count && (samples = lovrAudioStreamDecode(stream)) != 0) {
|
||||||
alBufferData(buffers[n++], format, sourceData->buffer, samples * sizeof(ALshort), frequency);
|
alBufferData(buffers[n++], format, stream->buffer, samples * sizeof(ALshort), frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
alSourceQueueBuffers(source->id, n, buffers);
|
alSourceQueueBuffers(source->id, n, buffers);
|
||||||
|
|
||||||
if (samples == 0 && source->isLooping && n < count) {
|
if (samples == 0 && source->isLooping && n < count) {
|
||||||
lovrSourceDataRewind(sourceData);
|
lovrAudioStreamRewind(stream);
|
||||||
lovrSourceStream(source, buffers + n, count - n);
|
lovrSourceStream(source, buffers + n, count - n);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int lovrSourceTell(Source* source) {
|
int lovrSourceTell(Source* source) {
|
||||||
int decoderOffset = lovrSourceDataTell(source->sourceData);
|
int decoderOffset = lovrAudioStreamTell(source->stream);
|
||||||
int samplesPerBuffer = source->sourceData->bufferSize / source->sourceData->channelCount / sizeof(ALshort);
|
int samplesPerBuffer = source->stream->bufferSize / source->stream->channelCount / sizeof(ALshort);
|
||||||
int queuedBuffers, sampleOffset;
|
int queuedBuffers, sampleOffset;
|
||||||
alGetSourcei(source->id, AL_BUFFERS_QUEUED, &queuedBuffers);
|
alGetSourcei(source->id, AL_BUFFERS_QUEUED, &queuedBuffers);
|
||||||
alGetSourcei(source->id, AL_SAMPLE_OFFSET, &sampleOffset);
|
alGetSourcei(source->id, AL_SAMPLE_OFFSET, &sampleOffset);
|
||||||
|
@ -285,7 +285,7 @@ int lovrSourceTell(Source* source) {
|
||||||
int offset = decoderOffset - queuedBuffers * samplesPerBuffer + sampleOffset;
|
int offset = decoderOffset - queuedBuffers * samplesPerBuffer + sampleOffset;
|
||||||
|
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
return offset + source->sourceData->samples;
|
return offset + source->stream->samples;
|
||||||
} else {
|
} else {
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "data/source.h"
|
#include "data/audioStream.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <AL/al.h>
|
#include <AL/al.h>
|
||||||
#include <AL/alc.h>
|
#include <AL/alc.h>
|
||||||
|
@ -15,13 +15,13 @@ typedef enum {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Ref ref;
|
Ref ref;
|
||||||
SourceData* sourceData;
|
AudioStream* stream;
|
||||||
ALuint id;
|
ALuint id;
|
||||||
ALuint buffers[SOURCE_BUFFERS];
|
ALuint buffers[SOURCE_BUFFERS];
|
||||||
bool isLooping;
|
bool isLooping;
|
||||||
} Source;
|
} Source;
|
||||||
|
|
||||||
Source* lovrSourceCreate(SourceData* sourceData);
|
Source* lovrSourceCreate(AudioStream* stream);
|
||||||
void lovrSourceDestroy(const Ref* ref);
|
void lovrSourceDestroy(const Ref* ref);
|
||||||
int lovrSourceGetBitDepth(Source* source);
|
int lovrSourceGetBitDepth(Source* source);
|
||||||
int lovrSourceGetChannelCount(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