Need simple sound
FoxyBrown via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Jul 6 11:18:43 PDT 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:
>> 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;
}
More information about the Digitalmars-d-learn
mailing list