127static int stream_thread(
void *la_data )
140 SDL_CondBroadcast( la->
cond );
141 alSourceStop( la->
source );
146 alGetSourcei( la->
source, AL_BUFFERS_PROCESSED, &alstate );
150 alSourceUnqueueBuffers( la->
source, 1, &removed );
152 if ((la->
active < 0) || (ret < 0)) {
157 SDL_CondBroadcast( la->
cond );
158 alSourceStop( la->
source );
183 char buf[ 32 * 1024 ];
188 while (size <
sizeof(buf)) {
191 SDL_mutexP( la->
lock );
192 result = ov_read_filter(
196 (SDL_BYTEORDER == SDL_BIG_ENDIAN),
202 SDL_mutexV( la->
lock );
213 else if (result == OV_HOLE) {
214 WARN(_(
"OGG: Vorbis hole detected in music!"));
218 else if (result == OV_EBADLINK) {
219 WARN(_(
"OGG: Invalid stream section or corrupt link in music!"));
228 alBufferData( buffer, la->
format, buf, size, la->
info->rate );
242static void rg_filter(
float **pcm,
long channels,
long samples,
void *filter_param )
246 float max_scale = param->rg_max_scale;
249 if (scale_factor > max_scale) {
250 for (
int i=0; i < channels; i++)
251 for (
int j=0; j < samples; j++) {
252 float cur_sample = pcm[i][j] * scale_factor;
258 if (cur_sample < -0.5)
259 cur_sample = tanh((cur_sample + 0.5) / (1-0.5)) * (1-0.5) - 0.5;
260 else if (cur_sample > 0.5)
261 cur_sample = tanh((cur_sample - 0.5) / (1-0.5)) * (1-0.5) + 0.5;
262 pcm[i][j] = cur_sample;
265 else if (scale_factor > 0.0)
266 for (
int i=0; i < channels; i++)
267 for (
int j=0; j < samples; j++)
268 pcm[i][j] *= scale_factor;
280 alGetSourcei( la->
source, param, &b );
284 lua_pushboolean(L,b);
297 alGetSourcei( la->
source, AL_SOURCE_STATE, &s );
301 lua_pushboolean(L, s==state );
339 luaL_typerror(L, ind, AUDIO_METATABLE);
353 luaL_getmetatable(L, AUDIO_METATABLE);
354 lua_setmetatable(L, -2);
368 if (lua_getmetatable(L,ind)==0)
370 lua_getfield(L, LUA_REGISTRYINDEX, AUDIO_METATABLE);
373 if (lua_rawequal(L, -1, -2))
388 case LUA_AUDIO_STATIC:
390 if (alIsSource( la->
source )==AL_TRUE)
391 alDeleteSources( 1, &la->
source );
393 if (la->
buf != NULL) {
404 case LUA_AUDIO_STREAM:
406 if (la->
th != NULL) {
408 if (SDL_CondWaitTimeout( la->
cond,
sound_lock, 3000 ) == SDL_MUTEX_TIMEDOUT)
410 WARN(_(
"Timed out while waiting for audio thread of '%s' to finish!"), la->name);
412 WARN(_(
"Timed out while waiting for audio thread to finish!"));
415 if (alIsSource( la->
source )==AL_TRUE)
416 alDeleteSources( 1, &la->
source );
419 if (la->
cond != NULL)
420 SDL_DestroyCond( la->
cond );
421 if (la->
lock != NULL)
422 SDL_DestroyMutex( la->
lock );
465 lua_pushboolean( L, (memcmp( a1, a2,
sizeof(
LuaAudio_t) )==0) );
475 alGenSources( 1, source );
476 if (alIsSource(*source)==AL_TRUE)
482 case AL_OUT_OF_MEMORY:
485 lua_gc( naevL, LUA_GCCOLLECT, 0 );
488 alGenSources( 1, source );
489 if (alIsSource(*source)==AL_TRUE)
496 al_checkHandleError( err, __func__, __LINE__ );
521 if (lua_isstring(L,1))
522 name = lua_tostring(L,1);
528 NLUA_INVALID_PARAMETER(L,1);
531 if (lua_isnoneornil(L,2)) {
535 const char *type = luaL_optstring(L,2,
"static");
536 if (strcmp(type,
"static")==0)
538 else if (strcmp(type,
"stream")==0)
541 NLUA_INVALID_PARAMETER(L,2);
550 rw = PHYSFSRWOPS_openRead( name );
552 return NLUA_ERROR(L,
"Unable to open '%s'", name );
554 la.name = strdup( name );
568 la.
type = LUA_AUDIO_STATIC;
581 ALfloat track_gain_db, track_peak;
584 la.
type = LUA_AUDIO_STREAM;
588 return NLUA_ERROR(L,_(
"Audio '%s' does not appear to be a Vorbis bitstream."), name );
593 vc = ov_comment( &la.
stream, -1 );
596 if ((tag = vorbis_comment_query(vc,
"replaygain_track_gain", 0)))
597 track_gain_db = atof(tag);
598 if ((tag = vorbis_comment_query(vc,
"replaygain_track_peak", 0)))
599 track_peak = atof(tag);
604 if (la.
info->channels == 1)
605 la.
format = AL_FORMAT_MONO16;
607 la.
format = AL_FORMAT_STEREO16;
610 la.
lock = SDL_CreateMutex();
611 la.
cond = SDL_CreateCond();
619 alSourcef( la.
source, AL_GAIN, master );
628 alSourcei( la.
source, AL_SOURCE_RELATIVE, AL_TRUE );
629 alSource3f( la.
source, AL_POSITION, 0., 0., 0. );
654 switch (source->type) {
655 case LUA_AUDIO_STATIC:
657 la->
buf = source->buf;
664 case LUA_AUDIO_STREAM:
665 WARN(_(
"Unimplemented"));
671 la->
type = source->type;
677 alSourcef( la->
source, AL_GAIN, master * source->volume );
678 la->
volume = source->volume;
680 alSourcei( la->
source, AL_SOURCE_RELATIVE, AL_TRUE );
681 alSource3f( la->
source, AL_POSITION, 0., 0., 0. );
697 audio_clone( &la, source );
715 if ((la->
type == LUA_AUDIO_STREAM) && (la->
th == NULL)) {
719 alGetSourcei( la->
source, AL_BUFFERS_QUEUED, &alstate );
720 while (alstate < 2) {
726 alGetSourcei( la->
source, AL_BUFFERS_QUEUED, &alstate );
729 la->
th = SDL_CreateThread( stream_thread,
"stream_thread", la );
733 alSourcePlay( la->
source );
737 lua_pushboolean(L,1);
754 alSourcePause( la->
source );
790 case LUA_AUDIO_STATIC:
791 alSourceStop( la->
source );
794 case LUA_AUDIO_STREAM:
796 if (la->
th != NULL) {
798 if (SDL_CondWaitTimeout( la->
cond,
sound_lock, 3000 ) == SDL_MUTEX_TIMEDOUT)
800 WARN(_(
"Timed out while waiting for audio thread of '%s' to finish!"), la->name);
802 WARN(_(
"Timed out while waiting for audio thread to finish!"));
808 alSourceStop( la->
source );
811 alGetSourcei( la->
source, AL_BUFFERS_PROCESSED, &alstate );
812 alSourceUnqueueBuffers( la->
source, alstate, removed );
815 SDL_mutexP( la->
lock );
816 ov_pcm_seek( &la->
stream, 0 );
817 SDL_mutexV( la->
lock );
850 case LUA_AUDIO_STATIC:
852 alSourceRewind( la->
source );
856 case LUA_AUDIO_STREAM:
857 SDL_mutexP( la->
lock );
858 ov_raw_seek( &la->
stream, 0 );
859 SDL_mutexV( la->
lock );
878 double offset = luaL_checknumber(L,2);
879 const char *unit = luaL_optstring(L,3,
"seconds");
882 if (strcmp(unit,
"samples")==0)
884 else if (strcmp(unit,
"seconds")!=0)
885 return NLUA_ERROR(L, _(
"Unknown seek source '%s'! Should be either 'seconds' or 'samples'!"), unit );
891 case LUA_AUDIO_STATIC:
894 alSourcef( la->
source, AL_SEC_OFFSET, offset );
896 alSourcef( la->
source, AL_SAMPLE_OFFSET, offset );
901 case LUA_AUDIO_STREAM:
902 SDL_mutexP( la->
lock );
904 ov_time_seek( &la->
stream, offset );
906 ov_pcm_seek( &la->
stream, offset );
907 SDL_mutexV( la->
lock );
928 const char *unit = luaL_optstring(L,2,
"seconds");
933 if (strcmp(unit,
"samples")==0)
935 else if (strcmp(unit,
"seconds")!=0)
936 return NLUA_ERROR(L, _(
"Unknown seek source '%s'! Should be either 'seconds' or 'samples'!"), unit );
939 lua_pushnumber(L, -1.);
944 case LUA_AUDIO_STATIC:
947 alGetSourcef( la->
source, AL_SEC_OFFSET, &aloffset );
949 alGetSourcef( la->
source, AL_SAMPLE_OFFSET, &aloffset );
955 case LUA_AUDIO_STREAM:
956 SDL_mutexP( la->
lock );
958 offset = ov_time_tell( &la->
stream );
960 offset = ov_pcm_tell( &la->
stream );
961 SDL_mutexV( la->
lock );
968 lua_pushnumber(L, offset);
983 const char *unit = luaL_optstring(L,2,
"seconds");
984 float duration = -1.;
986 ALint bytes, channels, bits, samples;
989 if (strcmp(unit,
"samples")==0)
991 else if (strcmp(unit,
"seconds")!=0)
992 return NLUA_ERROR(L, _(
"Unknown duration source '%s'! Should be either 'seconds' or 'samples'!"), unit );
995 lua_pushnumber(L, -1.);
1000 case LUA_AUDIO_STATIC:
1003 alGetBufferi( buffer, AL_SIZE, &bytes );
1004 alGetBufferi( buffer, AL_CHANNELS, &channels );
1005 alGetBufferi( buffer, AL_BITS, &bits );
1007 samples = bytes * 8 / (channels * bits);
1011 alGetBufferi( buffer, AL_FREQUENCY, &freq );
1012 duration = (float) samples / (
float) freq;
1020 case LUA_AUDIO_STREAM:
1021 SDL_mutexP( la->
lock );
1023 duration = ov_time_total( &la->
stream, -1 );
1025 duration = ov_pcm_total( &la->
stream, -1 );
1026 SDL_mutexV( la->
lock );
1029 case LUA_AUDIO_NULL:
1033 lua_pushnumber(L, duration);
1048 double volume =
CLAMP( 0.0, 1.0, luaL_checknumber(L,2) );
1049 int ignorevol = lua_toboolean(L,3);
1055 alSourcef( la->
source, AL_GAIN, volume );
1058 alSourcef( la->
source, AL_GAIN, master * volume );
1078 else if (lua_gettop(L) > 0)
1082 lua_pushnumber(L, volume);
1099 alSourcei( la->
source, AL_SOURCE_RELATIVE, lua_toboolean(L,2) );
1121 pos[0] = luaL_optnumber(L,2,0.);
1122 pos[1] = luaL_optnumber(L,3,0.);
1123 pos[2] = luaL_optnumber(L,4,0.);
1126 alSourcefv( la->
source, AL_POSITION, pos );
1146 lua_pushnumber(L,0.);
1147 lua_pushnumber(L,0.);
1148 lua_pushnumber(L,0.);
1153 alGetSource3f( la->
source, AL_POSITION, &pos[0], &pos[1], &pos[2] );
1157 lua_pushnumber(L,pos[0]);
1158 lua_pushnumber(L,pos[1]);
1159 lua_pushnumber(L,pos[2]);
1179 vel[0] = luaL_optnumber(L,2,0.);
1180 vel[1] = luaL_optnumber(L,3,0.);
1181 vel[2] = luaL_optnumber(L,4,0.);
1184 alSourcefv( la->
source, AL_VELOCITY, vel );
1204 lua_pushnumber(L,0.);
1205 lua_pushnumber(L,0.);
1206 lua_pushnumber(L,0.);
1211 alGetSource3f( la->
source, AL_VELOCITY, &vel[0], &vel[1], &vel[2] );
1215 lua_pushnumber(L,vel[0]);
1216 lua_pushnumber(L,vel[1]);
1217 lua_pushnumber(L,vel[2]);
1231 int b = lua_toboolean(L,2);
1235 alSourcei( la->
source, AL_LOOPING, b );
1263 double pitch = luaL_checknumber(L,2);
1267 alSourcef( la->
source, AL_PITCH, pitch );
1286 alGetSourcef( la->
source, AL_PITCH, &p );
1290 lua_pushnumber(L,p);
1311 vec2 *pos, *vel, vel0;
1318 name = luaL_checkstring(L,1);
1319 if (lua_gettop(L) > 1) {
1322 if (lua_gettop(L) > 2) {
1349 double ref = luaL_checknumber(L,2);
1350 double max = luaL_checknumber(L,3);
1354 alSourcef( la->
source, AL_REFERENCE_DISTANCE, ref );
1355 alSourcef( la->
source, AL_MAX_DISTANCE, max );
1373 lua_pushnumber(L,0.);
1374 lua_pushnumber(L,0.);
1378 alGetSourcef( la->
source, AL_REFERENCE_DISTANCE, &ref );
1379 alGetSourcef( la->
source, AL_MAX_DISTANCE, &max );
1382 lua_pushnumber( L, ref );
1383 lua_pushnumber( L, max );
1396 double rolloff = luaL_checknumber(L,2);
1400 alSourcef( la->
source, AL_ROLLOFF_FACTOR, rolloff );
1417 lua_pushnumber(L,0.);
1421 alGetSourcef( la->
source, AL_ROLLOFF_FACTOR, &rolloff);
1424 lua_pushnumber( L, rolloff );
1428static void efx_setnum( lua_State *L,
int pos, ALuint effect,
const char *name, ALuint param ) {
1429 lua_getfield(L,pos,name);
1430 if (!lua_isnil(L,-1))
1431 nalEffectf( effect, param, luaL_checknumber(L,-1) );
1434static void efx_setint( lua_State *L,
int pos, ALuint effect,
const char *name, ALuint param ) {
1435 lua_getfield(L,pos,name);
1436 if (!lua_isnil(L,-1))
1437 nalEffecti( effect, param, luaL_checkinteger(L,-1) );
1440static void efx_setbool( lua_State *L,
int pos, ALuint effect,
const char *name, ALuint param ) {
1441 lua_getfield(L,pos,name);
1442 if (!lua_isnil(L,-1))
1443 nalEffecti( effect, param, lua_toboolean(L,-1) ? AL_TRUE : AL_FALSE );
1446static int audioL_setEffectGlobal( lua_State *L )
1448 const char *name = luaL_checkstring(L,1);
1449 ALuint effect, slot;
1456 lua_getfield(L,p,
"type");
1457 type = luaL_checkstring(L,-1);
1461 lua_getfield(L,p,
"volume");
1462 if (lua_isnil(L,-1))
1465 volume = luaL_checknumber(L,-1);
1475 if (strcmp(name,
lua_efx[i].name)==0) {
1482 nalGenEffects(1, &effect);
1483 nalGenAuxiliaryEffectSlots( 1, &slot );
1484 lae->
name = strdup( name );
1494 if (strcmp(type,
"reverb")==0) {
1495 nalEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
1497 efx_setnum( L, p, effect,
"density", AL_REVERB_DENSITY );
1498 efx_setnum( L, p, effect,
"diffusion", AL_REVERB_DIFFUSION );
1499 efx_setnum( L, p, effect,
"gain", AL_REVERB_GAIN );
1500 efx_setnum( L, p, effect,
"highgain", AL_REVERB_GAINHF );
1501 efx_setnum( L, p, effect,
"decaytime", AL_REVERB_DECAY_TIME );
1502 efx_setnum( L, p, effect,
"decayhighratio", AL_REVERB_DECAY_HFRATIO );
1503 efx_setnum( L, p, effect,
"earlygain", AL_REVERB_REFLECTIONS_GAIN );
1504 efx_setnum( L, p, effect,
"earlydelay", AL_REVERB_REFLECTIONS_DELAY );
1505 efx_setnum( L, p, effect,
"lategain", AL_REVERB_LATE_REVERB_GAIN );
1506 efx_setnum( L, p, effect,
"latedelay", AL_REVERB_LATE_REVERB_DELAY );
1507 efx_setnum( L, p, effect,
"roomrolloff", AL_REVERB_ROOM_ROLLOFF_FACTOR );
1508 efx_setnum( L, p, effect,
"airabsorption", AL_REVERB_AIR_ABSORPTION_GAINHF );
1509 efx_setbool( L, p, effect,
"highlimit", AL_REVERB_DECAY_HFLIMIT );
1511 else if (strcmp(type,
"distortion")==0) {
1512 nalEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_DISTORTION);
1514 efx_setnum( L, p, effect,
"gain", AL_DISTORTION_GAIN );
1515 efx_setnum( L, p, effect,
"edge", AL_DISTORTION_EDGE );
1516 efx_setnum( L, p, effect,
"lowcut", AL_DISTORTION_LOWPASS_CUTOFF );
1517 efx_setnum( L, p, effect,
"center", AL_DISTORTION_EQCENTER );
1518 efx_setnum( L, p, effect,
"bandwidth", AL_DISTORTION_EQBANDWIDTH );
1520 else if (strcmp(type,
"chorus")==0) {
1521 nalEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_CHORUS);
1523 efx_setint( L, p, effect,
"waveform", AL_CHORUS_WAVEFORM );
1524 efx_setint( L, p, effect,
"phase", AL_CHORUS_PHASE );
1525 efx_setnum( L, p, effect,
"rate", AL_CHORUS_RATE );
1526 efx_setnum( L, p, effect,
"depth", AL_CHORUS_DEPTH );
1527 efx_setnum( L, p, effect,
"feedback", AL_CHORUS_FEEDBACK );
1528 efx_setnum( L, p, effect,
"delay", AL_CHORUS_DELAY );
1530 else if (strcmp(type,
"compressor")==0) {
1531 nalEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_COMPRESSOR);
1533 efx_setbool( L, p, effect,
"enable", AL_COMPRESSOR_ONOFF );
1535 else if (strcmp(type,
"echo")==0) {
1536 nalEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_ECHO);
1538 efx_setnum( L, p, effect,
"delay", AL_ECHO_DELAY );
1539 efx_setnum( L, p, effect,
"tapdelay", AL_ECHO_LRDELAY );
1540 efx_setnum( L, p, effect,
"damping", AL_ECHO_DAMPING );
1541 efx_setnum( L, p, effect,
"feedback", AL_ECHO_FEEDBACK );
1542 efx_setnum( L, p, effect,
"spread", AL_ECHO_SPREAD );
1544 else if (strcmp(type,
"ringmodulator")==0) {
1545 nalEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_RING_MODULATOR);
1547 efx_setnum( L, p, effect,
"frequency", AL_RING_MODULATOR_FREQUENCY );
1548 efx_setnum( L, p, effect,
"highcut", AL_RING_MODULATOR_HIGHPASS_CUTOFF );
1549 efx_setint( L, p, effect,
"waveform", AL_RING_MODULATOR_WAVEFORM );
1551 else if (strcmp(type,
"equalizer")==0) {
1552 nalEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EQUALIZER);
1554 efx_setnum( L, p, effect,
"lowgain", AL_EQUALIZER_LOW_GAIN );
1555 efx_setnum( L, p, effect,
"lowcut", AL_EQUALIZER_LOW_CUTOFF );
1556 efx_setnum( L, p, effect,
"lowmidgain", AL_EQUALIZER_MID1_GAIN );
1557 efx_setnum( L, p, effect,
"lowmidfrequency", AL_EQUALIZER_MID1_CENTER );
1558 efx_setnum( L, p, effect,
"lowmidbandwidth", AL_EQUALIZER_MID1_WIDTH );
1559 efx_setnum( L, p, effect,
"highmidgain", AL_EQUALIZER_MID2_GAIN );
1560 efx_setnum( L, p, effect,
"highmidfrequency", AL_EQUALIZER_MID2_CENTER );
1561 efx_setnum( L, p, effect,
"highmidbandwidth", AL_EQUALIZER_MID2_WIDTH );
1562 efx_setnum( L, p, effect,
"highgain", AL_EQUALIZER_HIGH_GAIN );
1563 efx_setnum( L, p, effect,
"highcut", AL_EQUALIZER_HIGH_CUTOFF );
1565 else if (strcmp(type,
"pitchshifter")==0) {
1566 nalEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_PITCH_SHIFTER);
1568 efx_setint( L, p, effect,
"tunecoarse", AL_PITCH_SHIFTER_COARSE_TUNE );
1569 efx_setint( L, p, effect,
"tunefine'", AL_PITCH_SHIFTER_FINE_TUNE );
1571 else if (strcmp(type,
"vocalmorpher")==0) {
1572 nalEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_VOCAL_MORPHER);
1574 efx_setint( L, p, effect,
"phonemea", AL_VOCAL_MORPHER_PHONEMEA );
1575 efx_setint( L, p, effect,
"phonemeb", AL_VOCAL_MORPHER_PHONEMEB );
1576 efx_setint( L, p, effect,
"tunecoarsea", AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING );
1577 efx_setint( L, p, effect,
"tunecoarseb", AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING );
1578 efx_setint( L, p, effect,
"waveform", AL_VOCAL_MORPHER_WAVEFORM );
1579 efx_setnum( L, p, effect,
"rate", AL_VOCAL_MORPHER_RATE );
1581 else if (strcmp(type,
"flanger")==0) {
1582 nalEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_FLANGER);
1584 efx_setint( L, p, effect,
"waveform", AL_FLANGER_WAVEFORM );
1585 efx_setnum( L, p, effect,
"phase", AL_FLANGER_PHASE );
1586 efx_setnum( L, p, effect,
"rate", AL_FLANGER_RATE );
1587 efx_setnum( L, p, effect,
"depth", AL_FLANGER_DEPTH );
1588 efx_setnum( L, p, effect,
"feedback", AL_FLANGER_FEEDBACK );
1589 efx_setnum( L, p, effect,
"delay", AL_FLANGER_DELAY );
1591 else if (strcmp(type,
"frequencyshifter")==0) {
1592 nalEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_FREQUENCY_SHIFTER);
1594 efx_setnum( L, p, effect,
"frequency", AL_FREQUENCY_SHIFTER_FREQUENCY );
1595 efx_setint( L, p, effect,
"leftdirection", AL_FREQUENCY_SHIFTER_LEFT_DIRECTION );
1596 efx_setint( L, p, effect,
"rightdirection", AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION );
1600 return NLUA_ERROR(L, _(
"Usupported audio effect type '%s'!"), type);
1604 nalAuxiliaryEffectSlotf( slot, AL_EFFECTSLOT_GAIN, volume );
1605 nalAuxiliaryEffectSloti( slot, AL_EFFECTSLOT_EFFECT, effect );
1613static LuaAudioEfx_t *audio_getEffectByName(
const char *name )
1616 if (strcmp(name,
lua_efx[i].name)==0)
1618 WARN(_(
"Unknown audio effect '%s'!"), name);
1636 lua_pushboolean(L,1);
1642 return audioL_setEffectGlobal(L);
1645 const char *name = luaL_checkstring(L,2);
1646 int enable = (lua_isnoneornil(L,3)) ? 1 : lua_toboolean(L,3);
1656 alSource3i( la->
source, AL_AUXILIARY_SEND_FILTER, lae->
slot, 0, AL_FILTER_NULL );
1659 alSource3i( la->
source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL );
1664 lua_pushboolean(L,1);
1677 const char *name = luaL_optstring(L,1,NULL);
1695 lae = audio_getEffectByName( name );
1716 double speed = luaL_optnumber( L, 1, 3433. );
1717 double absorption = luaL_optnumber( L, 2, -1. );
1723 alSpeedOfSound( speed );
1724 if (absorption > 0.)
1725 sound_setAbsorption( absorption );
1745 alDopplerFactor( luaL_checknumber(L,1) );