|
|
@@ -1,5 +1,5 @@ |
|
|
|
/* |
|
|
|
* Copyright (C) 2006 Robert Reif |
|
|
|
* Copyright (C) 2006,2007 Robert Reif |
|
|
|
* |
|
|
|
* This library is free software; you can redistribute it and/or |
|
|
|
* modify it under the terms of the GNU Lesser General Public |
|
|
@@ -70,6 +70,7 @@ MAKE_FUNCPTR(jack_port_get_buffer); |
|
|
|
MAKE_FUNCPTR(jack_get_ports); |
|
|
|
MAKE_FUNCPTR(jack_port_name); |
|
|
|
MAKE_FUNCPTR(jack_get_buffer_size); |
|
|
|
MAKE_FUNCPTR(jack_port_unregister); |
|
|
|
#undef MAKE_FUNCPTR |
|
|
|
|
|
|
|
void *jackhandle = NULL; |
|
|
@@ -87,8 +88,8 @@ static GUID const CLSID_WineASIO = { |
|
|
|
#define twoRaisedTo32 4294967296.0 |
|
|
|
#define twoRaisedTo32Reciprocal (1.0 / twoRaisedTo32) |
|
|
|
|
|
|
|
#define MAX_INPUTS 2 |
|
|
|
#define MAX_OUTPUTS 2 |
|
|
|
#define MAX_INPUTS 32 |
|
|
|
#define MAX_OUTPUTS 32 |
|
|
|
|
|
|
|
/* ASIO drivers use the thiscall calling convention which only Microsoft compilers |
|
|
|
* produce. These macros add an extra layer to fixup the registers properly for |
|
|
@@ -182,19 +183,24 @@ struct IWineASIOImpl |
|
|
|
char error_message[256]; |
|
|
|
long in_map[MAX_INPUTS]; |
|
|
|
long out_map[MAX_OUTPUTS]; |
|
|
|
long num_inputs; |
|
|
|
long num_outputs; |
|
|
|
short *input_buffers[MAX_INPUTS][2]; |
|
|
|
short *output_buffers[MAX_OUTPUTS][2]; |
|
|
|
void *input_buffers[MAX_INPUTS][2]; |
|
|
|
void *output_buffers[MAX_OUTPUTS][2]; |
|
|
|
long active_inputs; |
|
|
|
long active_outputs; |
|
|
|
BOOL time_info_mode; |
|
|
|
BOOL tc_read; |
|
|
|
long state; |
|
|
|
unsigned int sample_size; |
|
|
|
int sample_type; |
|
|
|
|
|
|
|
/* JACK stuff */ |
|
|
|
char client_name[64]; |
|
|
|
unsigned int num_inputs; |
|
|
|
jack_port_t *input_port[MAX_INPUTS]; |
|
|
|
const char *input_names[MAX_INPUTS]; |
|
|
|
unsigned int num_outputs; |
|
|
|
jack_port_t *output_port[MAX_OUTPUTS]; |
|
|
|
const char *output_names[MAX_INPUTS]; |
|
|
|
jack_client_t *client; |
|
|
|
long client_state; |
|
|
|
long toggle; |
|
|
@@ -215,7 +221,7 @@ static ULONG WINAPI IWineASIOImpl_AddRef(LPWINEASIO iface) |
|
|
|
{ |
|
|
|
IWineASIOImpl *This = (IWineASIOImpl *)iface; |
|
|
|
ULONG ref = InterlockedIncrement(&(This->ref)); |
|
|
|
TRACE("(%p) ref was %ld\n", This, ref - 1); |
|
|
|
TRACE("(%p) ref was %d\n", This, ref - 1); |
|
|
|
return ref; |
|
|
|
} |
|
|
|
|
|
|
@@ -223,7 +229,7 @@ static ULONG WINAPI IWineASIOImpl_Release(LPWINEASIO iface) |
|
|
|
{ |
|
|
|
IWineASIOImpl *This = (IWineASIOImpl *)iface; |
|
|
|
ULONG ref = InterlockedDecrement(&(This->ref)); |
|
|
|
TRACE("(%p) ref was %ld\n", This, ref + 1); |
|
|
|
TRACE("(%p) ref was %d\n", This, ref + 1); |
|
|
|
|
|
|
|
if (!ref) { |
|
|
|
fp_jack_client_close(This->client); |
|
|
@@ -269,10 +275,25 @@ static HRESULT WINAPI IWineASIOImpl_QueryInterface(LPWINEASIO iface, REFIID riid |
|
|
|
WRAP_THISCALL( ASIOBool __stdcall, IWineASIOImpl_init, (LPWINEASIO iface, void *sysHandle)) |
|
|
|
{ |
|
|
|
IWineASIOImpl * This = (IWineASIOImpl*)iface; |
|
|
|
jack_port_t *input, *output; |
|
|
|
jack_status_t status; |
|
|
|
int i; |
|
|
|
const char ** ports; |
|
|
|
TRACE("(%p, %p)\n", iface, sysHandle); |
|
|
|
|
|
|
|
strcpy(This->client_name, "Wine_ASIO_Jack_Client"); |
|
|
|
#if 0 |
|
|
|
This->sample_type = ASIOSTInt16LSB; |
|
|
|
This->sample_size = 2; |
|
|
|
#endif |
|
|
|
#if 1 |
|
|
|
This->sample_type = ASIOSTInt32LSB; |
|
|
|
This->sample_size = 4; |
|
|
|
#endif |
|
|
|
#if 0 |
|
|
|
This->sample_type = ASIOSTFloat32LSB; |
|
|
|
This->sample_size = 4; |
|
|
|
#endif |
|
|
|
This->sample_rate = 48000.0; |
|
|
|
This->block_frames = 1024; |
|
|
|
This->input_latency = This->block_frames; |
|
|
@@ -313,14 +334,17 @@ WRAP_THISCALL( ASIOBool __stdcall, IWineASIOImpl_init, (LPWINEASIO iface, void * |
|
|
|
for (i = 0; i < MAX_INPUTS; i++) |
|
|
|
{ |
|
|
|
This->in_map[i] = 0; |
|
|
|
This->input_names[i] = 0; |
|
|
|
} |
|
|
|
|
|
|
|
for (i = 0; i < MAX_OUTPUTS; i++) |
|
|
|
{ |
|
|
|
This->out_map[i] = 0; |
|
|
|
This->output_names[i] = 0; |
|
|
|
} |
|
|
|
|
|
|
|
This->client = fp_jack_client_open("Wine_ASIO_Jack_Client", JackNullOption, &status, NULL); |
|
|
|
This->client = fp_jack_client_open(This->client_name, JackNullOption, &status, NULL); |
|
|
|
|
|
|
|
if (This->client == NULL) |
|
|
|
{ |
|
|
|
WARN("failed to open jack server\n"); |
|
|
@@ -332,38 +356,91 @@ WRAP_THISCALL( ASIOBool __stdcall, IWineASIOImpl_init, (LPWINEASIO iface, void * |
|
|
|
if (status & JackServerStarted) |
|
|
|
TRACE("JACK server started\n"); |
|
|
|
|
|
|
|
if (status & JackNameNotUnique) |
|
|
|
{ |
|
|
|
strcpy(This->client_name, jack_get_client_name(This->client)); |
|
|
|
TRACE("unique name `%s' assigned\n", This->client_name); |
|
|
|
} |
|
|
|
|
|
|
|
fp_jack_set_process_callback(This->client, jack_process, This); |
|
|
|
|
|
|
|
This->sample_rate = fp_jack_get_sample_rate(This->client); |
|
|
|
This->block_frames = fp_jack_get_buffer_size(This->client); |
|
|
|
|
|
|
|
This->miliseconds = (long)((double)(This->block_frames * 1000) / This->sample_rate); |
|
|
|
This->input_latency = This->block_frames; |
|
|
|
This->output_latency = This->block_frames * 2; |
|
|
|
|
|
|
|
TRACE("sample rate: %f\n", This->sample_rate); |
|
|
|
TRACE("buffer size: %ld\n", This->block_frames); |
|
|
|
|
|
|
|
for (i = 0; i < MAX_INPUTS; i++) |
|
|
|
{ |
|
|
|
char name[32]; |
|
|
|
snprintf(name, sizeof(name), "Input%d", i); |
|
|
|
This->input_port[i] = fp_jack_port_register(This->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, i); |
|
|
|
if (This->input_port[i] == 0) |
|
|
|
break; |
|
|
|
/* create two temporary ports to see what's out there */ |
|
|
|
input = fp_jack_port_register(This->client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); |
|
|
|
output = fp_jack_port_register(This->client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); |
|
|
|
|
|
|
|
This->num_inputs++; |
|
|
|
if ((input == NULL) || (output == NULL)) |
|
|
|
{ |
|
|
|
WARN("couldn't register ports\n"); |
|
|
|
return ASE_NotPresent; |
|
|
|
} |
|
|
|
|
|
|
|
TRACE("found %ld inputs\n", This->num_inputs); |
|
|
|
/* you need to the client to find out what ports are available */ |
|
|
|
if (fp_jack_activate(This->client)) |
|
|
|
{ |
|
|
|
WARN("couldn't activate client\n"); |
|
|
|
return ASE_NotPresent; |
|
|
|
} |
|
|
|
|
|
|
|
/* get the list of avaliable input ports */ |
|
|
|
ports = fp_jack_get_ports(This->client, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); |
|
|
|
|
|
|
|
if (ports == NULL) |
|
|
|
{ |
|
|
|
WARN("couldn't get input ports\n"); |
|
|
|
return ASE_NotPresent; |
|
|
|
} |
|
|
|
|
|
|
|
for (i = 0; i < MAX_OUTPUTS; i++) |
|
|
|
for (This->num_inputs = 0; This->num_inputs < MAX_INPUTS; This->num_inputs++) |
|
|
|
{ |
|
|
|
char name[32]; |
|
|
|
snprintf(name, sizeof(name), "Output%d", i); |
|
|
|
This->output_port[i] = fp_jack_port_register(This->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, i); |
|
|
|
if (This->output_port[i] == 0) |
|
|
|
if (ports[This->num_inputs]) |
|
|
|
{ |
|
|
|
This->input_names[This->num_inputs] = strdup(ports[This->num_inputs]); |
|
|
|
TRACE("input port[%d] %s\n", This->num_inputs, This->input_names[This->num_inputs]); |
|
|
|
} |
|
|
|
else |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
free(ports); |
|
|
|
|
|
|
|
/* get the list of avaliable output ports */ |
|
|
|
ports = fp_jack_get_ports(This->client, NULL, NULL, JackPortIsPhysical | JackPortIsInput); |
|
|
|
|
|
|
|
if (ports == NULL) |
|
|
|
{ |
|
|
|
WARN("couldn't get output ports\n"); |
|
|
|
return ASE_NotPresent; |
|
|
|
} |
|
|
|
|
|
|
|
This->num_outputs++; |
|
|
|
for (This->num_outputs = 0; This->num_outputs < MAX_OUTPUTS; This->num_outputs++) |
|
|
|
{ |
|
|
|
if (ports[This->num_outputs]) |
|
|
|
{ |
|
|
|
This->output_names[This->num_outputs] = strdup(ports[This->num_outputs]); |
|
|
|
TRACE("output port[%d] %s\n", This->num_outputs, This->output_names[This->num_outputs]); |
|
|
|
} |
|
|
|
else |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
TRACE("found %ld outputs\n", This->num_outputs); |
|
|
|
free(ports); |
|
|
|
|
|
|
|
/* get rid of temporary ports */ |
|
|
|
fp_jack_port_unregister(This->client, input); |
|
|
|
fp_jack_port_unregister(This->client, output); |
|
|
|
|
|
|
|
TRACE("found %d inputs\n", This->num_inputs); |
|
|
|
TRACE("found %d outputs\n", This->num_outputs); |
|
|
|
|
|
|
|
return ASIOTrue; |
|
|
|
} |
|
|
@@ -390,7 +467,6 @@ WRAP_THISCALL( void __stdcall, IWineASIOImpl_getErrorMessage, (LPWINEASIO iface, |
|
|
|
WRAP_THISCALL( ASIOError __stdcall, IWineASIOImpl_start, (LPWINEASIO iface)) |
|
|
|
{ |
|
|
|
IWineASIOImpl * This = (IWineASIOImpl*)iface; |
|
|
|
const char ** ports; |
|
|
|
int i; |
|
|
|
TRACE("(%p)\n", iface); |
|
|
|
|
|
|
@@ -400,52 +476,44 @@ WRAP_THISCALL( ASIOError __stdcall, IWineASIOImpl_start, (LPWINEASIO iface)) |
|
|
|
This->system_time.lo = 0; |
|
|
|
This->system_time.hi = 0; |
|
|
|
|
|
|
|
if (fp_jack_activate(This->client)) |
|
|
|
for (i = 0; i < This->active_inputs; i++) |
|
|
|
{ |
|
|
|
WARN("couldn't activate client\n"); |
|
|
|
return ASE_NotPresent; |
|
|
|
} |
|
|
|
This->input_port[i] = fp_jack_port_register(This->client, This->input_names[i], JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, i); |
|
|
|
|
|
|
|
ports = fp_jack_get_ports(This->client, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); |
|
|
|
if (This->input_port[i] == NULL) |
|
|
|
{ |
|
|
|
WARN("input %d connect failed\n", i); |
|
|
|
return ASE_NotPresent; |
|
|
|
} |
|
|
|
|
|
|
|
if (ports == NULL) |
|
|
|
{ |
|
|
|
WARN("couldn't get input ports\n"); |
|
|
|
return ASE_NotPresent; |
|
|
|
} |
|
|
|
TRACE("registered input port %d: %s\n", i, This->input_names[i]); |
|
|
|
|
|
|
|
for (i = 0; i < This->active_inputs; i++) |
|
|
|
{ |
|
|
|
if (fp_jack_connect(This->client, ports[i], fp_jack_port_name(This->input_port[i]))) |
|
|
|
if (fp_jack_connect(This->client, This->input_names[i], fp_jack_port_name(This->input_port[i]))) |
|
|
|
{ |
|
|
|
WARN("input %d connect failed\n", i); |
|
|
|
free(ports); |
|
|
|
return ASE_NotPresent; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
free(ports); |
|
|
|
for (i = 0; i < This->active_outputs; i++) |
|
|
|
{ |
|
|
|
This->output_port[i] = fp_jack_port_register(This->client, This->output_names[i], JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, i); |
|
|
|
|
|
|
|
ports = fp_jack_get_ports(This->client, NULL, NULL, JackPortIsPhysical | JackPortIsInput); |
|
|
|
if (This->output_port[i] == NULL) |
|
|
|
{ |
|
|
|
WARN("output %d connect failed\n", i); |
|
|
|
return ASE_NotPresent; |
|
|
|
} |
|
|
|
|
|
|
|
if (ports == NULL) |
|
|
|
{ |
|
|
|
WARN("couldn't get output ports\n"); |
|
|
|
return ASE_NotPresent; |
|
|
|
} |
|
|
|
TRACE("registered output port %d: %s\n", i, This->output_names[i]); |
|
|
|
|
|
|
|
for (i = 0; i < This->active_outputs; i++) |
|
|
|
{ |
|
|
|
if (fp_jack_connect(This->client, fp_jack_port_name(This->output_port[i]), ports[i])) |
|
|
|
if (fp_jack_connect(This->client, fp_jack_port_name(This->output_port[i]), This->output_names[i])) |
|
|
|
{ |
|
|
|
WARN("output %d connect failed\n", i); |
|
|
|
free(ports); |
|
|
|
return ASE_NotPresent; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
free(ports); |
|
|
|
|
|
|
|
This->state = Run; |
|
|
|
TRACE("started\n"); |
|
|
|
|
|
|
@@ -482,6 +550,8 @@ WRAP_THISCALL( ASIOError __stdcall, IWineASIOImpl_getChannels, (LPWINEASIO iface |
|
|
|
if (numOutputChannels) |
|
|
|
*numOutputChannels = This->num_outputs; |
|
|
|
|
|
|
|
TRACE("inputs: %d outputs: %d\n", This->num_inputs, This->num_outputs); |
|
|
|
|
|
|
|
return ASE_OK; |
|
|
|
} |
|
|
|
|
|
|
@@ -516,6 +586,8 @@ WRAP_THISCALL( ASIOError __stdcall, IWineASIOImpl_getBufferSize, (LPWINEASIO ifa |
|
|
|
if (granularity) |
|
|
|
*granularity = 0; |
|
|
|
|
|
|
|
TRACE("min: %ld max: %ld preferred: %ld granularity: 0\n", This->block_frames, This->block_frames, This->block_frames); |
|
|
|
|
|
|
|
return ASE_OK; |
|
|
|
} |
|
|
|
|
|
|
@@ -538,6 +610,8 @@ WRAP_THISCALL( ASIOError __stdcall, IWineASIOImpl_getSampleRate, (LPWINEASIO ifa |
|
|
|
if (sampleRate) |
|
|
|
*sampleRate = This->sample_rate; |
|
|
|
|
|
|
|
TRACE("rate: %f\n", This->sample_rate); |
|
|
|
|
|
|
|
return ASE_OK; |
|
|
|
} |
|
|
|
|
|
|
@@ -560,6 +634,8 @@ WRAP_THISCALL( ASIOError __stdcall, IWineASIOImpl_setSampleRate, (LPWINEASIO ifa |
|
|
|
This->callbacks->sampleRateDidChange(This->sample_rate); |
|
|
|
} |
|
|
|
|
|
|
|
TRACE("rate: %f\n", This->sample_rate); |
|
|
|
|
|
|
|
return ASE_OK; |
|
|
|
} |
|
|
|
|
|
|
@@ -623,13 +699,16 @@ WRAP_THISCALL( ASIOError __stdcall, IWineASIOImpl_getChannelInfo, (LPWINEASIO if |
|
|
|
{ |
|
|
|
IWineASIOImpl * This = (IWineASIOImpl*)iface; |
|
|
|
int i; |
|
|
|
char name[32]; |
|
|
|
const char * name; |
|
|
|
TRACE("(%p, %p)\n", iface, info); |
|
|
|
|
|
|
|
if (info->channel < 0 || (info->isInput ? info->channel >= MAX_INPUTS : info->channel >= MAX_OUTPUTS)) |
|
|
|
if (info->channel < 0 || (info->isInput ? info->channel >= This->num_inputs : info->channel >= This->num_outputs)) |
|
|
|
return ASE_InvalidParameter; |
|
|
|
|
|
|
|
info->type = ASIOSTInt16LSB; |
|
|
|
TRACE("info->channel = %ld\n", info->channel); |
|
|
|
TRACE("info->isInput = %ld\n", info->isInput); |
|
|
|
|
|
|
|
info->type = This->sample_type; |
|
|
|
info->channelGroup = 0; |
|
|
|
info->isActive = ASIOFalse; |
|
|
|
|
|
|
@@ -644,7 +723,7 @@ WRAP_THISCALL( ASIOError __stdcall, IWineASIOImpl_getChannelInfo, (LPWINEASIO if |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
snprintf(name, sizeof(name), "Input %ld", info->channel); |
|
|
|
name = This->input_names[info->channel]; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
@@ -657,11 +736,16 @@ WRAP_THISCALL( ASIOError __stdcall, IWineASIOImpl_getChannelInfo, (LPWINEASIO if |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
snprintf(name, sizeof(name), "Output %ld", info->channel); |
|
|
|
name = This->output_names[info->channel]; |
|
|
|
} |
|
|
|
|
|
|
|
strcpy(info->name, name); |
|
|
|
|
|
|
|
TRACE("info->isActive = %ld\n", info->isActive); |
|
|
|
TRACE("info->channelGroup = %ld\n", info->channelGroup); |
|
|
|
TRACE("info->type = %ld\n", info->type); |
|
|
|
TRACE("info->name = %s\n", info->name); |
|
|
|
|
|
|
|
return ASE_OK; |
|
|
|
} |
|
|
|
|
|
|
@@ -722,8 +806,8 @@ WRAP_THISCALL( ASIOError __stdcall, IWineASIOImpl_createBuffers, (LPWINEASIO ifa |
|
|
|
} |
|
|
|
|
|
|
|
This->in_map[This->active_inputs] = info->channelNum; |
|
|
|
This->input_buffers[This->active_inputs][0] = HeapAlloc(GetProcessHeap(), 0, This->block_frames * sizeof(short)); |
|
|
|
This->input_buffers[This->active_inputs][1] = HeapAlloc(GetProcessHeap(), 0, This->block_frames * sizeof(short)); |
|
|
|
This->input_buffers[This->active_inputs][0] = HeapAlloc(GetProcessHeap(), 0, This->block_frames * This->sample_size); |
|
|
|
This->input_buffers[This->active_inputs][1] = HeapAlloc(GetProcessHeap(), 0, This->block_frames * This->sample_size); |
|
|
|
if (This->input_buffers[This->active_inputs][0] && This->input_buffers[This->active_inputs][1]) |
|
|
|
{ |
|
|
|
info->buffers[0] = This->input_buffers[This->active_inputs][0]; |
|
|
@@ -754,8 +838,8 @@ WRAP_THISCALL( ASIOError __stdcall, IWineASIOImpl_createBuffers, (LPWINEASIO ifa |
|
|
|
} |
|
|
|
|
|
|
|
This->out_map[This->active_outputs] = info->channelNum; |
|
|
|
This->output_buffers[This->active_outputs][0] = HeapAlloc(GetProcessHeap(), 0, This->block_frames * sizeof(short)); |
|
|
|
This->output_buffers[This->active_outputs][1] = HeapAlloc(GetProcessHeap(), 0, This->block_frames * sizeof(short)); |
|
|
|
This->output_buffers[This->active_outputs][0] = HeapAlloc(GetProcessHeap(), 0, This->block_frames * This->sample_size); |
|
|
|
This->output_buffers[This->active_outputs][1] = HeapAlloc(GetProcessHeap(), 0, This->block_frames * This->sample_size); |
|
|
|
if (This->output_buffers[This->active_outputs][0] && This->output_buffers[This->active_outputs][1]) |
|
|
|
{ |
|
|
|
info->buffers[0] = This->output_buffers[This->active_outputs][0]; |
|
|
@@ -912,6 +996,7 @@ BOOL init_jack() |
|
|
|
LOAD_FUNCPTR(jack_get_ports); |
|
|
|
LOAD_FUNCPTR(jack_port_name); |
|
|
|
LOAD_FUNCPTR(jack_get_buffer_size); |
|
|
|
LOAD_FUNCPTR(jack_port_unregister); |
|
|
|
#undef LOAD_FUNCPTR |
|
|
|
|
|
|
|
return TRUE; |
|
|
@@ -931,8 +1016,10 @@ HRESULT asioCreateInstance(REFIID riid, LPVOID *ppobj) |
|
|
|
IWineASIOImpl * pobj; |
|
|
|
TRACE("(%s, %p)\n", debugstr_guid(riid), ppobj); |
|
|
|
|
|
|
|
if (!init_jack()) |
|
|
|
if (!init_jack()) { |
|
|
|
WARN("init_jack failed!\n"); |
|
|
|
return ERROR_NOT_SUPPORTED; |
|
|
|
} |
|
|
|
|
|
|
|
pobj = HeapAlloc(GetProcessHeap(), 0, sizeof(*pobj)); |
|
|
|
if (pobj == NULL) { |
|
|
@@ -973,14 +1060,41 @@ static int jack_process(jack_nframes_t nframes, void * arg) |
|
|
|
This->sample_position += nframes; |
|
|
|
|
|
|
|
/* get the input data from JACK and copy it to the ASIO buffers */ |
|
|
|
for (i = 0; i < This->active_inputs; i++) |
|
|
|
switch (This->sample_type) |
|
|
|
{ |
|
|
|
short * buffer = This->input_buffers[i][This->toggle]; |
|
|
|
case ASIOSTInt16LSB: |
|
|
|
for (i = 0; i < This->active_inputs; i++) |
|
|
|
{ |
|
|
|
short * buffer = This->input_buffers[i][This->toggle]; |
|
|
|
|
|
|
|
in = fp_jack_port_get_buffer(This->input_port[i], nframes); |
|
|
|
in = fp_jack_port_get_buffer(This->input_port[i], nframes); |
|
|
|
|
|
|
|
for (j = 0; j < nframes; j++) |
|
|
|
buffer[j] = in[j] * 32767.0f; |
|
|
|
for (j = 0; j < nframes; j++) |
|
|
|
buffer[j] = in[j] * 32767.0f; |
|
|
|
} |
|
|
|
break; |
|
|
|
case ASIOSTInt32LSB: |
|
|
|
for (i = 0; i < This->active_inputs; i++) |
|
|
|
{ |
|
|
|
int32_t * buffer = This->input_buffers[i][This->toggle]; |
|
|
|
|
|
|
|
in = fp_jack_port_get_buffer(This->input_port[i], nframes); |
|
|
|
|
|
|
|
for (j = 0; j < nframes; j++) |
|
|
|
buffer[j] = in[j] * 2147483647.0f; |
|
|
|
} |
|
|
|
break; |
|
|
|
case ASIOSTFloat32LSB: |
|
|
|
for (i = 0; i < This->active_inputs; i++) |
|
|
|
{ |
|
|
|
float * buffer = This->input_buffers[i][This->toggle]; |
|
|
|
|
|
|
|
in = fp_jack_port_get_buffer(This->input_port[i], nframes); |
|
|
|
|
|
|
|
for (j = 0; j < nframes; j++) |
|
|
|
buffer[j] = in[j]; |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
/* call the ASIO user callback to read the input data and fill the output data */ |
|
|
@@ -993,14 +1107,41 @@ static int jack_process(jack_nframes_t nframes, void * arg) |
|
|
|
sem_wait(&This->semaphore2); |
|
|
|
|
|
|
|
/* copy the ASIO data to JACK */ |
|
|
|
for (i = 0; i < This->active_outputs; i++) |
|
|
|
switch (This->sample_type) |
|
|
|
{ |
|
|
|
short * buffer = This->output_buffers[i][This->toggle]; |
|
|
|
case ASIOSTInt16LSB: |
|
|
|
for (i = 0; i < This->active_outputs; i++) |
|
|
|
{ |
|
|
|
short * buffer = This->output_buffers[i][This->toggle]; |
|
|
|
|
|
|
|
out = fp_jack_port_get_buffer(This->output_port[i], nframes); |
|
|
|
out = fp_jack_port_get_buffer(This->output_port[i], nframes); |
|
|
|
|
|
|
|
for (j = 0; j < nframes; j++) |
|
|
|
out[j] = buffer[j] / 32767.0f; |
|
|
|
for (j = 0; j < nframes; j++) |
|
|
|
out[j] = buffer[j] / 32767.0f; |
|
|
|
} |
|
|
|
break; |
|
|
|
case ASIOSTInt32LSB: |
|
|
|
for (i = 0; i < This->active_outputs; i++) |
|
|
|
{ |
|
|
|
int32_t * buffer = This->output_buffers[i][This->toggle]; |
|
|
|
|
|
|
|
out = fp_jack_port_get_buffer(This->output_port[i], nframes); |
|
|
|
|
|
|
|
for (j = 0; j < nframes; j++) |
|
|
|
out[j] = buffer[j] / 2147483647.0f; |
|
|
|
} |
|
|
|
break; |
|
|
|
case ASIOSTFloat32LSB: |
|
|
|
for (i = 0; i < This->active_outputs; i++) |
|
|
|
{ |
|
|
|
float * buffer = This->output_buffers[i][This->toggle]; |
|
|
|
|
|
|
|
out = fp_jack_port_get_buffer(This->output_port[i], nframes); |
|
|
|
|
|
|
|
for (j = 0; j < nframes; j++) |
|
|
|
out[j] = buffer[j]; |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (ts == JackTransportStopped) |
|
|
|