digitalmars.D.learn - Need simple sound
- Martin Tschierschke (3/3) Jul 03 2017 Hello for a simple game I would like to add some very simple
- Guillaume Piolat (3/6) Jul 03 2017 DerelictSDL supports the loading of SDL_mixer, which makes it
- Martin Tschierschke (6/13) Jul 03 2017 Thank you for the hint, a short google search was not so
- Vladimir Panteleev (3/17) Jul 04 2017 Here's a program that plays some square waves:
- Martin Tschierschke (2/20) Jul 04 2017 Cool, will try!
- Dukc (4/7) Jul 04 2017 When simplicity is the matter number 1, Arsd-official most likely
- Sebastiaan Koppe (1/6) Jul 04 2017 Portaudio is simple as well. And nice cross platform.
- FoxyBrown (2/8) Jul 04 2017 are there any bindings?
- Sebastiaan Koppe (2/5) Jul 05 2017 Sure, see http://code.dlang.org/packages/portaudio
- Martin Tschierschke (19/26) Jul 05 2017 Sorry, for that question but now, as I have several different
- Sebastiaan Koppe (75/103) Jul 05 2017 This one plays a wav file. Couldn't get dub to do single-file on
- Martin Tschierschke (27/68) Jul 05 2017 Thank you!
- FoxyBrown (3/10) Jul 06 2017 I can't seem to get this to work. Are there any windows dll's or
- Sebastiaan Koppe (3/15) Jul 06 2017 I have found dlls here
- FoxyBrown (240/247) Jul 06 2017 So, after a bit of work I can get port audio to work but the
- Sebastiaan Koppe (4/12) Jul 06 2017 The example I posted earlier did work on my Mac.
- FoxyBrown (16/29) Jul 06 2017 The example was drawn pretty much off the portaudio binding you
- Mike Parker (7/11) Jul 06 2017 That's what the DerelictUtil ([1] && [2]) package does, though it
- FoxyBrown (200/213) Jul 06 2017 I went ahead and simplified the DLL import
- FoxyBrown (146/146) Jul 06 2017 Heres a better version that automatically generates a class
- Sebastiaan Koppe (6/10) Jul 07 2017 While you are at it. Please also write compile time C
- Adam D. Ruppe (4/7) Jul 04 2017 simpleaudio.d. It'd probably be good enough for this (it works on
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 2017
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 2017
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: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?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 2017
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:Here's a program that plays some square waves: https://dump.thecybershadow.net/9db4fcd7b004e5dfccf537e49cbb72a6/test.dOn Monday, 3 July 2017 at 08:55:20 UTC, Martin Tschierschke wrote: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?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 04 2017
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:Cool, will try!On Monday, 3 July 2017 at 09:24:35 UTC, Guillaume Piolat wrote:Here's a program that plays some square waves: https://dump.thecybershadow.net/9db4fcd7b004e5dfccf537e49cbb72a6/test.dOn Monday, 3 July 2017 at 08:55:20 UTC, Martin Tschierschke wrote: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?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 04 2017
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 2017
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 2017
On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe wrote:are there any bindings?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 2017
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:Sure, see http://code.dlang.org/packages/portaudioPortaudio is simple as well. And nice cross platform.are there any bindings?
Jul 05 2017
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: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...? /+ dub.sdl: name "hello" +/ void main() { writef("Do you like the music?"); char[] answer; answer = readln(); writef("This was your Answer: ", answer); }On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe wrote:Sure, see http://code.dlang.org/packages/portaudioPortaudio is simple as well. And nice cross platform.are there any bindings?
Jul 05 2017
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: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; }On Wednesday, 5 July 2017 at 05:34:37 UTC, FoxyBrown wrote: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...? /+ dub.sdl: name "hello" +/ void main() { writef("Do you like the music?"); char[] answer; answer = readln(); writef("This was your Answer: ", answer); }On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe wrote:Sure, see http://code.dlang.org/packages/portaudioPortaudio is simple as well. And nice cross platform.are there any bindings?
Jul 05 2017
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: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)On Wednesday, 5 July 2017 at 05:34:37 UTC, FoxyBrown wrote: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...? /+ dub.sdl: name "hello" +/ void main() { writef("Do you like the music?"); char[] answer; answer = readln(); writef("This was your Answer: ", answer); }On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe wrote:Sure, see http://code.dlang.org/packages/portaudioPortaudio is simple as well. And nice cross platform.are there any bindings?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 2017
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:I can't seem to get this to work. Are there any windows dll's or libs that work that are not outdated?On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe wrote:Sure, see http://code.dlang.org/packages/portaudioPortaudio is simple as well. And nice cross platform.are there any bindings?
Jul 06 2017
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:I have found dlls here https://github.com/spatialaudio/portaudio-binariesOn Wednesday, 5 July 2017 at 05:34:37 UTC, FoxyBrown wrote:I can't seem to get this to work. Are there any windows dll's or libs that work that are not outdated?On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe wrote:Sure, see http://code.dlang.org/packages/portaudioPortaudio is simple as well. And nice cross platform.are there any bindings?
Jul 06 2017
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: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; }On Tuesday, 4 July 2017 at 20:37:44 UTC, Sebastiaan Koppe wrote:Sure, see http://code.dlang.org/packages/portaudioPortaudio is simple as well. And nice cross platform.are there any bindings?
Jul 06 2017
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:The example I posted earlier did work on my Mac. I will try your example + dll loader on Windows later today. Nice loader btw.Sure, see http://code.dlang.org/packages/portaudioSo, 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.
Jul 06 2017
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: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.On Wednesday, 5 July 2017 at 07:21:45 UTC, Sebastiaan Koppe wrote:The example I posted earlier did work on my Mac. I will try your example + dll loader on Windows later today. Nice loader btw.Sure, see http://code.dlang.org/packages/portaudioSo, 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.
Jul 06 2017
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 2017
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: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; }On Wednesday, 5 July 2017 at 07:21:45 UTC, Sebastiaan Koppe wrote:The example I posted earlier did work on my Mac. I will try your example + dll loader on Windows later today. Nice loader btw.Sure, see http://code.dlang.org/packages/portaudioSo, 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.
Jul 06 2017
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 2017
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 2017
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 2017