2017-12-10 20:40:37 +00:00
|
|
|
#include "api.h"
|
2017-01-03 03:09:33 +00:00
|
|
|
#include "audio/audio.h"
|
2019-05-18 00:11:22 +00:00
|
|
|
#include "data/blob.h"
|
2018-01-21 20:54:16 +00:00
|
|
|
#include "data/audioStream.h"
|
2019-04-05 11:16:34 +00:00
|
|
|
#include "data/soundData.h"
|
2019-05-20 09:47:33 +00:00
|
|
|
#include "core/maf.h"
|
2019-06-02 07:20:10 +00:00
|
|
|
#include "core/ref.h"
|
2019-05-13 10:53:17 +00:00
|
|
|
#include <stdlib.h>
|
2017-01-03 03:09:33 +00:00
|
|
|
|
2020-09-28 00:13:00 +00:00
|
|
|
StringEntry lovrSourceType[] = {
|
2020-02-17 02:31:02 +00:00
|
|
|
[SOURCE_STATIC] = ENTRY("static"),
|
|
|
|
[SOURCE_STREAM] = ENTRY("stream"),
|
|
|
|
{ 0 }
|
2018-07-06 05:08:14 +00:00
|
|
|
};
|
|
|
|
|
2020-09-28 00:13:00 +00:00
|
|
|
StringEntry lovrTimeUnit[] = {
|
2020-02-17 02:31:02 +00:00
|
|
|
[UNIT_SECONDS] = ENTRY("seconds"),
|
|
|
|
[UNIT_SAMPLES] = ENTRY("samples"),
|
|
|
|
{ 0 }
|
2018-07-05 03:11:52 +00:00
|
|
|
};
|
2017-01-03 03:09:33 +00:00
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioUpdate(lua_State* L) {
|
2017-01-06 01:00:53 +00:00
|
|
|
lovrAudioUpdate();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioGetDopplerEffect(lua_State* L) {
|
2018-02-26 05:54:39 +00:00
|
|
|
float factor, speedOfSound;
|
|
|
|
lovrAudioGetDopplerEffect(&factor, &speedOfSound);
|
|
|
|
lua_pushnumber(L, factor);
|
|
|
|
lua_pushnumber(L, speedOfSound);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioGetMicrophoneNames(lua_State* L) {
|
2018-07-07 00:55:19 +00:00
|
|
|
const char* names[MAX_MICROPHONES];
|
2019-05-13 10:53:17 +00:00
|
|
|
uint32_t count;
|
2018-07-07 00:55:19 +00:00
|
|
|
lovrAudioGetMicrophoneNames(names, &count);
|
|
|
|
|
|
|
|
if (lua_istable(L, 1)) {
|
|
|
|
lua_settop(L, 1);
|
|
|
|
} else {
|
|
|
|
lua_settop(L, 0);
|
|
|
|
lua_createtable(L, count, 0);
|
|
|
|
}
|
|
|
|
|
2019-05-13 10:53:17 +00:00
|
|
|
for (uint32_t i = 0; i < count; i++) {
|
2018-07-07 00:55:19 +00:00
|
|
|
lua_pushstring(L, names[i]);
|
|
|
|
lua_rawseti(L, -2, i + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioGetOrientation(lua_State* L) {
|
2019-01-30 00:01:40 +00:00
|
|
|
float orientation[4], angle, ax, ay, az;
|
2018-11-27 23:03:05 +00:00
|
|
|
lovrAudioGetOrientation(orientation);
|
2019-01-30 00:01:40 +00:00
|
|
|
quat_getAngleAxis(orientation, &angle, &ax, &ay, &az);
|
|
|
|
lua_pushnumber(L, angle);
|
|
|
|
lua_pushnumber(L, ax);
|
|
|
|
lua_pushnumber(L, ay);
|
|
|
|
lua_pushnumber(L, az);
|
|
|
|
return 4;
|
2017-01-06 05:36:38 +00:00
|
|
|
}
|
|
|
|
|
2019-02-18 02:26:56 +00:00
|
|
|
static int l_lovrAudioGetPose(lua_State* L) {
|
2019-06-03 14:13:52 +00:00
|
|
|
float position[4], orientation[4], angle, ax, ay, az;
|
2019-02-18 02:26:56 +00:00
|
|
|
lovrAudioGetPosition(position);
|
|
|
|
lovrAudioGetOrientation(orientation);
|
|
|
|
quat_getAngleAxis(orientation, &angle, &ax, &ay, &az);
|
|
|
|
lua_pushnumber(L, position[0]);
|
|
|
|
lua_pushnumber(L, position[1]);
|
|
|
|
lua_pushnumber(L, position[2]);
|
|
|
|
lua_pushnumber(L, angle);
|
|
|
|
lua_pushnumber(L, ax);
|
|
|
|
lua_pushnumber(L, ay);
|
|
|
|
lua_pushnumber(L, az);
|
|
|
|
return 7;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioGetPosition(lua_State* L) {
|
2019-06-03 14:13:52 +00:00
|
|
|
float position[4];
|
2018-11-27 23:03:05 +00:00
|
|
|
lovrAudioGetPosition(position);
|
2019-01-30 00:01:40 +00:00
|
|
|
lua_pushnumber(L, position[0]);
|
|
|
|
lua_pushnumber(L, position[1]);
|
|
|
|
lua_pushnumber(L, position[2]);
|
|
|
|
return 3;
|
2017-01-06 05:36:38 +00:00
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioGetVelocity(lua_State* L) {
|
2019-06-03 14:13:52 +00:00
|
|
|
float velocity[4];
|
2018-11-27 23:03:05 +00:00
|
|
|
lovrAudioGetVelocity(velocity);
|
2019-01-30 00:01:40 +00:00
|
|
|
lua_pushnumber(L, velocity[0]);
|
|
|
|
lua_pushnumber(L, velocity[1]);
|
|
|
|
lua_pushnumber(L, velocity[2]);
|
|
|
|
return 3;
|
2017-02-26 20:57:56 +00:00
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioGetVolume(lua_State* L) {
|
2017-01-06 08:41:08 +00:00
|
|
|
lua_pushnumber(L, lovrAudioGetVolume());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioIsSpatialized(lua_State* L) {
|
2017-10-31 08:14:09 +00:00
|
|
|
lua_pushboolean(L, lovrAudioIsSpatialized());
|
2017-02-26 21:14:15 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioNewMicrophone(lua_State* L) {
|
2018-07-07 00:55:19 +00:00
|
|
|
const char* name = luaL_optstring(L, 1, NULL);
|
|
|
|
int samples = luaL_optinteger(L, 2, 1024);
|
|
|
|
int sampleRate = luaL_optinteger(L, 3, 8000);
|
|
|
|
int bitDepth = luaL_optinteger(L, 4, 16);
|
|
|
|
int channelCount = luaL_optinteger(L, 5, 1);
|
|
|
|
Microphone* microphone = lovrMicrophoneCreate(name, samples, sampleRate, bitDepth, channelCount);
|
2019-06-02 07:20:10 +00:00
|
|
|
luax_pushtype(L, Microphone, microphone);
|
2019-04-05 10:41:03 +00:00
|
|
|
lovrRelease(Microphone, microphone);
|
2018-07-07 00:55:19 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioNewSource(lua_State* L) {
|
2018-07-06 05:08:14 +00:00
|
|
|
Source* source = NULL;
|
2018-07-25 04:15:07 +00:00
|
|
|
SoundData* soundData = luax_totype(L, 1, SoundData);
|
|
|
|
AudioStream* stream = luax_totype(L, 1, AudioStream);
|
2020-09-28 00:13:00 +00:00
|
|
|
bool isStatic = soundData || luax_checkenum(L, 2, SourceType, NULL) == SOURCE_STATIC;
|
2018-07-06 05:08:14 +00:00
|
|
|
|
|
|
|
if (isStatic) {
|
2018-07-25 04:15:07 +00:00
|
|
|
if (soundData) {
|
|
|
|
source = lovrSourceCreateStatic(soundData);
|
2018-07-06 06:30:37 +00:00
|
|
|
} else {
|
2018-07-25 04:15:07 +00:00
|
|
|
if (stream) {
|
|
|
|
soundData = lovrSoundDataCreateFromAudioStream(stream);
|
2018-07-06 05:08:14 +00:00
|
|
|
} else {
|
|
|
|
Blob* blob = luax_readblob(L, 1, "Source");
|
|
|
|
soundData = lovrSoundDataCreateFromBlob(blob);
|
2019-04-05 10:41:03 +00:00
|
|
|
lovrRelease(Blob, blob);
|
2018-07-06 05:08:14 +00:00
|
|
|
}
|
|
|
|
|
2018-07-06 06:30:37 +00:00
|
|
|
lovrAssert(soundData, "Could not create static Source");
|
|
|
|
source = lovrSourceCreateStatic(soundData);
|
2019-04-05 10:41:03 +00:00
|
|
|
lovrRelease(SoundData, soundData);
|
2018-07-06 06:30:37 +00:00
|
|
|
}
|
2018-01-22 16:14:24 +00:00
|
|
|
} else {
|
2018-07-25 04:15:07 +00:00
|
|
|
if (stream) {
|
|
|
|
source = lovrSourceCreateStream(stream);
|
2018-07-06 06:30:37 +00:00
|
|
|
} else {
|
2018-07-06 05:08:14 +00:00
|
|
|
Blob* blob = luax_readblob(L, 1, "Source");
|
2018-07-25 04:15:07 +00:00
|
|
|
stream = lovrAudioStreamCreate(blob, 4096);
|
2018-07-06 06:30:37 +00:00
|
|
|
lovrAssert(stream, "Could not create stream Source");
|
|
|
|
source = lovrSourceCreateStream(stream);
|
2019-04-05 10:41:03 +00:00
|
|
|
lovrRelease(Blob, blob);
|
|
|
|
lovrRelease(AudioStream, stream);
|
2018-01-31 18:17:01 +00:00
|
|
|
}
|
2018-01-22 16:14:24 +00:00
|
|
|
}
|
|
|
|
|
2019-06-02 07:20:10 +00:00
|
|
|
luax_pushtype(L, Source, source);
|
2019-04-05 10:41:03 +00:00
|
|
|
lovrRelease(Source, source);
|
2017-01-06 01:00:53 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2017-01-06 05:36:38 +00:00
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioPause(lua_State* L) {
|
2017-01-06 08:37:16 +00:00
|
|
|
lovrAudioPause();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioSetDopplerEffect(lua_State* L) {
|
2019-01-29 10:28:55 +00:00
|
|
|
float factor = luax_optfloat(L, 1, 1.f);
|
|
|
|
float speedOfSound = luax_optfloat(L, 2, 343.29f);
|
2018-02-26 05:54:39 +00:00
|
|
|
lovrAudioSetDopplerEffect(factor, speedOfSound);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioSetOrientation(lua_State* L) {
|
2018-11-27 23:03:05 +00:00
|
|
|
float orientation[4];
|
|
|
|
luax_readquat(L, 1, orientation, NULL);
|
|
|
|
lovrAudioSetOrientation(orientation);
|
2017-01-06 05:36:38 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-02-18 02:26:56 +00:00
|
|
|
static int l_lovrAudioSetPose(lua_State* L) {
|
2019-06-03 14:13:52 +00:00
|
|
|
float position[4], orientation[4];
|
2019-02-18 02:26:56 +00:00
|
|
|
int index = 1;
|
|
|
|
index = luax_readvec3(L, index, position, NULL);
|
|
|
|
index = luax_readquat(L, index, orientation, NULL);
|
|
|
|
lovrAudioSetPosition(position);
|
|
|
|
lovrAudioSetOrientation(orientation);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioSetPosition(lua_State* L) {
|
2019-06-03 14:13:52 +00:00
|
|
|
float position[4];
|
2018-11-27 23:03:05 +00:00
|
|
|
luax_readvec3(L, 1, position, NULL);
|
|
|
|
lovrAudioSetPosition(position);
|
2017-01-06 05:36:38 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-01-06 08:37:16 +00:00
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioSetVelocity(lua_State* L) {
|
2019-06-03 14:13:52 +00:00
|
|
|
float velocity[4];
|
2018-11-27 23:03:05 +00:00
|
|
|
luax_readvec3(L, 1, velocity, NULL);
|
|
|
|
lovrAudioSetVelocity(velocity);
|
2017-02-26 20:57:56 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioSetVolume(lua_State* L) {
|
2019-01-29 10:28:55 +00:00
|
|
|
float volume = luax_checkfloat(L, 1);
|
2017-01-06 08:41:08 +00:00
|
|
|
lovrAudioSetVolume(volume);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrAudioStop(lua_State* L) {
|
2017-01-06 08:37:16 +00:00
|
|
|
lovrAudioStop();
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 11:08:07 +00:00
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static const luaL_Reg lovrAudio[] = {
|
2017-03-11 11:08:07 +00:00
|
|
|
{ "update", l_lovrAudioUpdate },
|
2018-02-26 05:54:39 +00:00
|
|
|
{ "getDopplerEffect", l_lovrAudioGetDopplerEffect },
|
2018-07-07 00:55:19 +00:00
|
|
|
{ "getMicrophoneNames", l_lovrAudioGetMicrophoneNames },
|
2017-03-11 11:08:07 +00:00
|
|
|
{ "getOrientation", l_lovrAudioGetOrientation },
|
2019-02-18 02:26:56 +00:00
|
|
|
{ "getPose", l_lovrAudioGetPose },
|
2017-03-11 11:08:07 +00:00
|
|
|
{ "getPosition", l_lovrAudioGetPosition },
|
|
|
|
{ "getVelocity", l_lovrAudioGetVelocity },
|
|
|
|
{ "getVolume", l_lovrAudioGetVolume },
|
|
|
|
{ "isSpatialized", l_lovrAudioIsSpatialized },
|
2018-07-07 00:55:19 +00:00
|
|
|
{ "newMicrophone", l_lovrAudioNewMicrophone },
|
2017-03-11 11:08:07 +00:00
|
|
|
{ "newSource", l_lovrAudioNewSource },
|
|
|
|
{ "pause", l_lovrAudioPause },
|
2018-02-26 05:54:39 +00:00
|
|
|
{ "setDopplerEffect", l_lovrAudioSetDopplerEffect },
|
2017-03-11 11:08:07 +00:00
|
|
|
{ "setOrientation", l_lovrAudioSetOrientation },
|
2019-02-18 02:26:56 +00:00
|
|
|
{ "setPose", l_lovrAudioSetPose },
|
2017-03-11 11:08:07 +00:00
|
|
|
{ "setPosition", l_lovrAudioSetPosition },
|
|
|
|
{ "setVelocity", l_lovrAudioSetVelocity },
|
|
|
|
{ "setVolume", l_lovrAudioSetVolume },
|
|
|
|
{ "stop", l_lovrAudioStop },
|
|
|
|
{ NULL, NULL }
|
|
|
|
};
|
2018-09-27 01:27:38 +00:00
|
|
|
|
2019-08-26 22:53:10 +00:00
|
|
|
int luaopen_lovr_audio(lua_State* L) {
|
2018-09-27 01:27:38 +00:00
|
|
|
lua_newtable(L);
|
2020-08-19 19:12:06 +00:00
|
|
|
luax_register(L, lovrAudio);
|
2019-04-05 10:48:36 +00:00
|
|
|
luax_registertype(L, Microphone);
|
|
|
|
luax_registertype(L, Source);
|
2018-11-19 16:08:56 +00:00
|
|
|
if (lovrAudioInit()) {
|
|
|
|
luax_atexit(L, lovrAudioDestroy);
|
|
|
|
}
|
2018-09-27 01:27:38 +00:00
|
|
|
return 1;
|
|
|
|
}
|