www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Need simple sound

reply Martin Tschierschke <mt smartdolphin.de> writes:
Hello for a simple game I would like to add some very simple 
sound, not much different than the beeps of "PAC Man". Is there 
anything I can use for this?
Jul 03
next sibling parent reply Guillaume Piolat <first.last gmail.com> writes:
On Monday, 3 July 2017 at 08:55:20 UTC, Martin Tschierschke wrote:
 Hello for a simple game I would like to add some very simple 
 sound, not much different than the beeps of "PAC Man". Is there 
 anything I can use for this?
DerelictSDL supports the loading of SDL_mixer, which makes it very practical.
Jul 03
parent reply Martin Tschierschke <mt smartdolphin.de> writes:
On Monday, 3 July 2017 at 09:24:35 UTC, Guillaume Piolat wrote:
 On Monday, 3 July 2017 at 08:55:20 UTC, Martin Tschierschke 
 wrote:
 Hello for a simple game I would like to add some very simple 
 sound, not much different than the beeps of "PAC Man". Is 
 there anything I can use for this?
DerelictSDL supports the loading of SDL_mixer, which makes it very practical.
Thank you for the hint, a short google search was not so successful, can you give me an additional hint / link? I think I would have to produce a time series of a sinus for example and to play it?
Jul 03
parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Monday, 3 July 2017 at 10:40:03 UTC, Martin Tschierschke wrote:
 On Monday, 3 July 2017 at 09:24:35 UTC, Guillaume Piolat wrote:
 On Monday, 3 July 2017 at 08:55:20 UTC, Martin Tschierschke 
 wrote:
 Hello for a simple game I would like to add some very simple 
 sound, not much different than the beeps of "PAC Man". Is 
 there anything I can use for this?
DerelictSDL supports the loading of SDL_mixer, which makes it very practical.
Thank you for the hint, a short google search was not so successful, can you give me an additional hint / link? I think I would have to produce a time series of a sinus for example and to play it?
Here's a program that plays some square waves: https://dump.thecybershadow.net/9db4fcd7b004e5dfccf537e49cbb72a6/test.d
Jul 04
parent Martin Tschierschke <mt smartdolphin.de> writes:
On Tuesday, 4 July 2017 at 11:59:33 UTC, Vladimir Panteleev wrote:
 On Monday, 3 July 2017 at 10:40:03 UTC, Martin Tschierschke 
 wrote:
 On Monday, 3 July 2017 at 09:24:35 UTC, Guillaume Piolat wrote:
 On Monday, 3 July 2017 at 08:55:20 UTC, Martin Tschierschke 
 wrote:
 Hello for a simple game I would like to add some very simple 
 sound, not much different than the beeps of "PAC Man". Is 
 there anything I can use for this?
DerelictSDL supports the loading of SDL_mixer, which makes it very practical.
Thank you for the hint, a short google search was not so successful, can you give me an additional hint / link? I think I would have to produce a time series of a sinus for example and to play it?
Here's a program that plays some square waves: https://dump.thecybershadow.net/9db4fcd7b004e5dfccf537e49cbb72a6/test.d
Cool, will try!
Jul 04
prev sibling parent reply Dukc <ajieskola gmail.com> writes:
On Monday, 3 July 2017 at 08:55:20 UTC, Martin Tschierschke wrote:
 Hello for a simple game I would like to add some very simple 
 sound, not much different than the beeps of "PAC Man". Is there 
 anything I can use for this?
When simplicity is the matter number 1, Arsd-official most likely what you're looking for. It has a library file for audio. Simpleaudio.d or Simplesound.d, not sure which it was.
Jul 04
next sibling parent reply Sebastiaan Koppe <mail skoppe.eu> writes:
 On Monday, 3 July 2017 at 08:55:20 UTC, Martin Tschierschke 
 wrote:
 Hello for a simple game I would like to add some very simple 
 sound, not much different than the beeps of "PAC Man". Is there 
 anything I can use for this?
Portaudio is simple as well. And nice cross platform.
Jul 04
parent reply FoxyBrown <Foxy Brown.IPT> writes:
On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe wrote:
 On Monday, 3 July 2017 at 08:55:20 UTC, Martin Tschierschke 
 wrote:
 Hello for a simple game I would like to add some very simple 
 sound, not much different than the beeps of "PAC Man". Is 
 there anything I can use for this?
Portaudio is simple as well. And nice cross platform.
are there any bindings?
Jul 04
parent reply Sebastiaan Koppe <mail skoppe.eu> writes:
On Wednesday, 5 July 2017 at 05:34:37 UTC, FoxyBrown wrote:
 On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe wrote:
 Portaudio is simple as well. And nice cross platform.
are there any bindings?
Sure, see http://code.dlang.org/packages/portaudio
Jul 05
next sibling parent reply Martin Tschierschke <mt smartdolphin.de> writes:
On Wednesday, 5 July 2017 at 07:21:45 UTC, Sebastiaan Koppe wrote:
 On Wednesday, 5 July 2017 at 05:34:37 UTC, FoxyBrown wrote:
 On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe 
 wrote:
 Portaudio is simple as well. And nice cross platform.
are there any bindings?
Sure, see http://code.dlang.org/packages/portaudio
Sorry, for that question but now, as I have several different options - all not 'overdocumented' - so what would be the shortest possible D program waiting for input and playing a sound from a file in parallel? Something short like the single-file dub example...? #!/usr/bin/env dub /+ dub.sdl: name "hello" +/ void main() { writef("Do you like the music?"); char[] answer; answer = readln(); writef("This was your Answer: ", answer); }
Jul 05
parent reply Sebastiaan Koppe <mail skoppe.eu> writes:
On Wednesday, 5 July 2017 at 09:43:05 UTC, Martin Tschierschke 
wrote:
 On Wednesday, 5 July 2017 at 07:21:45 UTC, Sebastiaan Koppe 
 wrote:
 On Wednesday, 5 July 2017 at 05:34:37 UTC, FoxyBrown wrote:
 On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe 
 wrote:
 Portaudio is simple as well. And nice cross platform.
are there any bindings?
Sure, see http://code.dlang.org/packages/portaudio
Sorry, for that question but now, as I have several different options - all not 'overdocumented' - so what would be the shortest possible D program waiting for input and playing a sound from a file in parallel? Something short like the single-file dub example...? #!/usr/bin/env dub /+ dub.sdl: name "hello" +/ void main() { writef("Do you like the music?"); char[] answer; answer = readln(); writef("This was your Answer: ", answer); }
This one plays a wav file. Couldn't get dub to do single-file on it. It kept giving linker errors. (Took example from https://github.com/v--/portaudio/blob/master/examples/pa_test.d) **dub.sdl name "audio" description "plays audio file" authors "Sebastiaan Koppe" dependency "portaudio" version="==1.0.0" dependency "wave-d" version="~>1.0.6" configuration "executable" { mainSourceFile "audio.d" targetType "executable" } **audio.d import std.stdio; import waved; import deimos.portaudio; import std.conv, std.stdio; import std.algorithm : min; struct Audio { float* samples; size_t frames; size_t position; } extern(C) int callback(const(void)* inputBuffer, void* outputBuffer, size_t framesPerBuffer, const(PaStreamCallbackTimeInfo)* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { auto pout = cast(float*)outputBuffer; Audio* audio = cast(Audio*)userData; enum vol = 0.2f; size_t frames = min(audio.frames - audio.position, framesPerBuffer); foreach(i; 0 .. frames) *pout++ = vol * audio.samples[i + audio.position]; foreach(i; frames .. framesPerBuffer) *pout++ = 0; audio.position += framesPerBuffer; return frames == framesPerBuffer ? paContinue : paComplete; } int main() { PaStream* stream; PaError err; Sound input = decodeWAV("my_wav_file.wav"); string answer; auto audio = Audio(input.samples.ptr, input.samples.length); if ((err = Pa_Initialize()) != paNoError) goto Lerror; if ((err = Pa_OpenDefaultStream(&stream, 0, input.channels, paFloat32, cast(double)input.sampleRate, paFramesPerBufferUnspecified, &callback, &audio)) != paNoError) goto Lerror; if ((err = Pa_StartStream(stream)) != paNoError) goto Lerror; writef("Do you like the music?"); answer = readln(); writefln("This was your Answer: %s", answer); if ((err = Pa_StopStream(stream)) != paNoError) goto Lerror; if ((err = Pa_CloseStream(stream)) != paNoError) goto Lerror; if ((err = Pa_Terminate()) != paNoError) goto Lerror; return 0; Lerror: stderr.writefln("error %s", to!string(Pa_GetErrorText(err))); return 1; }
Jul 05
parent Martin Tschierschke <mt smartdolphin.de> writes:
On Wednesday, 5 July 2017 at 10:19:54 UTC, Sebastiaan Koppe wrote:
 On Wednesday, 5 July 2017 at 09:43:05 UTC, Martin Tschierschke 
 wrote:
 On Wednesday, 5 July 2017 at 07:21:45 UTC, Sebastiaan Koppe 
 wrote:
 On Wednesday, 5 July 2017 at 05:34:37 UTC, FoxyBrown wrote:
 On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe 
 wrote:
 Portaudio is simple as well. And nice cross platform.
are there any bindings?
Sure, see http://code.dlang.org/packages/portaudio
Sorry, for that question but now, as I have several different options - all not 'overdocumented' - so what would be the shortest possible D program waiting for input and playing a sound from a file in parallel? Something short like the single-file dub example...? #!/usr/bin/env dub /+ dub.sdl: name "hello" +/ void main() { writef("Do you like the music?"); char[] answer; answer = readln(); writef("This was your Answer: ", answer); }
This one plays a wav file. Couldn't get dub to do single-file on it. It kept giving linker errors. (Took example from https://github.com/v--/portaudio/blob/master/examples/pa_test.d)
[...]
  Lerror:
     stderr.writefln("error %s", 
 to!string(Pa_GetErrorText(err)));
     return 1;
 }
Thank you! Without the error handling it would be quite simple :-) So, the following process starts the music in main, it is just to clarify the process for me: In main: //1 PaStream* stream; Sound input = decodeWAV("FILE.wav"); auto audio = Audio(input....); Pa_Initialize(); Pa_OpenDefaultStream(&stream,...input...&callback,&audio); //2 Pa_StartStream(stream); //3 Pa_StopStream(stream); Pa_CloseStream(stream); For my purpose I will try to encapsulate it all in 3 additional own methods on top of it: //1 auto myinput = InitWav("File.wav"); //2 PlaySound(myinput,volume=default, length=max_length); //3 StopSound(myinput); With a new Struct myinput to handle input,audio and stream. Thank you all for your help!
Jul 05
prev sibling next sibling parent reply FoxyBrown <Foxy Brown.IPT> writes:
On Wednesday, 5 July 2017 at 07:21:45 UTC, Sebastiaan Koppe wrote:
 On Wednesday, 5 July 2017 at 05:34:37 UTC, FoxyBrown wrote:
 On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe 
 wrote:
 Portaudio is simple as well. And nice cross platform.
are there any bindings?
Sure, see http://code.dlang.org/packages/portaudio
I can't seem to get this to work. Are there any windows dll's or libs that work that are not outdated?
Jul 06
parent Sebastiaan Koppe <mail skoppe.eu> writes:
On Thursday, 6 July 2017 at 10:47:53 UTC, FoxyBrown wrote:
 On Wednesday, 5 July 2017 at 07:21:45 UTC, Sebastiaan Koppe 
 wrote:
 On Wednesday, 5 July 2017 at 05:34:37 UTC, FoxyBrown wrote:
 On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe 
 wrote:
 Portaudio is simple as well. And nice cross platform.
are there any bindings?
Sure, see http://code.dlang.org/packages/portaudio
I can't seem to get this to work. Are there any windows dll's or libs that work that are not outdated?
I have found dlls here https://github.com/spatialaudio/portaudio-binaries
Jul 06
prev sibling parent reply FoxyBrown <Foxy Brown.IPT> writes:
On Wednesday, 5 July 2017 at 07:21:45 UTC, Sebastiaan Koppe wrote:
 On Wednesday, 5 July 2017 at 05:34:37 UTC, FoxyBrown wrote:
 On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe 
 wrote:
 Portaudio is simple as well. And nice cross platform.
are there any bindings?
Sure, see http://code.dlang.org/packages/portaudio
So, after a bit of work I can get port audio to work but the callback never seems to be called(no audio, never hits bp). Shows all the devices and seems to run fine otherwise. Tried all the devices I I have. The default stream doesn't work either. Here is the following code: import portaudio; import std.conv, std.stdio; import core.stdc.stdio; alias BOOL = ubyte; alias DWORD = uint; struct dllimport { string dllName; } template hasAttribute(alias sym, T) { static bool helper() { foreach(a; __traits(getAttributes, sym)) { if(is(a == T) || __traits(compiles, typeof(a)) && is(typeof(a) == T)) return true; } return false; } enum bool hasAttribute = helper(); } template getAttribute(alias sym, T) { static T helper() { foreach(a; __traits(getAttributes, sym)) { static if(is(a == T) || __traits(compiles, typeof(a)) && is(typeof(a) == T)) return a; } assert(0, "attribute " ~ T.stringof ~ " not found"); } enum T getAttribute = helper(); } void doImport(alias T)() { import core.sys.windows.windows, std.conv; bool isDLLLoaded = false; HINSTANCE dll; foreach(m; __traits(allMembers, T)) { static if(__traits(compiles, typeof(__traits(getMember, T, m)))) { static if(hasAttribute!(__traits(getMember, T, m), dllimport)) { auto dllName = getAttribute!(__traits(getMember, T, m), dllimport).dllName; if (!isDLLLoaded) { writeln("Loading DLL `"~dllName~"'..."); isDLLLoaded = true; dll = LoadLibrary(to!wstring(dllName~"\0").ptr); if (dll == null) { // ERROR, handle writeln("Error, aborting!"); return; } } auto q = GetProcAddress(dll, m); mixin(m~" = cast(typeof("~m~"))q;"); //func(m, getAttribute!(__traits(getMember, T, m), dllimport).dllName, cast(void**)&__traits(getMember, T, m)); } } } } mixin template DllImportFunctions() { struct DllImporter { shared static this() { doImport!(__traits(parent, DllImporter))(); } static loadFunction(string name, const(char)[] dllName, void** addr) { printf("import %.*s from %.*s into %llx\n", name.length, name.ptr, dllName.length, dllName.ptr, addr); } } } extern(C) dllimport("portaudio_x86.dll") __gshared { PaError function() Pa_Initialize; PaError function() Pa_Terminate; PaHostApiIndex function() Pa_GetHostApiCount; PaHostApiIndex function() Pa_GetDefaultHostApi; PaDeviceIndex function() Pa_GetDefaultOutputDevice; PaDeviceIndex function() Pa_GetDefaultInputDevice; PaDeviceIndex function() Pa_GetDeviceCount; const(PaHostErrorInfo)* function() Pa_GetLastHostErrorInfo; PaDeviceIndex function(PaHostApiIndex hostApi, int hostApiDeviceIndex ) Pa_HostApiDeviceIndexToDeviceIndex; PaHostApiIndex function(PaHostApiTypeId type) Pa_HostApiTypeIdToHostApiIndex; const(PaHostApiInfo)* function(PaHostApiIndex hostApi) Pa_GetHostApiInfo; PaError function(PaStream *stream, PaStreamFinishedCallback streamFinishedCallback) Pa_SetStreamFinishedCallback; PaError function(PaStream *stream) Pa_CloseStream; PaError function(PaStream** stream, int numInputChannels, int numOutputChannels, PaSampleFormat sampleFormat, double sampleRate, ulong framesPerBuffer, PaStreamCallback streamCallback, void *userData) Pa_OpenDefaultStream; PaError function(PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, ulong framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback streamCallback, void *userData) Pa_OpenStream; PaError function(const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate) Pa_IsFormatSupported; const(PaDeviceInfo)* function(PaDeviceIndex device) Pa_GetDeviceInfo; PaError function(PaStream *stream) Pa_StartStream; PaError function(PaStream *stream) Pa_StopStream; PaError function(PaStream *stream) Pa_AbortStream; PaError function(PaStream *stream) Pa_IsStreamStopped; void function(long msec) Pa_Sleep; PaError function(PaSampleFormat format) Pa_GetSampleSize; long function(PaStream* stream) Pa_GetStreamWriteAvailable; long function(PaStream* stream) Pa_GetStreamReadAvailable; PaError function(PaStream* stream, const void *buffer, ulong frames) Pa_WriteStream; PaError function(PaStream* stream, void *buffer, ulong frames) Pa_ReadStream; double function(PaStream* stream) Pa_GetStreamCpuLoad; PaTime function(PaStream *stream) Pa_GetStreamTime; const(PaStreamInfo)* function(PaStream *stream) Pa_GetStreamInfo; PaError function(PaStream *stream) Pa_IsStreamActive; const(char)* function(PaError errorCode) Pa_GetErrorText; } mixin DllImportFunctions; struct Phase { float left=0, right=0; } extern(C) int sawtooth(const(void)* inputBuffer, void* outputBuffer, size_t framesPerBuffer, const(PaStreamCallbackTimeInfo)* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { auto phase = cast(Phase*)userData; auto pout = cast(float*)outputBuffer; enum vol = 0.2f; foreach(i; 0 .. framesPerBuffer) { *pout++ = vol * phase.left; *pout++ = vol * phase.right; phase.left += 0.01f; if (phase.left >= 1.0f) phase.left -= 2.0f; phase.right += 0.03f; if (phase.right >= 1.0f) phase.right -= 2.0f; } return 0; } int main() { enum NUM_SECONDS = 5; PaStream* stream; PaError err; Phase phase_data; if ((err = Pa_Initialize()) == paNoError) { writeln("---------------------------------------------------------------------------"); auto numDevices = Pa_GetDeviceCount(); if(numDevices < 0) { printf("ERROR: Pa_CountDevices returned 0x%x\n", numDevices); err = numDevices; goto Lerror; } for(auto i = 0; i < numDevices; i++ ) { auto deviceInfo = Pa_GetDeviceInfo(i); writeln("Device "~to!string(i)~" > "~to!string(deviceInfo.name)~", "~to!string(deviceInfo.maxInputChannels)~", "~to!string(deviceInfo.maxOutputChannels)~", "~to!string(deviceInfo.defaultLowOutputLatency)~","~to!string(deviceInfo.defaultH ghOutputLatency)~", "~to!string(deviceInfo.defaultSampleRate)~", "~to!string(deviceInfo.hostApi)); } double sampleRate = 44100; PaStreamParameters* input; if (input != null) { input.device = 0; auto id = Pa_GetDeviceInfo(input.device); input.hostApiSpecificStreamInfo = null; input.channelCount = id.maxInputChannels; input.sampleFormat = paFloat32; input.suggestedLatency = (id.defaultLowInputLatency + id.defaultHighInputLatency)/2; sampleRate = id.defaultSampleRate; } PaStreamParameters* output = new PaStreamParameters(); if (output != null) { output.device = 15; auto od = Pa_GetDeviceInfo(output.device); output.hostApiSpecificStreamInfo = null; output.channelCount = od.maxOutputChannels; output.sampleFormat = paFloat32; output.suggestedLatency = (od.defaultLowOutputLatency + od.defaultHighOutputLatency)/2; sampleRate = od.defaultSampleRate; } //if ((err = Pa_OpenDefaultStream(&stream, 0, 2, paFloat32, SAMPLE_RATE, paFramesPerBufferUnspecified, &sawtooth, &phase_data)) != paNoError) goto Lerror; if ((err = Pa_OpenStream(&stream, input, output, sampleRate, paFramesPerBufferUnspecified, paNoFlag, &sawtooth, &phase_data)) != paNoError) goto Lerror; if ((err = Pa_StartStream(stream)) != paNoError) goto Lerror; Pa_Sleep(NUM_SECONDS * 1000); if ((err = Pa_StopStream(stream)) != paNoError) goto Lerror; if ((err = Pa_CloseStream(stream)) != paNoError) goto Lerror; if ((err = Pa_Terminate()) != paNoError) goto Lerror; return 0; } else { Lerror: writeln(to!string(Pa_GetErrorText(err))); getchar(); return 1; } return 0; }
Jul 06
parent reply Sebastiaan Koppe <mail skoppe.eu> writes:
On Thursday, 6 July 2017 at 13:28:26 UTC, FoxyBrown wrote:
 On Wednesday, 5 July 2017 at 07:21:45 UTC, Sebastiaan Koppe 
 wrote:
 Sure, see http://code.dlang.org/packages/portaudio
So, after a bit of work I can get port audio to work but the callback never seems to be called(no audio, never hits bp). Shows all the devices and seems to run fine otherwise. Tried all the devices I I have. The default stream doesn't work either.
The example I posted earlier did work on my Mac. I will try your example + dll loader on Windows later today. Nice loader btw.
Jul 06
next sibling parent reply FoxyBrown <Foxy Brown.IPT> writes:
On Thursday, 6 July 2017 at 14:41:32 UTC, Sebastiaan Koppe wrote:
 On Thursday, 6 July 2017 at 13:28:26 UTC, FoxyBrown wrote:
 On Wednesday, 5 July 2017 at 07:21:45 UTC, Sebastiaan Koppe 
 wrote:
 Sure, see http://code.dlang.org/packages/portaudio
So, after a bit of work I can get port audio to work but the callback never seems to be called(no audio, never hits bp). Shows all the devices and seems to run fine otherwise. Tried all the devices I I have. The default stream doesn't work either.
The example I posted earlier did work on my Mac. I will try your example + dll loader on Windows later today. Nice loader btw.
The example was drawn pretty much off the portaudio binding you linked. I just fixed it up so that the device parameters were automatically detected for the device I specified(as I got tired of manually typing them and getting errors). The autodll fixed the problem of trying to get the libs to work, which none did and just didn't seem worth the trouble getting to work. whats the real difference between that and the dll with the autoload code? We can bind the dll to the exe at compile time then use import to import it and load it from memory, so it, in effect, is self contained like a lib. I think the autoDLL if done right. I hacked it together and worked easier than I thought but didn't put in the time to make it nice. It could avoid libs all together, not that we need to do that. Still need a h/di file, of course. But why port audio is not calling the callback is beyond me.
Jul 06
parent Mike Parker <aldacron gmail.com> writes:
On Thursday, 6 July 2017 at 17:33:49 UTC, FoxyBrown wrote:

 I think the autoDLL if done right. I hacked it together and 
 worked easier than I thought but didn't put in the time to make 
 it nice. It could avoid libs all together, not that we need to 
 do that. Still need a h/di file, of course.
That's what the DerelictUtil ([1] && [2]) package does, though it requires manual effort to load DLLs. It also allows you to load specific versions of a DLL with the same binding. It would be interesting to adapt your "autodll" approach in a future version. [1] http://derelictorg.github.io/loading/loader/ [2] https://github.com/DerelictOrg/DerelictUtil
Jul 06
prev sibling next sibling parent FoxyBrown <Foxy Brown.IPT> writes:
On Thursday, 6 July 2017 at 14:41:32 UTC, Sebastiaan Koppe wrote:
 On Thursday, 6 July 2017 at 13:28:26 UTC, FoxyBrown wrote:
 On Wednesday, 5 July 2017 at 07:21:45 UTC, Sebastiaan Koppe 
 wrote:
 Sure, see http://code.dlang.org/packages/portaudio
So, after a bit of work I can get port audio to work but the callback never seems to be called(no audio, never hits bp). Shows all the devices and seems to run fine otherwise. Tried all the devices I I have. The default stream doesn't work either.
The example I posted earlier did work on my Mac. I will try your example + dll loader on Windows later today. Nice loader btw.
I went ahead and simplified the DLL import import portaudio; import std.conv, std.stdio; import core.stdc.stdio; alias BOOL = ubyte; alias DWORD = uint; // New void DllImport(alias T)(string dllName) { import core.sys.windows.windows, std.conv, std.meta; auto dll = LoadLibrary(to!wstring(dllName~"\0").ptr); if (dll == null) assert(0, "Cannot load DLL `"~dllName~"'"); foreach(fname; __traits(derivedMembers, T)) { auto func = GetProcAddress(dll, fname); enum s = "auto p = cast(void**)&"~T.stringof~"."~fname~"; *p = cast(typeof(p))func;"; mixin(s); } } extern(C) class PortAudioDLL { public static PaError function() Pa_Initialize; public static PaError function() Pa_Terminate; public static PaHostApiIndex function() Pa_GetHostApiCount; public static PaHostApiIndex function() Pa_GetDefaultHostApi; public static PaDeviceIndex function() Pa_GetDefaultOutputDevice; public static PaDeviceIndex function() Pa_GetDefaultInputDevice; public static PaDeviceIndex function() Pa_GetDeviceCount; public static const(PaHostErrorInfo)* function() Pa_GetLastHostErrorInfo; public static PaDeviceIndex function(PaHostApiIndex hostApi, int hostApiDeviceIndex ) Pa_HostApiDeviceIndexToDeviceIndex; public static PaHostApiIndex function(PaHostApiTypeId type) Pa_HostApiTypeIdToHostApiIndex; public static const(PaHostApiInfo)* function(PaHostApiIndex hostApi) Pa_GetHostApiInfo; public static PaError function(PaStream *stream, PaStreamFinishedCallback streamFinishedCallback) Pa_SetStreamFinishedCallback; public static PaError function(PaStream *stream) Pa_CloseStream; public static PaError function(PaStream** stream, int numInputChannels, int numOutputChannels, PaSampleFormat sampleFormat, double sampleRate, ulong framesPerBuffer, PaStreamCallback streamCallback, void *userData) Pa_OpenDefaultStream; public static PaError function(PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, ulong framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback streamCallback, void *userData) Pa_OpenStream; public static PaError function(const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate) Pa_IsFormatSupported; public static const(PaDeviceInfo)* function(PaDeviceIndex device) Pa_GetDeviceInfo; public static PaError function(PaStream *stream) Pa_StartStream; public static PaError function(PaStream *stream) Pa_StopStream; public static PaError function(PaStream *stream) Pa_AbortStream; public static PaError function(PaStream *stream) Pa_IsStreamStopped; public static void function(long msec) Pa_Sleep; public static PaError function(PaSampleFormat format) Pa_GetSampleSize; public static long function(PaStream* stream) Pa_GetStreamWriteAvailable; public static long function(PaStream* stream) Pa_GetStreamReadAvailable; public static PaError function(PaStream* stream, const void *buffer, ulong frames) Pa_WriteStream; public static PaError function(PaStream* stream, void *buffer, ulong frames) Pa_ReadStream; public static double function(PaStream* stream) Pa_GetStreamCpuLoad; public static PaTime function(PaStream *stream) Pa_GetStreamTime; public static const(PaStreamInfo)* function(PaStream *stream) Pa_GetStreamInfo; public static PaError function(PaStream *stream) Pa_IsStreamActive; public static const(char)* function(PaError errorCode) Pa_GetErrorText; } struct Phase { float left=0, right=0; } bool test = false; extern(C) int sawtooth(const(void)* inputBuffer, void* outputBuffer, size_t framesPerBuffer, const(PaStreamCallbackTimeInfo)* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { test = true; auto phase = cast(Phase*)userData; auto pout = cast(float*)outputBuffer; enum vol = 0.2f; foreach(i; 0 .. framesPerBuffer) { *pout++ = vol * phase.left; *pout++ = vol * phase.right; phase.left += 0.01f; if (phase.left >= 1.0f) phase.left -= 2.0f; phase.right += 0.03f; if (phase.right >= 1.0f) phase.right -= 2.0f; } return 0; } int main() { DllImport!PortAudioDLL("portaudio_x86.dll"); with(PortAudioDLL) { enum NUM_SECONDS = 5; PaStream* stream; PaError err; Phase phase_data; if ((err = Pa_Initialize()) == paNoError) { writeln("---------------------------------------------------------------------------"); auto numDevices = Pa_GetDeviceCount(); if(numDevices < 0) { printf("ERROR: Pa_CountDevices returned 0x%x\n", numDevices); err = numDevices; goto Lerror; } for(auto i = 0; i < numDevices; i++ ) { auto deviceInfo = Pa_GetDeviceInfo(i); writeln("Device "~to!string(i)~" > "~to!string(deviceInfo.name)~", "~to!string(deviceInfo.maxInputChannels)~", "~to!string(deviceInfo.maxOutputChannels)~", "~to!string(deviceInfo.defaultLowOutputLatency)~","~to!string(deviceInfo.defaultH ghOutputLatency)~", "~to!string(deviceInfo.defaultSampleRate)~", "~to!string(deviceInfo.hostApi)); } double sampleRate = 44100; PaStreamParameters* input; if (input != null) { input.device = 0; auto id = Pa_GetDeviceInfo(input.device); input.hostApiSpecificStreamInfo = null; input.channelCount = id.maxInputChannels; input.sampleFormat = paFloat32; input.suggestedLatency = (id.defaultLowInputLatency + id.defaultHighInputLatency)/2; sampleRate = id.defaultSampleRate; } PaStreamParameters* output = new PaStreamParameters(); if (output != null) { output.device = 9; auto od = Pa_GetDeviceInfo(output.device); output.hostApiSpecificStreamInfo = null; output.channelCount = od.maxOutputChannels; output.sampleFormat = paFloat32; output.suggestedLatency = (od.defaultLowOutputLatency + od.defaultHighOutputLatency)/2; sampleRate = od.defaultSampleRate; } //if ((err = Pa_OpenDefaultStream(&stream, 0, 2, paFloat32, SAMPLE_RATE, paFramesPerBufferUnspecified, &sawtooth, &phase_data)) != paNoError) goto Lerror; if ((err = Pa_OpenStream(&stream, input, output, sampleRate, paFramesPerBufferUnspecified, paNoFlag, &sawtooth, &phase_data)) != paNoError) goto Lerror; //PaError function(PaStream** stream, int numInputChannels, int numOutputChannels, PaSampleFormat sampleFormat, double sampleRate, ulong framesPerBuffer, , PaStreamCallback streamCallback, void *userData) Pa_OpenDefaultStream; //PaError function(PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, ulong framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback streamCallback, void *userData) Pa_OpenStream; if ((err = Pa_StartStream(stream)) != paNoError) goto Lerror; Pa_Sleep(NUM_SECONDS * 1000); writeln(test); if ((err = Pa_StopStream(stream)) != paNoError) goto Lerror; if ((err = Pa_CloseStream(stream)) != paNoError) goto Lerror; if ((err = Pa_Terminate()) != paNoError) goto Lerror; writeln("DONE"); getchar(); return 0; } else { Lerror: writeln(to!string(Pa_GetErrorText(err))); getchar(); return 1; } } return 0; }
Jul 06
prev sibling parent reply FoxyBrown <Foxy Brown.IPT> writes:
Heres a better version that automatically generates a class 
wrapping the portaudio.dll. Need portaudio.di(possibly renamed to 
portaudio.d and imported). Still same problem as original though.



import portaudio;
import std.conv, std.stdio;
import core.stdc.stdio;

alias BOOL = ubyte;
alias DWORD = uint;

auto BuildDLLClassFromCHeader(alias modulename, string name)()
{
	import std.traits, std.algorithm, std.meta;
	auto s = "extern (C) class " ~name~"\n{\n\timport ___import = 
"~moduleName!modulename~";\n";
	mixin("import "~moduleName!modulename~";");
	foreach(m; AliasSeq!(__traits(allMembers, modulename)))
	{		
		mixin("alias member = " ~ fullyQualifiedName!(modulename) ~ "." 
~ m ~ ";");		
		static if (is(typeof(member) == function))
			static if (functionLinkage!member != "C")
				continue;
			else
				s ~= "\tpublic static typeof(___import."~__traits(identifier, 
member)~")* "~__traits(identifier, member)~";\n";
	}
	
	return s ~ "}";
}

void DllImport(alias T)(string dllName)
{
	import core.sys.windows.windows, std.conv, std.meta;
	auto dll = LoadLibrary(to!wstring(dllName~"\0").ptr);
	if (dll == null)
		assert(0, "Cannot load DLL `"~dllName~"'");

	foreach(fname; __traits(derivedMembers, T))
	{		
		auto func = GetProcAddress(dll, fname);
		enum s = "auto p = cast(void**)&"~T.stringof~"."~fname~"; *p = 
cast(typeof(p))func;";				
		mixin(s);
	}
}


mixin(BuildDLLClassFromCHeader!(portaudio, "PortAudioDLL")());








struct Phase
{
     float left=0, right=0;
}

bool test = false;
extern(C) int sawtooth(const(void)* inputBuffer, void* 
outputBuffer, size_t framesPerBuffer, 
const(PaStreamCallbackTimeInfo)* timeInfo, PaStreamCallbackFlags 
statusFlags, void *userData)
{
	test = true;
     auto phase = cast(Phase*)userData;
     auto pout = cast(float*)outputBuffer;
     enum vol = 0.2f;
     foreach(i; 0 .. framesPerBuffer)
     {
         *pout++ = vol * phase.left;
         *pout++ = vol * phase.right;

         phase.left += 0.01f;
         if (phase.left >= 1.0f) phase.left -= 2.0f;

         phase.right += 0.03f;
         if (phase.right >= 1.0f) phase.right -= 2.0f;
     }
     return 0;
}

int main()
{
	DllImport!PortAudioDLL("portaudio_x86.dll");
	with(PortAudioDLL)
	{
		enum NUM_SECONDS = 5;

		PaStream* stream;
		PaError err;
		Phase phase_data;
	
		

		if ((err = Pa_Initialize()) == paNoError)
		{
			writeln("---------------------------------------------------------------------------");

			auto numDevices = Pa_GetDeviceCount();
			if(numDevices < 0)
			{
				printf("ERROR: Pa_CountDevices returned 0x%x\n", numDevices);
				err = numDevices;
				goto Lerror;
			}

		
			for(auto i = 0; i < numDevices; i++ )
			{	
				auto deviceInfo = Pa_GetDeviceInfo(i);
				writeln("Device "~to!string(i)~" > 
"~to!string(deviceInfo.name)~", 
"~to!string(deviceInfo.maxInputChannels)~", 
"~to!string(deviceInfo.maxOutputChannels)~", 
"~to!string(deviceInfo.defaultLowOutputLatency)~","~to!string(deviceInfo.defaultH
ghOutputLatency)~", "~to!string(deviceInfo.defaultSampleRate)~",
"~to!string(deviceInfo.hostApi));
			}

			double sampleRate = 44100;
			PaStreamParameters* input;
			if (input != null)
			{
				input.device = 0;
				auto id = Pa_GetDeviceInfo(input.device);
				input.hostApiSpecificStreamInfo = null;
				input.channelCount = id.maxInputChannels;
				input.sampleFormat = paFloat32;
				input.suggestedLatency = (id.defaultLowInputLatency + 
id.defaultHighInputLatency)/2;
				sampleRate = id.defaultSampleRate;
			}
			PaStreamParameters* output = new PaStreamParameters();
			if (output != null)
			{
				output.device = 9;
				auto od = Pa_GetDeviceInfo(output.device);
				output.hostApiSpecificStreamInfo = null;
				output.channelCount = od.maxOutputChannels;
				output.sampleFormat = paFloat32;
				output.suggestedLatency = (od.defaultLowOutputLatency + 
od.defaultHighOutputLatency)/2;
				sampleRate = od.defaultSampleRate;
			}
			if ((err =          Pa_OpenStream(&stream, input, output,      
             sampleRate, paFramesPerBufferUnspecified, paNoFlag, 
&sawtooth, &phase_data)) != paNoError) goto Lerror;



			if ((err = Pa_StartStream(stream)) != paNoError) goto Lerror;

			Pa_Sleep(NUM_SECONDS * 1000);

			writeln(test);
			if ((err = Pa_StopStream(stream)) != paNoError) goto Lerror;
			if ((err = Pa_CloseStream(stream)) != paNoError) goto Lerror;
			if ((err = Pa_Terminate()) != paNoError) goto Lerror;

			writeln("DONE");
			getchar();
			return 0;
		} else
		{
			Lerror:
				writeln(to!string(Pa_GetErrorText(err)));
				getchar();
				return 1;
		}
	}
	return 0;
}
Jul 06
parent Sebastiaan Koppe <mail skoppe.eu> writes:
On Thursday, 6 July 2017 at 20:36:08 UTC, FoxyBrown wrote:
 Heres a better version that automatically generates a class 
 wrapping the portaudio.dll. Need portaudio.di(possibly renamed 
 to portaudio.d and imported). Still same problem as original 
 though.
While you are at it. Please also write compile time C preprocessor. (He said half jokingly.) I tried your example. Unfortunately my windows dev setup is so far beyond repair, I could not get it to run. I am sorry but I can't help you.
Jul 07
prev sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 4 July 2017 at 17:51:06 UTC, Dukc wrote:
 When simplicity is the matter number 1, Arsd-official most 
 likely what you're looking for. It has a library file for 
 audio. Simpleaudio.d or Simplesound.d, not sure which it was.
simpleaudio.d. It'd probably be good enough for this (it works on Windows and Linux only though, no Mac), but I'm still not quite happy with the module which is why I didn't bring it up here.
Jul 04