initial commit
This commit is contained in:
20
vst-scheduler/makefile
Normal file
20
vst-scheduler/makefile
Normal file
@@ -0,0 +1,20 @@
|
||||
# Compile with MinGW.
|
||||
# You can call this makefile with:
|
||||
# make PDDIR=<path/to/pd>
|
||||
# or you can specify it below:
|
||||
|
||||
PDDIR=
|
||||
|
||||
WINARCH := $(shell $(CC) -dumpmachine)
|
||||
|
||||
ifeq (i686% , $(WINARCH))
|
||||
arch = 32
|
||||
else
|
||||
arch = 64
|
||||
endif
|
||||
|
||||
ALL: vstschedlib.c
|
||||
gcc -Wall -I$(PDDIR)src -I../vst-template vstschedlib.c -static-libgcc \
|
||||
-shared -L$(PDDIR)bin -l:pd.dll -o vstschedlib.dll
|
||||
strip vstschedlib.dll
|
||||
cp vstschedlib.dll ../build/pd-scheduler$(arch)/vstschedlib.dll
|
||||
730
vst-scheduler/vstschedlib.c
Normal file
730
vst-scheduler/vstschedlib.c
Normal file
@@ -0,0 +1,730 @@
|
||||
/* PdVst v0.0.2 - VST - Pd bridging plugin
|
||||
** Copyright (C) 2004 Joseph A. Sarlo
|
||||
**
|
||||
** This program is free software; you can redistribute it and/orsig
|
||||
** modify it under the terms of the GNU General Public License
|
||||
** as published by the Free Software Foundation; either version 2
|
||||
** of the License, or (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
**
|
||||
** jsarlo@ucsd.edu
|
||||
*/
|
||||
|
||||
#define _WIN32_WINDOWS 0x410
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#include "m_pd.h"
|
||||
#include "s_stuff.h"
|
||||
#include "pdvstTransfer.h"
|
||||
#define MAXARGS 1024
|
||||
#define MAXSTRLEN 1024
|
||||
#define TIMEUNITPERSEC (32.*441000.)
|
||||
|
||||
#define kVstTransportChanged 1
|
||||
#define kVstTransportPlaying 2
|
||||
|
||||
#define kVstTransportRecording 8
|
||||
#ifdef VSTMIDIOUTENABLE
|
||||
EXTERN int midi_outhead;
|
||||
int _midi_outtail=0; // _midi_outtail defined locally
|
||||
typedef struct _midiqelem
|
||||
{
|
||||
double q_time;
|
||||
int q_portno;
|
||||
unsigned char q_onebyte;
|
||||
unsigned char q_byte1;
|
||||
unsigned char q_byte2;
|
||||
unsigned char q_byte3;
|
||||
} t_midiqelem;
|
||||
|
||||
#ifndef MIDIQSIZE
|
||||
#define MIDIQSIZE 1024
|
||||
#endif /*MIDIQSIZE */
|
||||
|
||||
EXTERN t_midiqelem midi_outqueue[MIDIQSIZE];
|
||||
//EXTERN int msw_nmidiout;
|
||||
int msw_nmidiout=0;
|
||||
|
||||
#endif // VSTMIDIOUTENABLE
|
||||
|
||||
|
||||
typedef struct _vstParameterReceiver
|
||||
{
|
||||
t_object x_obj;
|
||||
t_symbol *x_sym;
|
||||
}t_vstParameterReceiver;
|
||||
|
||||
typedef struct _vstGuiNameReceiver
|
||||
{
|
||||
t_object x_obj;
|
||||
}t_vstGuiNameReceiver;
|
||||
|
||||
t_vstGuiNameReceiver *vstGuiNameReceiver;
|
||||
|
||||
t_vstParameterReceiver *vstParameterReceivers[MAXPARAMETERS];
|
||||
|
||||
t_class *vstParameterReceiver_class;
|
||||
t_class *vstGuiNameReceiver_class;
|
||||
|
||||
char *pdvstTransferMutexName,
|
||||
*pdvstTransferFileMapName,
|
||||
*vstProcEventName,
|
||||
*pdProcEventName;
|
||||
pdvstTransferData *pdvstData;
|
||||
HANDLE vstHostProcess,
|
||||
pdvstTransferMutex,
|
||||
pdvstTransferFileMap,
|
||||
vstProcEvent,
|
||||
pdProcEvent;
|
||||
pdvstTimeInfo timeInfo;
|
||||
|
||||
int tokenizeCommandLineString(char *clString, char **tokens)
|
||||
{
|
||||
int i, charCount = 0;
|
||||
int tokCount= 0;
|
||||
int quoteOpen = 0;
|
||||
|
||||
for (i = 0; i < (signed int)strlen(clString); i++)
|
||||
{
|
||||
if (clString[i] == '"')
|
||||
{
|
||||
quoteOpen = !quoteOpen;
|
||||
}
|
||||
else if (clString[i] == ' ' && !quoteOpen)
|
||||
{
|
||||
tokens[tokCount][charCount] = 0;
|
||||
tokCount++;
|
||||
charCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tokens[tokCount][charCount] = clString[i];
|
||||
charCount++;
|
||||
}
|
||||
}
|
||||
tokens[tokCount][charCount] = 0;
|
||||
tokCount++;
|
||||
return tokCount;
|
||||
}
|
||||
|
||||
void parseArgs(int argc, char **argv)
|
||||
{
|
||||
int vstHostProcessId;
|
||||
|
||||
while ((argc > 0) && (**argv == '-'))
|
||||
{
|
||||
if (strcmp(*argv, "-vsthostid") == 0)
|
||||
{
|
||||
vstHostProcessId = atoi(argv[1]);
|
||||
vstHostProcess = OpenProcess(PROCESS_ALL_ACCESS,
|
||||
FALSE,
|
||||
vstHostProcessId);
|
||||
if (vstHostProcess == NULL)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
if (strcmp(*argv, "-mutexname") == 0)
|
||||
{
|
||||
pdvstTransferMutexName = argv[1];
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
if (strcmp(*argv, "-filemapname") == 0)
|
||||
{
|
||||
pdvstTransferFileMapName = argv[1];
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
if (strcmp(*argv, "-vstproceventname") == 0)
|
||||
{
|
||||
vstProcEventName = argv[1];
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
if (strcmp(*argv, "-pdproceventname") == 0)
|
||||
{
|
||||
pdProcEventName = argv[1];
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int setPdvstGuiState(int state)
|
||||
{
|
||||
t_symbol *tempSym;
|
||||
|
||||
tempSym = gensym("rvstopengui");
|
||||
if (tempSym->s_thing)
|
||||
{
|
||||
pd_float(tempSym->s_thing, (float)state);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int setPdvstPlugName(char* instanceName)
|
||||
{
|
||||
t_symbol *tempSym;
|
||||
tempSym = gensym("rvstplugname");
|
||||
if (tempSym->s_thing)
|
||||
{
|
||||
pd_symbol(tempSym->s_thing, gensym(instanceName));
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int setPdvstFloatParameter(int index, float value)
|
||||
{
|
||||
t_symbol *tempSym;
|
||||
char string[1024];
|
||||
|
||||
sprintf(string, "rvstparameter%d", index);
|
||||
tempSym = gensym(string);
|
||||
if (tempSym->s_thing)
|
||||
{
|
||||
pd_float(tempSym->s_thing, value);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sendPdVstFloatParameter(t_vstParameterReceiver *x, t_float floatValue)
|
||||
{
|
||||
int index;
|
||||
|
||||
index = atoi(x->x_sym->s_name + strlen("svstParameter"));
|
||||
WaitForSingleObject(pdvstTransferMutex, INFINITE);
|
||||
pdvstData->vstParameters[index].type = FLOAT_TYPE;
|
||||
pdvstData->vstParameters[index].direction = PD_SEND;
|
||||
pdvstData->vstParameters[index].updated = 1;
|
||||
pdvstData->vstParameters[index].value.floatData = floatValue;
|
||||
ReleaseMutex(pdvstTransferMutex);
|
||||
}
|
||||
|
||||
void sendPdVstGuiName(t_vstGuiNameReceiver *x, t_symbol *symbolValue)
|
||||
{
|
||||
WaitForSingleObject(pdvstTransferMutex, INFINITE);
|
||||
pdvstData->guiName.type = STRING_TYPE;
|
||||
pdvstData->guiName.direction = PD_SEND;
|
||||
pdvstData->guiName.updated = 1;
|
||||
strcpy(pdvstData->guiName.value.stringData,symbolValue->s_name);
|
||||
|
||||
ReleaseMutex(pdvstTransferMutex);
|
||||
|
||||
}
|
||||
|
||||
void makePdvstParameterReceivers()
|
||||
{
|
||||
int i;
|
||||
char string[1024];
|
||||
|
||||
for (i = 0; i < MAXPARAMETERS; i++)
|
||||
{
|
||||
vstParameterReceivers[i] = (t_vstParameterReceiver *)pd_new(vstParameterReceiver_class);
|
||||
sprintf(string, "svstparameter%d", i);
|
||||
vstParameterReceivers[i]->x_sym = gensym(string);
|
||||
pd_bind(&vstParameterReceivers[i]->x_obj.ob_pd, gensym(string));
|
||||
}
|
||||
}
|
||||
|
||||
void makePdvstGuiNameReceiver()
|
||||
{
|
||||
vstGuiNameReceiver = (t_vstGuiNameReceiver *)pd_new(vstGuiNameReceiver_class);
|
||||
pd_bind(&vstGuiNameReceiver->x_obj.ob_pd, gensym("guiName"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void send_dacs(void)
|
||||
{
|
||||
int i, j, sampleCount, nChannels, blockSize;
|
||||
t_sample *soundin, *soundout;
|
||||
|
||||
soundin = get_sys_soundin();
|
||||
soundout = get_sys_soundout();
|
||||
nChannels = pdvstData->nChannels;
|
||||
blockSize = pdvstData->blockSize;
|
||||
if (blockSize == *(get_sys_schedblocksize()))
|
||||
{
|
||||
sampleCount = 0;
|
||||
for (i = 0; i < nChannels; i++)
|
||||
{
|
||||
for (j = 0; j < blockSize; j++)
|
||||
{
|
||||
soundin[sampleCount] = pdvstData->samples[i][j];
|
||||
pdvstData->samples[i][j] = soundout[sampleCount];
|
||||
soundout[sampleCount] = 0;
|
||||
sampleCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scheduler_tick( void)
|
||||
{
|
||||
//l sys_addhist(0);
|
||||
send_dacs();
|
||||
//l sys_setmiditimediff(0, 1e-6 * *(get_sys_schedadvance()));
|
||||
//l sys_addhist(1);
|
||||
/// { JYG
|
||||
//sched_tick(*(get_sys_time()) + *(get_sys_time_per_dsp_tick()));
|
||||
sched_tick();
|
||||
/// JYG }
|
||||
//l sys_addhist(2);
|
||||
sys_pollmidiqueue();
|
||||
sys_pollgui();
|
||||
//l sys_addhist(3);
|
||||
}
|
||||
/*
|
||||
int HFClock()
|
||||
{
|
||||
LARGE_INTEGER freq, now;
|
||||
|
||||
QueryPerformanceFrequency(&freq);
|
||||
QueryPerformanceCounter(&now);
|
||||
return (int)((now.QuadPart * 1000) / freq.QuadPart);
|
||||
}
|
||||
*/
|
||||
|
||||
int scheduler()
|
||||
{
|
||||
int i,
|
||||
blockTime,
|
||||
|
||||
active = 1;
|
||||
DWORD vstHostProcessStatus = 0;
|
||||
|
||||
|
||||
vstParameterReceiver_class = class_new(gensym("vstParameterReceiver"),
|
||||
0,
|
||||
0,
|
||||
sizeof(t_vstParameterReceiver),
|
||||
0,
|
||||
0);
|
||||
|
||||
class_addfloat(vstParameterReceiver_class, (t_method)sendPdVstFloatParameter);
|
||||
makePdvstParameterReceivers();
|
||||
|
||||
vstGuiNameReceiver_class = class_new(gensym("vstGuiNameReceiver"),
|
||||
0,
|
||||
0,
|
||||
sizeof(t_vstGuiNameReceiver),
|
||||
0,
|
||||
0);
|
||||
|
||||
class_addsymbol(vstGuiNameReceiver_class,(t_method)sendPdVstGuiName);
|
||||
makePdvstGuiNameReceiver();
|
||||
|
||||
*(get_sys_time_per_dsp_tick()) = (TIMEUNITPERSEC) * \
|
||||
((double)*(get_sys_schedblocksize())) / \
|
||||
*(get_sys_dacsr());
|
||||
//l sys_clearhist();
|
||||
//if (*(get_sys_sleepgrain()) < 1000) // JYG
|
||||
if (*(get_sys_sleepgrain()) < 100)
|
||||
{
|
||||
*(get_sys_sleepgrain()) = *(get_sys_schedadvance()) / 4;
|
||||
}
|
||||
if (*(get_sys_sleepgrain()) < 100)
|
||||
{
|
||||
*(get_sys_sleepgrain()) = 100;
|
||||
}
|
||||
else if (*(get_sys_sleepgrain()) > 5000)
|
||||
{
|
||||
*(get_sys_sleepgrain()) = 5000;
|
||||
}
|
||||
sys_initmidiqueue();
|
||||
|
||||
#ifdef VSTMIDIOUTENABLE
|
||||
pdvstData->midiOutQueueSize=0;
|
||||
#endif // VSTMIDIOUTENABLE
|
||||
while (active)
|
||||
{
|
||||
WaitForSingleObject(pdvstTransferMutex, INFINITE);
|
||||
active = pdvstData->active;
|
||||
// check sample rate
|
||||
if (pdvstData->sampleRate != (int)sys_getsr())
|
||||
{
|
||||
post("check samplerate");
|
||||
sys_setchsr(pdvstData->nChannels,
|
||||
pdvstData->nChannels,
|
||||
pdvstData->sampleRate);
|
||||
}
|
||||
// check for vstParameter changed
|
||||
if (pdvstData->guiState.direction == PD_RECEIVE && \
|
||||
pdvstData->guiState.updated)
|
||||
{
|
||||
if(setPdvstGuiState((int)pdvstData->guiState.value.floatData))
|
||||
pdvstData->guiState.updated=0;
|
||||
}
|
||||
// JYG { check for vstplug instance name
|
||||
if (pdvstData->plugName.direction == PD_RECEIVE && \
|
||||
pdvstData->plugName.updated)
|
||||
{
|
||||
if (setPdvstPlugName((char*)pdvstData->plugName.value.stringData))
|
||||
pdvstData->plugName.updated=0;
|
||||
}
|
||||
|
||||
if (pdvstData->hostTimeInfo.updated)
|
||||
{
|
||||
pdvstData->hostTimeInfo.updated=0;
|
||||
t_symbol *tempSym;
|
||||
|
||||
if (timeInfo.flags!=pdvstData->hostTimeInfo.flags)
|
||||
{
|
||||
timeInfo.flags=pdvstData->hostTimeInfo.flags;
|
||||
|
||||
tempSym = gensym("vstTimeInfo.flags");
|
||||
if (tempSym->s_thing)
|
||||
{
|
||||
pd_float(tempSym->s_thing, (float)timeInfo.flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeInfo.flags=0;
|
||||
pdvstData->hostTimeInfo.updated=1; // keep flag as updated
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ((timeInfo.flags&(kVstTransportChanged|kVstTransportPlaying|kVstTransportRecording))||(timeInfo.ppqPos!=(float)pdvstData->hostTimeInfo.ppqPos))
|
||||
{
|
||||
timeInfo.ppqPos=(float)pdvstData->hostTimeInfo.ppqPos;
|
||||
|
||||
tempSym = gensym("vstTimeInfo.ppqPos");
|
||||
if (tempSym->s_thing)
|
||||
{
|
||||
pd_float(tempSym->s_thing, timeInfo.ppqPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeInfo.ppqPos=0.;
|
||||
pdvstData->hostTimeInfo.updated=1; // keep flag as updated
|
||||
}
|
||||
}
|
||||
if ((timeInfo.flags&kVstTransportChanged)|(timeInfo.tempo!=(float)pdvstData->hostTimeInfo.tempo))
|
||||
{
|
||||
timeInfo.tempo=(float)pdvstData->hostTimeInfo.tempo;
|
||||
|
||||
tempSym = gensym("vstTimeInfo.tempo");
|
||||
if (tempSym->s_thing)
|
||||
{
|
||||
pd_float(tempSym->s_thing, timeInfo.tempo);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeInfo.tempo=0.;
|
||||
pdvstData->hostTimeInfo.updated=1; // keep flag as updated
|
||||
}
|
||||
}
|
||||
|
||||
if ((timeInfo.flags&kVstTransportChanged)|timeInfo.timeSigNumerator!=pdvstData->hostTimeInfo.timeSigNumerator)
|
||||
{
|
||||
timeInfo.timeSigNumerator=pdvstData->hostTimeInfo.timeSigNumerator;
|
||||
|
||||
tempSym = gensym("vstTimeInfo.timeSigNumerator");
|
||||
if (tempSym->s_thing)
|
||||
{
|
||||
pd_float(tempSym->s_thing, (float)timeInfo.timeSigNumerator);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeInfo.timeSigNumerator=0;
|
||||
pdvstData->hostTimeInfo.updated=1; // keep flag as updated
|
||||
}
|
||||
}
|
||||
if ((timeInfo.flags&kVstTransportChanged)| timeInfo.timeSigDenominator!=pdvstData->hostTimeInfo.timeSigDenominator)
|
||||
{
|
||||
timeInfo.timeSigDenominator=pdvstData->hostTimeInfo.timeSigDenominator;
|
||||
|
||||
tempSym = gensym("vstTimeInfo.timeSigDenominator");
|
||||
if (tempSym->s_thing)
|
||||
{
|
||||
pd_float(tempSym->s_thing, (float)timeInfo.timeSigDenominator);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeInfo.timeSigDenominator=0;
|
||||
pdvstData->hostTimeInfo.updated=1; // keep flag as updated
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// JYG }
|
||||
for (i = 0; i < pdvstData->nParameters; i++)
|
||||
{
|
||||
if (pdvstData->vstParameters[i].direction == PD_RECEIVE && \
|
||||
pdvstData->vstParameters[i].updated)
|
||||
{
|
||||
if (pdvstData->vstParameters[i].type == FLOAT_TYPE)
|
||||
{
|
||||
if (setPdvstFloatParameter(i,
|
||||
pdvstData->vstParameters[i].value.floatData))
|
||||
{
|
||||
pdvstData->vstParameters[i].updated = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// check for new midi-in message (VSTi)
|
||||
if (pdvstData->midiQueueUpdated)
|
||||
{
|
||||
for (i = 0; i < pdvstData->midiQueueSize; i++)
|
||||
{
|
||||
if (pdvstData->midiQueue[i].messageType == NOTE_ON)
|
||||
{
|
||||
inmidi_noteon(0,
|
||||
pdvstData->midiQueue[i].channelNumber,
|
||||
pdvstData->midiQueue[i].dataByte1,
|
||||
pdvstData->midiQueue[i].dataByte2);
|
||||
}
|
||||
else if (pdvstData->midiQueue[i].messageType == NOTE_OFF)
|
||||
{
|
||||
inmidi_noteon(0,
|
||||
pdvstData->midiQueue[i].channelNumber,
|
||||
pdvstData->midiQueue[i].dataByte1,
|
||||
0);
|
||||
}
|
||||
else if (pdvstData->midiQueue[i].messageType == CONTROLLER_CHANGE)
|
||||
{
|
||||
inmidi_controlchange(0,
|
||||
pdvstData->midiQueue[i].channelNumber,
|
||||
pdvstData->midiQueue[i].dataByte1,
|
||||
pdvstData->midiQueue[i].dataByte2);
|
||||
}
|
||||
else if (pdvstData->midiQueue[i].messageType == PROGRAM_CHANGE)
|
||||
{
|
||||
inmidi_programchange(0,
|
||||
pdvstData->midiQueue[i].channelNumber,
|
||||
pdvstData->midiQueue[i].dataByte1);
|
||||
}
|
||||
else if (pdvstData->midiQueue[i].messageType == PITCH_BEND)
|
||||
{
|
||||
int value = (((int)pdvstData->midiQueue[i].dataByte2) * 16) + \
|
||||
(int)pdvstData->midiQueue[i].dataByte1;
|
||||
|
||||
inmidi_pitchbend(0,
|
||||
pdvstData->midiQueue[i].channelNumber,
|
||||
value);
|
||||
}
|
||||
else if (pdvstData->midiQueue[i].messageType == CHANNEL_PRESSURE)
|
||||
{
|
||||
inmidi_aftertouch(0,
|
||||
pdvstData->midiQueue[i].channelNumber,
|
||||
pdvstData->midiQueue[i].dataByte1);
|
||||
}
|
||||
else if (pdvstData->midiQueue[i].messageType == KEY_PRESSURE)
|
||||
{
|
||||
inmidi_polyaftertouch(0,
|
||||
pdvstData->midiQueue[i].channelNumber,
|
||||
pdvstData->midiQueue[i].dataByte1,
|
||||
pdvstData->midiQueue[i].dataByte2);
|
||||
}
|
||||
else if (pdvstData->midiQueue[i].messageType == OTHER)
|
||||
{
|
||||
// FIXME: what to do?
|
||||
}
|
||||
else
|
||||
{
|
||||
post("pdvstData->midiQueue error"); // FIXME: error?
|
||||
}
|
||||
}
|
||||
pdvstData->midiQueueSize = 0;
|
||||
pdvstData->midiQueueUpdated = 0;
|
||||
}
|
||||
|
||||
/// flush vstmidi out messages here
|
||||
#ifdef VSTMIDIOUTENABLE
|
||||
if (msw_nmidiout==0)
|
||||
{
|
||||
int i=pdvstData->midiOutQueueSize; // si la midiOutQueue n'a pas été vidée, rajouter des éléments à la fin de celle-ci
|
||||
while (midi_outhead != _midi_outtail)
|
||||
{
|
||||
int statusType = midi_outqueue[_midi_outtail].q_byte1 & 0xF0;
|
||||
int statusChannel = midi_outqueue[_midi_outtail].q_byte1 & 0x0F;
|
||||
|
||||
// faut il gérer midi_outqueue[_midi_outtail].q_onebyte ?
|
||||
|
||||
///copie de la pile midi_outqueue dans la pile vst midiOutQueue
|
||||
pdvstData->midiOutQueue[i].channelNumber= statusChannel;
|
||||
pdvstData->midiOutQueue[i].statusByte = midi_outqueue[_midi_outtail].q_byte1;
|
||||
pdvstData->midiOutQueue[i].dataByte1= midi_outqueue[_midi_outtail].q_byte2;
|
||||
pdvstData->midiOutQueue[i].dataByte2= midi_outqueue[_midi_outtail].q_byte3;
|
||||
|
||||
if (statusType == 0x90)
|
||||
if (midi_outqueue[_midi_outtail].q_byte3==0)
|
||||
// note off
|
||||
{
|
||||
pdvstData->midiOutQueue[i].messageType = NOTE_OFF;
|
||||
pdvstData->midiOutQueue[i].statusByte = statusChannel|0x80;
|
||||
// post("note_off[%d] : %d",i,midi_outqueue[_midi_outtail].q_byte2);
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// note on
|
||||
pdvstData->midiOutQueue[i].messageType = NOTE_ON;
|
||||
//post("note_on[%d] : %d",i,midi_outqueue[_midi_outtail].q_byte2);
|
||||
|
||||
}
|
||||
else if (statusType == 0xA0)
|
||||
// key pressure
|
||||
pdvstData->midiOutQueue[i].messageType = KEY_PRESSURE;
|
||||
else if (statusType == 0xB0)
|
||||
// controller change
|
||||
pdvstData->midiOutQueue[i].messageType = CONTROLLER_CHANGE;
|
||||
else if (statusType == 0xC0)
|
||||
// program change
|
||||
pdvstData->midiOutQueue[i].messageType = PROGRAM_CHANGE;
|
||||
else if (statusType == 0xD0)
|
||||
// channel pressure
|
||||
pdvstData->midiOutQueue[i].messageType = CHANNEL_PRESSURE;
|
||||
else if (statusType == 0xE0)
|
||||
// pitch bend
|
||||
pdvstData->midiOutQueue[i].messageType = PITCH_BEND;
|
||||
else
|
||||
// something else
|
||||
pdvstData->midiOutQueue[i].messageType = OTHER;
|
||||
|
||||
|
||||
_midi_outtail = (_midi_outtail + 1 == MIDIQSIZE ? 0 : _midi_outtail + 1);
|
||||
i = i + 1;
|
||||
if (i>= MAXMIDIOUTQUEUESIZE)
|
||||
break;
|
||||
|
||||
}
|
||||
if (i>0)
|
||||
{
|
||||
pdvstData->midiOutQueueSize=i;
|
||||
pdvstData->midiOutQueueUpdated=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdvstData->midiOutQueueSize=0;
|
||||
pdvstData->midiOutQueueUpdated=0;
|
||||
}
|
||||
}
|
||||
#endif // VSTMIDIOUTENABLE
|
||||
|
||||
// run at approx. real-time
|
||||
blockTime = (int)((float)(pdvstData->blockSize) / \
|
||||
(float)pdvstData->sampleRate * 1000.0);
|
||||
if (blockTime < 1)
|
||||
{
|
||||
blockTime = 1;
|
||||
}
|
||||
if (pdvstData->syncToVst)
|
||||
{
|
||||
ReleaseMutex(pdvstTransferMutex);
|
||||
if (WaitForSingleObject(vstProcEvent, 1000) == WAIT_TIMEOUT)
|
||||
{
|
||||
// we have probably lost sync by now (1 sec)
|
||||
WaitForSingleObject(pdvstTransferMutex, 100);
|
||||
pdvstData->syncToVst = 0;
|
||||
ReleaseMutex(pdvstTransferMutex);
|
||||
}
|
||||
ResetEvent(vstProcEvent);
|
||||
scheduler_tick();
|
||||
SetEvent(pdProcEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReleaseMutex(pdvstTransferMutex);
|
||||
scheduler_tick();
|
||||
Sleep(blockTime);
|
||||
}
|
||||
GetExitCodeProcess(vstHostProcess, &vstHostProcessStatus);
|
||||
if (vstHostProcessStatus != STILL_ACTIVE)
|
||||
{
|
||||
active = 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pd_extern_sched(char *flags)
|
||||
{
|
||||
int i, argc;
|
||||
char *argv[MAXARGS];
|
||||
//l sys_audioapi = API_NONE;
|
||||
|
||||
|
||||
t_audiosettings as;
|
||||
|
||||
sys_get_audio_settings(&as);
|
||||
as.a_api = API_NONE;
|
||||
sys_set_audio_settings(&as);
|
||||
|
||||
//
|
||||
for (i = 0; i < MAXARGS; i++)
|
||||
{
|
||||
argv[i] = (char *)malloc(MAXSTRLEN * sizeof(char));
|
||||
}
|
||||
argc = tokenizeCommandLineString(flags, argv);
|
||||
parseArgs(argc, argv);
|
||||
pdvstTransferMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, pdvstTransferMutexName);
|
||||
vstProcEvent = OpenEvent(EVENT_ALL_ACCESS, 0, vstProcEventName);
|
||||
pdProcEvent = OpenEvent(EVENT_ALL_ACCESS, 0, pdProcEventName);
|
||||
pdvstTransferFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS,
|
||||
0,
|
||||
pdvstTransferFileMapName);
|
||||
pdvstData = (pdvstTransferData *)MapViewOfFile(pdvstTransferFileMap,
|
||||
FILE_MAP_ALL_ACCESS,
|
||||
0,
|
||||
0,
|
||||
sizeof(pdvstTransferData));
|
||||
WaitForSingleObject(pdvstTransferMutex, INFINITE);
|
||||
//l *(get_sys_schedadvance()) = *(get_sys_main_advance()) * 1000;
|
||||
//l post("Hello, appel sys_setchsr dans _main. Version 64");
|
||||
sys_setchsr(pdvstData->nChannels,
|
||||
pdvstData->nChannels,
|
||||
pdvstData->sampleRate);
|
||||
ReleaseMutex(pdvstTransferMutex);
|
||||
//timeBeginPeriod(1);
|
||||
scheduler();
|
||||
UnmapViewOfFile(pdvstData);
|
||||
CloseHandle(pdvstTransferFileMap);
|
||||
CloseHandle(pdvstTransferMutex);
|
||||
for (i = 0; i < MAXARGS; i++)
|
||||
{
|
||||
free(argv[i]);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user