2018-07-06 03:23:46 +00:00
# include "api.h"
# include "data/soundData.h"
2020-11-26 21:14:02 +00:00
# include "data/blob.h"
2020-12-16 15:07:29 +00:00
# include "core/ref.h"
2020-12-19 22:17:16 +00:00
# include "core/util.h"
2020-12-16 15:07:29 +00:00
# include <stdlib.h>
2021-02-05 21:06:25 +00:00
StringEntry lovrSampleFormat [ ] = {
[ SAMPLE_F32 ] = ENTRY ( " f32 " ) ,
[ SAMPLE_I16 ] = ENTRY ( " i16 " ) ,
{ 0 }
} ;
static int l_lovrSoundDataGetFormat ( lua_State * L ) {
2020-11-26 21:14:02 +00:00
SoundData * soundData = luax_checktype ( L , 1 , SoundData ) ;
2021-02-05 21:06:25 +00:00
luax_pushenum ( L , SampleFormat , soundData - > format ) ;
return 1 ;
}
static int l_lovrSoundDataGetSampleRate ( lua_State * L ) {
SoundData * soundData = luax_checktype ( L , 1 , SoundData ) ;
lua_pushinteger ( L , soundData - > sampleRate ) ;
return 1 ;
}
static int l_lovrSoundDataGetChannelCount ( lua_State * L ) {
SoundData * soundData = luax_checktype ( L , 1 , SoundData ) ;
lua_pushinteger ( L , soundData - > channels ) ;
2020-11-26 21:14:02 +00:00
return 1 ;
}
2018-07-06 03:23:46 +00:00
2021-02-04 18:25:06 +00:00
static int l_lovrSoundDataGetFrameCount ( lua_State * L ) {
2020-12-16 15:07:29 +00:00
SoundData * soundData = luax_checktype ( L , 1 , SoundData ) ;
2021-02-04 18:25:06 +00:00
uint32_t frames = lovrSoundDataGetFrameCount ( soundData ) ;
lua_pushinteger ( L , frames ) ;
2020-12-16 15:07:29 +00:00
return 1 ;
}
2021-02-05 21:06:25 +00:00
static int l_lovrSoundDataIsCompressed ( lua_State * L ) {
SoundData * soundData = luax_checktype ( L , 1 , SoundData ) ;
bool compressed = lovrSoundDataIsCompressed ( soundData ) ;
lua_pushboolean ( L , compressed ) ;
return 1 ;
}
static int l_lovrSoundDataIsStream ( lua_State * L ) {
SoundData * soundData = luax_checktype ( L , 1 , SoundData ) ;
bool stream = lovrSoundDataIsStream ( soundData ) ;
lua_pushboolean ( L , stream ) ;
return 1 ;
}
static int l_lovrSoundDataGetBlob ( lua_State * L ) {
SoundData * soundData = luax_checktype ( L , 1 , SoundData ) ;
Blob * blob = soundData - > blob ;
luax_pushtype ( L , Blob , blob ) ;
return 1 ;
}
2020-12-16 15:07:29 +00:00
// soundData:read(dest, {size}, {offset}) -> framesRead
// soundData:read({size}) -> framesRead
static int l_lovrSoundDataRead ( lua_State * L ) {
//struct SoundData* soundData, uint32_t offset, uint32_t count, void* data
SoundData * source = luax_checktype ( L , 1 , SoundData ) ;
int index = 2 ;
SoundData * dest = luax_totype ( L , index , SoundData ) ;
2020-12-16 15:47:51 +00:00
if ( dest ) index + + ;
2021-02-04 18:25:06 +00:00
size_t frameCount = lua_type ( L , index ) = = LUA_TNUMBER ? lua_tointeger ( L , index + + ) : lovrSoundDataGetFrameCount ( source ) ;
2020-12-16 15:07:29 +00:00
size_t offset = dest ? luaL_optinteger ( L , index , 0 ) : 0 ;
bool shouldRelease = false ;
if ( dest = = NULL ) {
dest = lovrSoundDataCreateRaw ( frameCount , source - > channels , source - > sampleRate , source - > format , NULL ) ;
shouldRelease = true ;
} else {
lovrAssert ( dest - > channels = = source - > channels , " Source (%d) and destination (%d) channel counts must match " , source - > channels , dest - > channels ) ;
lovrAssert ( dest - > sampleRate = = source - > sampleRate , " Source (%d) and destination (%d) sample rates must match " , source - > sampleRate , dest - > sampleRate ) ;
2021-02-05 21:06:25 +00:00
lovrAssert ( dest - > format = = source - > format , " Source (%s) and destination (%s) formats must match " , lovrSampleFormat [ source - > format ] . string , lovrSampleFormat [ dest - > format ] . string ) ;
2020-12-16 15:07:29 +00:00
lovrAssert ( offset + frameCount < = dest - > frames , " Tried to write samples past the end of a SoundData buffer " ) ;
lovrAssert ( dest - > blob , " Can't read into a stream destination " ) ;
}
size_t outFrames = source - > read ( source , offset , frameCount , dest - > blob - > data ) ;
dest - > frames = outFrames ;
2021-02-05 21:06:25 +00:00
dest - > blob - > size = outFrames * lovrSoundDataGetStride ( dest ) ;
2020-12-16 15:07:29 +00:00
luax_pushtype ( L , SoundData , dest ) ;
if ( shouldRelease ) lovrRelease ( SoundData , dest ) ;
return 1 ;
}
2020-12-10 12:29:42 +00:00
static int l_lovrSoundDataAppend ( lua_State * L ) {
SoundData * soundData = luax_checktype ( L , 1 , SoundData ) ;
Blob * blob = luax_totype ( L , 2 , Blob ) ;
SoundData * sound = luax_totype ( L , 2 , SoundData ) ;
2020-12-15 09:16:58 +00:00
size_t appendedSamples = 0 ;
2020-12-10 12:29:42 +00:00
if ( sound ) {
appendedSamples = lovrSoundDataStreamAppendSound ( soundData , sound ) ;
} else if ( blob ) {
appendedSamples = lovrSoundDataStreamAppendBlob ( soundData , blob ) ;
2020-12-15 09:32:00 +00:00
} else {
luaL_argerror ( L , 2 , " Invalid blob appended " ) ;
2020-12-10 12:29:42 +00:00
}
lua_pushinteger ( L , appendedSamples ) ;
return 1 ;
}
2021-02-05 21:06:25 +00:00
static int l_lovrSoundDataGetSample ( lua_State * L ) {
return 0 ;
}
2020-12-10 13:23:35 +00:00
static int l_lovrSoundDataSetSample ( lua_State * L ) {
SoundData * soundData = luax_checktype ( L , 1 , SoundData ) ;
int index = luaL_checkinteger ( L , 2 ) ;
float value = luax_checkfloat ( L , 3 ) ;
lovrSoundDataSetSample ( soundData , index , value ) ;
return 0 ;
}
2018-07-06 03:23:46 +00:00
const luaL_Reg lovrSoundData [ ] = {
2021-02-05 21:06:25 +00:00
{ " getFormat " , l_lovrSoundDataGetFormat } ,
{ " getSampleRate " , l_lovrSoundDataGetSampleRate } ,
{ " getChannelCount " , l_lovrSoundDataGetChannelCount } ,
2021-02-04 18:25:06 +00:00
{ " getFrameCount " , l_lovrSoundDataGetFrameCount } ,
2021-02-05 21:06:25 +00:00
{ " isCompressed " , l_lovrSoundDataIsCompressed } ,
{ " isStream " , l_lovrSoundDataIsStream } ,
{ " getBlob " , l_lovrSoundDataGetBlob } ,
2020-12-16 15:07:29 +00:00
{ " read " , l_lovrSoundDataRead } ,
2020-12-10 12:29:42 +00:00
{ " append " , l_lovrSoundDataAppend } ,
2021-02-05 21:06:25 +00:00
{ " getSample " , l_lovrSoundDataGetSample } ,
2020-12-10 13:23:35 +00:00
{ " setSample " , l_lovrSoundDataSetSample } ,
2020-12-03 16:07:55 +00:00
{ NULL , NULL }
2018-07-06 03:23:46 +00:00
} ;