Skip to content
This repository was archived by the owner on May 26, 2025. It is now read-only.

Commit 6348f5b

Browse files
committed
Sound: Fix loading PCM data.
1 parent 9eb8ad2 commit 6348f5b

File tree

5 files changed

+99
-37
lines changed

5 files changed

+99
-37
lines changed

Release/Tests/pcm.ngt

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,32 @@
11
void main(){
22
sound s;
3-
file f;
4-
f.open("C:/windows/media/tada.wav", "r");
5-
string pcm = f.read(f.get_size());
6-
f.close();
7-
s.load_from_memory(pcm, pcm.length());
8-
s.play_wait();
3+
tts_voice v;
4+
size_t size;
5+
string pcm = v.speak_to_memory("Test", size);
6+
show_window("Test");
7+
thread_func@ func = function(dictionary@ args){
8+
tts_voice@ v = cast<tts_voice@>(args[0]);
9+
while (!quit_requested){
10+
wait(1000);
11+
v.speak("Bla");
12+
}
13+
};
14+
dictionary args;
15+
@args[0] = v;
16+
thread t(func, args);
17+
t.detach();
18+
while (!quit_requested){
19+
s.load_pcm(pcm, size/2, 1, 16000, 16);
20+
bool result = random_bool();
21+
if (result){
22+
s.pitch = random(90, 100);
23+
s.set_fx("reverb");
24+
s.set_reverb_parameters(1.0f, 0.5f, 1.0f, 0, 0);
25+
}
26+
s.hrtf = true;
27+
s.set_position(0, 0, 0, random(-10, 10), random(-10, 10), 00);
28+
s.play();
29+
wait(result ? 500 : 250);
930
s.close();
31+
}
1032
}

SRC/main.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ class NGTScripting {
586586
scriptEngine->SetTranslateAppExceptionCallback(asFUNCTION(TranslateException), 0, asCALL_CDECL);
587587
scriptEngine->SetEngineProperty(asEP_ALLOW_UNSAFE_REFERENCES, true);
588588
scriptEngine->SetEngineProperty(asEP_INIT_GLOBAL_VARS_AFTER_BUILD, false);
589-
589+
scriptEngine->SetEngineProperty(asEP_ALLOW_IMPLICIT_HANDLE_TYPES, true);
590590
}
591591
~NGTScripting() {
592592
if (m_dbg)
@@ -810,7 +810,18 @@ class NGTScripting {
810810
}
811811
int Exec(asIScriptFunction* func) {
812812
if (func == nullptr)return -1;
813+
asIScriptModule* mod = func->GetModule();
814+
if (!mod)return -1;
815+
813816
int r = 0;
817+
r = mod->ResetGlobalVars(0);
818+
if (r < 0)
819+
{
820+
scriptEngine->WriteMessage(mod->GetName(), 0, 0, asMSGTYPE_ERROR, "Failed while initializing global variables");
821+
return -1;
822+
}
823+
824+
814825
scriptContext = scriptEngine->RequestContext();
815826
scriptContext->Prepare(func);
816827
// Execute the script until completion
@@ -1061,10 +1072,6 @@ class NGTEntry : public Application {
10611072
m_retcode = 1;
10621073
return;
10631074
}
1064-
if (module->ResetGlobalVars(0) < 0) {
1065-
show_message(true, true, true);
1066-
}
1067-
10681075
app->InitializeDebugger();
10691076
int result = app->Exec(func);
10701077
m_retcode = result;
@@ -1086,10 +1093,6 @@ class NGTEntry : public Application {
10861093
m_retcode = 1;
10871094
return;
10881095
}
1089-
if (module->ResetGlobalVars(0) < 0) {
1090-
show_message(true, true, true);
1091-
}
1092-
10931096
int result = app->Exec(func);
10941097

10951098
m_retcode = result;
@@ -1103,10 +1106,6 @@ class NGTEntry : public Application {
11031106
m_retcode = -1;
11041107
return;
11051108
}
1106-
if (module->ResetGlobalVars(0) < 0) {
1107-
show_message(true, true, true);
1108-
}
1109-
11101109
// Call compiler to create executable file
11111110
std::string main_exe = get_exe();
11121111
std::vector<std::string> name_split = string_split(".", value);

SRC/miniaudio.h

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8428,7 +8428,7 @@ The returned pointers will become invalid upon the next call this this function,
84288428

84298429
See Also
84308430
--------
8431-
ma_context_get_devices()
8431+
ma_context_enumerate_devices()
84328432
*/
84338433
MA_API ma_result ma_context_get_devices(ma_context* pContext, ma_device_info** ppPlaybackDeviceInfos, ma_uint32* pPlaybackDeviceCount, ma_device_info** ppCaptureDeviceInfos, ma_uint32* pCaptureDeviceCount);
84348434

@@ -57368,6 +57368,10 @@ MA_API ma_result ma_data_source_init(const ma_data_source_config* pConfig, ma_da
5736857368
return MA_INVALID_ARGS;
5736957369
}
5737057370

57371+
if (pConfig->vtable == NULL) {
57372+
return MA_INVALID_ARGS;
57373+
}
57374+
5737157375
pDataSourceBase->vtable = pConfig->vtable;
5737257376
pDataSourceBase->rangeBegInFrames = MA_DATA_SOURCE_DEFAULT_RANGE_BEG;
5737357377
pDataSourceBase->rangeEndInFrames = MA_DATA_SOURCE_DEFAULT_RANGE_END;
@@ -57433,6 +57437,8 @@ static ma_result ma_data_source_read_pcm_frames_within_range(ma_data_source* pDa
5743357437
return MA_INVALID_ARGS;
5743457438
}
5743557439

57440+
MA_ASSERT(pDataSourceBase->vtable != NULL);
57441+
5743657442
if ((pDataSourceBase->vtable->flags & MA_DATA_SOURCE_SELF_MANAGED_RANGE_AND_LOOP_POINT) != 0 || (pDataSourceBase->rangeEndInFrames == ~((ma_uint64)0) && (pDataSourceBase->loopEndInFrames == ~((ma_uint64)0) || loop == MA_FALSE))) {
5743757443
/* Either the data source is self-managing the range, or no range is set - just read like normal. The data source itself will tell us when the end is reached. */
5743857444
result = pDataSourceBase->vtable->onRead(pDataSourceBase, pFramesOut, frameCount, &framesRead);
@@ -57656,6 +57662,8 @@ MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, m
5765657662
return MA_INVALID_OPERATION; /* Trying to seek to far forward. */
5765757663
}
5765857664

57665+
MA_ASSERT(pDataSourceBase->vtable != NULL);
57666+
5765957667
return pDataSourceBase->vtable->onSeek(pDataSource, pDataSourceBase->rangeBegInFrames + frameIndex);
5766057668
}
5766157669

@@ -57685,6 +57693,8 @@ MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_
5768557693
return MA_INVALID_ARGS;
5768657694
}
5768757695

57696+
MA_ASSERT(pDataSourceBase->vtable != NULL);
57697+
5768857698
if (pDataSourceBase->vtable->onGetDataFormat == NULL) {
5768957699
return MA_NOT_IMPLEMENTED;
5769057700
}
@@ -57725,6 +57735,8 @@ MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSo
5772557735
return MA_SUCCESS;
5772657736
}
5772757737

57738+
MA_ASSERT(pDataSourceBase->vtable != NULL);
57739+
5772857740
if (pDataSourceBase->vtable->onGetCursor == NULL) {
5772957741
return MA_NOT_IMPLEMENTED;
5773057742
}
@@ -57758,6 +57770,8 @@ MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSo
5775857770
return MA_INVALID_ARGS;
5775957771
}
5776057772

57773+
MA_ASSERT(pDataSourceBase->vtable != NULL);
57774+
5776157775
/*
5776257776
If we have a range defined we'll use that to determine the length. This is one of rare times
5776357777
where we'll actually trust the caller. If they've set the range, I think it's mostly safe to
@@ -57845,6 +57859,8 @@ MA_API ma_result ma_data_source_set_looping(ma_data_source* pDataSource, ma_bool
5784557859

5784657860
ma_atomic_exchange_32(&pDataSourceBase->isLooping, isLooping);
5784757861

57862+
MA_ASSERT(pDataSourceBase->vtable != NULL);
57863+
5784857864
/* If there's no callback for this just treat it as a successful no-op. */
5784957865
if (pDataSourceBase->vtable->onSetLooping == NULL) {
5785057866
return MA_SUCCESS;
@@ -60396,7 +60412,7 @@ extern "C" {
6039660412
#define MA_DR_FLAC_XSTRINGIFY(x) MA_DR_FLAC_STRINGIFY(x)
6039760413
#define MA_DR_FLAC_VERSION_MAJOR 0
6039860414
#define MA_DR_FLAC_VERSION_MINOR 12
60399-
#define MA_DR_FLAC_VERSION_REVISION 42
60415+
#define MA_DR_FLAC_VERSION_REVISION 43
6040060416
#define MA_DR_FLAC_VERSION_STRING MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MAJOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MINOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_REVISION)
6040160417
#include <stddef.h>
6040260418
#if defined(_MSC_VER) && _MSC_VER >= 1700
@@ -60683,7 +60699,7 @@ extern "C" {
6068360699
#define MA_DR_MP3_XSTRINGIFY(x) MA_DR_MP3_STRINGIFY(x)
6068460700
#define MA_DR_MP3_VERSION_MAJOR 0
6068560701
#define MA_DR_MP3_VERSION_MINOR 6
60686-
#define MA_DR_MP3_VERSION_REVISION 39
60702+
#define MA_DR_MP3_VERSION_REVISION 40
6068760703
#define MA_DR_MP3_VERSION_STRING MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MAJOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MINOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_REVISION)
6068860704
#include <stddef.h>
6068960705
#define MA_DR_MP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152
@@ -85544,6 +85560,7 @@ static ma_bool32 ma_dr_flac__read_subframe_header(ma_dr_flac_bs* bs, ma_dr_flac_
8554485560
if ((header & 0x80) != 0) {
8554585561
return MA_FALSE;
8554685562
}
85563+
pSubframe->lpcOrder = 0;
8554785564
type = (header & 0x7E) >> 1;
8554885565
if (type == 0) {
8554985566
pSubframe->subframeType = MA_DR_FLAC_SUBFRAME_CONSTANT;
@@ -85601,6 +85618,9 @@ static ma_bool32 ma_dr_flac__decode_subframe(ma_dr_flac_bs* bs, ma_dr_flac_frame
8560185618
}
8560285619
subframeBitsPerSample -= pSubframe->wastedBitsPerSample;
8560385620
pSubframe->pSamplesS32 = pDecodedSamplesOut;
85621+
if (frame->header.blockSizeInPCMFrames < pSubframe->lpcOrder) {
85622+
return MA_FALSE;
85623+
}
8560485624
switch (pSubframe->subframeType)
8560585625
{
8560685626
case MA_DR_FLAC_SUBFRAME_CONSTANT:
@@ -90318,7 +90338,7 @@ MA_API const char* ma_dr_mp3_version_string(void)
9031890338
#define MA_DR_MP3_MIN(a, b) ((a) > (b) ? (b) : (a))
9031990339
#define MA_DR_MP3_MAX(a, b) ((a) < (b) ? (b) : (a))
9032090340
#if !defined(MA_DR_MP3_NO_SIMD)
90321-
#if !defined(MA_DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64))
90341+
#if !defined(MA_DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC))
9032290342
#define MA_DR_MP3_ONLY_SIMD
9032390343
#endif
9032490344
#if ((defined(_MSC_VER) && _MSC_VER >= 1400) && defined(_M_X64)) || ((defined(__i386) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__)) && ((defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE2__)))
@@ -90391,7 +90411,7 @@ static int ma_dr_mp3_have_simd(void)
9039190411
return g_have_simd - 1;
9039290412
#endif
9039390413
}
90394-
#elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64)
90414+
#elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
9039590415
#include <arm_neon.h>
9039690416
#define MA_DR_MP3_HAVE_SSE 0
9039790417
#define MA_DR_MP3_HAVE_SIMD 1
@@ -90420,7 +90440,7 @@ static int ma_dr_mp3_have_simd(void)
9042090440
#else
9042190441
#define MA_DR_MP3_HAVE_SIMD 0
9042290442
#endif
90423-
#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(__ARM_ARCH_6M__)
90443+
#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(_M_ARM64EC) && !defined(__ARM_ARCH_6M__)
9042490444
#define MA_DR_MP3_HAVE_ARMV6 1
9042590445
static __inline__ __attribute__((always_inline)) ma_int32 ma_dr_mp3_clip_int16_arm(ma_int32 a)
9042690446
{

SRC/ngt.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -591,16 +591,18 @@ void exit_engine(int return_number)
591591
e_ctx->Execute();
592592
int result = e_ctx->GetReturnDWord();
593593
if (result == 1) {
594-
e_ctx->Release();
594+
engine->ReturnContext(e_ctx);
595595
return;
596596
}
597-
e_ctx->Release();
597+
engine->ReturnContext(e_ctx);
598598
exit_callback = nullptr;
599599
}
600600
g_shutdown = true;
601601
g_retcode = return_number;
602-
if (ctx)
602+
if (ctx) {
603603
ctx->Abort();
604+
ctx->GetEngine()->ReturnContext(ctx);
605+
}
604606
}
605607

606608
CScriptArray* keys_pressed() {
@@ -2061,19 +2063,20 @@ script_thread::script_thread(asIScriptFunction* func, CScriptDictionary* args) {
20612063
void script_thread::detach() {
20622064
thread t([this]() {
20632065
this->context->Execute();
2064-
this->context->Unprepare();
2066+
this->context->GetEngine()->ReturnContext(this->context);
20652067
});
20662068
t.detach();
20672069
}
20682070
void script_thread::join() {
20692071
thread t([this]() {
20702072
this->context->Execute();
2071-
this->context->Unprepare();
2073+
this->context->GetEngine()->ReturnContext(this->context);
20722074
});
20732075
t.join();
20742076
}
20752077
void script_thread::destroy() {
20762078
this->context->Abort();
2079+
this->context->GetEngine()->ReturnContext(this->context);
20772080
}
20782081

20792082
user_idle::user_idle() {}

SRC/sound.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,7 +1353,7 @@ class MINIAUDIO_IMPLEMENTATION sound
13531353
ma_sound_set_rolloff(handle_, 2);
13541354
return true;
13551355
}
1356-
bool load_from_memory(string data, size_t stream_size)
1356+
bool load_from_memory(const string& data, size_t stream_size)
13571357
{
13581358
if (active)
13591359
this->close();
@@ -1379,7 +1379,7 @@ class MINIAUDIO_IMPLEMENTATION sound
13791379

13801380
return active;
13811381
}
1382-
bool load_pcm(string data, size_t size, int channels, int sample_rate)
1382+
bool load_pcm(const string& data, size_t size, int channels, int sample_rate, int bits_per_sample)
13831383
{
13841384
if (active)
13851385
this->close();
@@ -1389,9 +1389,27 @@ class MINIAUDIO_IMPLEMENTATION sound
13891389
ma_audio_buffer_uninit(&m_buffer);
13901390
buffer_initialized = false;
13911391
}
1392-
ma_audio_buffer_config bufferConfig = ma_audio_buffer_config_init(FORMAT, channels, size / 2, (const void*)data.c_str(), nullptr);
1392+
ma_audio_buffer_config bufferConfig = ma_audio_buffer_config_init(FORMAT, channels, size, (const void*)data.c_str(), nullptr);
13931393
bufferConfig.sampleRate = sample_rate;
13941394
bufferConfig.channels = channels;
1395+
ma_format format = ma_format_unknown;
1396+
switch (bits_per_sample) {
1397+
case 8:
1398+
format = ma_format_u8;
1399+
break;
1400+
case 16:
1401+
format = ma_format_s16;
1402+
break;
1403+
case 24:
1404+
format = ma_format_s24;
1405+
break;
1406+
case 32:
1407+
format = ma_format_f32;
1408+
break;
1409+
default:
1410+
break;
1411+
}
1412+
bufferConfig.format = format;
13951413
ma_result result = ma_audio_buffer_init(&bufferConfig, &m_buffer);
13961414
if (result != MA_SUCCESS)
13971415
return false;
@@ -2278,8 +2296,8 @@ void register_sound(asIScriptEngine* engine)
22782296
engine->RegisterObjectBehaviour("sound", asBEHAVE_ADDREF, "void f()", asMETHOD(sound, AddRef), asCALL_THISCALL);
22792297
engine->RegisterObjectBehaviour("sound", asBEHAVE_RELEASE, "void f()", asMETHOD(sound, Release), asCALL_THISCALL);
22802298
engine->RegisterObjectMethod(_O("sound"), "bool load(const string &in filename)const", asMETHOD(sound, load), asCALL_THISCALL);
2281-
engine->RegisterObjectMethod(_O("sound"), "bool load_from_memory(string memory, size_t memory_size = 0)const", asMETHOD(sound, load_from_memory), asCALL_THISCALL);
2282-
engine->RegisterObjectMethod(_O("sound"), "bool load_pcm(string memory, size_t memory_size = 0, int channels = 0, int sample_rate = 0)const", asMETHOD(sound, load_pcm), asCALL_THISCALL);
2299+
engine->RegisterObjectMethod(_O("sound"), "bool load_from_memory(const string&in memory, size_t memory_size = 0)const", asMETHOD(sound, load_from_memory), asCALL_THISCALL);
2300+
engine->RegisterObjectMethod(_O("sound"), "bool load_pcm(const string&in memory, size_t memory_size = 0, int channels = 0, int sample_rate = 0, int bits_per_sample = 0)const", asMETHOD(sound, load_pcm), asCALL_THISCALL);
22832301

22842302
engine->RegisterObjectMethod(_O("sound"), "bool stream(const string &in filename)const", asMETHOD(sound, stream), asCALL_THISCALL);
22852303
engine->RegisterObjectMethod(_O("sound"), "bool load_url(const string &in url)const", asMETHOD(sound, load_url), asCALL_THISCALL);
@@ -2332,5 +2350,5 @@ void register_sound(asIScriptEngine* engine)
23322350
engine->RegisterGlobalFunction("bool get_sound_global_hrtf()property", asFUNCTION(get_sound_global_hrtf), asCALL_CDECL);
23332351
engine->RegisterGlobalFunction("void set_spatial_blend_max_distance(float)property", asFUNCTION(set_spatial_blend_max_distance), asCALL_CDECL);
23342352
engine->RegisterGlobalFunction("float get_spatial_blend_max_distance()property", asFUNCTION(get_spatial_blend_max_distance), asCALL_CDECL);
2335-
std::this_thread::yield();
2336-
}
2353+
2354+
}

0 commit comments

Comments
 (0)