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.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 = 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;
}

Reply via email to