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.defaultHighOutputLatency)~", "~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;
}

Reply via email to