-
-
Save kode54/01929e2f1dfc9ee4f8f1 to your computer and use it in GitHub Desktop.
SCCore00 interface
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <dlfcn.h> | |
#include "SCCore.h" | |
SCCore::SCCore() | |
{ | |
duped = false; | |
path = 0; | |
handle = 0; | |
TG_initialize = 0; | |
//TG_terminate = 0; | |
TG_activate = 0; | |
TG_deactivate = 0; | |
TG_setSampleRate = 0; | |
TG_setMaxBlockSize = 0; | |
TG_flushMidi = 0; | |
TG_setInterruptThreadIdAtThisTime = 0; | |
// TG_PMidiIn = 0; | |
TG_ShortMidiIn = 0; | |
TG_LongMidiIn = 0; | |
// TG_isFatalError = 0; | |
// TG_getErrorStrings = 0; | |
TG_XPgetCurTotalRunningVoices = 0; | |
// TG_XPsetSystemConfig = 0; | |
// TG_XPgetCurSystemConfig = 0; | |
TG_Process = 0; | |
} | |
SCCore::~SCCore() | |
{ | |
Unload(); | |
} | |
void SCCore::Unload() | |
{ | |
if (handle) | |
{ | |
dlclose(handle); | |
handle = 0; | |
} | |
if (duped && path) | |
{ | |
unlink(path); | |
duped = false; | |
} | |
if (path) | |
{ | |
free(path); | |
path = 0; | |
} | |
} | |
static const char name_template[] = "/tmp/SCCore.dylib.XXXXXXXX"; | |
bool SCCore::Load(const char * _path, bool dupe) | |
{ | |
if (dupe) | |
{ | |
path = (char *) malloc(strlen(name_template) + 1); | |
strcpy(path, name_template); | |
mktemp(path); | |
const char * uniq = path + strlen(path) - 8; | |
FILE * f = fopen(_path, "rb"); | |
if (!f) return false; | |
fseek(f, 0, SEEK_END); | |
size_t fs = ftell(f); | |
fseek(f, 0, SEEK_SET); | |
unsigned char * buffer = (unsigned char *) malloc(fs); | |
if (!fs) | |
{ | |
fclose(f); | |
return false; | |
} | |
fread(buffer, 1, fs, f); | |
fclose(f); | |
for (size_t i = 0; i < fs - 14; ++i) | |
{ | |
if (memcmp(buffer + i, "SCCore00.dylib", 14) == 0) | |
{ | |
memcpy(buffer + i, uniq, 8); | |
i += 13; | |
} | |
} | |
duped = true; | |
f = fopen(path, "wb"); | |
if (!f) | |
{ | |
free(buffer); | |
return false; | |
} | |
fwrite(buffer, 1, fs, f); | |
fclose(f); | |
free(buffer); | |
} | |
else | |
{ | |
path = (char *) malloc(strlen(_path) + 1); | |
strcpy(path, _path); | |
} | |
handle = dlopen(path, RTLD_LAZY | RTLD_LOCAL); | |
if (handle) | |
{ | |
*(void**)&TG_initialize = dlsym(handle, "TG_initialize"); | |
//*(void**)&TG_terminate = dlsym(handle, "TG_terminate"); | |
*(void**)&TG_activate = dlsym(handle, "TG_activate"); | |
*(void**)&TG_deactivate = dlsym(handle, "TG_deactivate"); | |
*(void**)&TG_setSampleRate = dlsym(handle, "TG_setSampleRate"); | |
*(void**)&TG_setMaxBlockSize = dlsym(handle, "TG_setMaxBlockSize"); | |
*(void**)&TG_flushMidi = dlsym(handle, "TG_flushMidi"); | |
*(void**)&TG_setInterruptThreadIdAtThisTime = dlsym(handle, "TG_setInterruptThreadIdAtThisTime"); | |
//*(void**)&TG_PMidiIn = dlsym(handle, "TG_PMidiIn"); | |
*(void**)&TG_ShortMidiIn = dlsym(handle, "TG_ShortMidiIn"); | |
*(void**)&TG_LongMidiIn = dlsym(handle, "TG_LongMidiIn"); | |
//*(void**)&TG_isFatalError = dlsym(handle, "TG_isFatalError"); | |
//*(void**)&TG_getErrorStrings = dlsym(handle, "TG_getErrorStrings"); | |
*(void**)&TG_XPgetCurTotalRunningVoices = dlsym(handle, "TG_XPgetCurTotalRunningVoices"); | |
//*(void**)&TG_XPsetSystemConfig = dlsym(handle, "TG_XPsetSystemConfig"); | |
//*(void**)&TG_XPgetCurSystemConfig = dlsym(handle, "TG_XPgetCurSystemConfig"); | |
*(void**)&TG_Process = dlsym(handle, "TG_Process"); | |
if (TG_initialize && /*TG_terminate &&*/ TG_activate && TG_deactivate && | |
TG_setSampleRate && TG_setMaxBlockSize && TG_flushMidi && | |
TG_setInterruptThreadIdAtThisTime && /*TG_PMidiIn &&*/ | |
TG_ShortMidiIn && TG_LongMidiIn && /*TG_isFatalError && | |
TG_getErrorStrings &&*/ TG_XPgetCurTotalRunningVoices && | |
/*TG_XPsetSystemConfig && TG_XPgetCurSystemConfig &&*/ | |
TG_Process) | |
{ | |
return true; | |
} | |
else | |
{ | |
TG_initialize = 0; | |
//TG_terminate = 0; | |
TG_activate = 0; | |
TG_deactivate = 0; | |
TG_setSampleRate = 0; | |
TG_setMaxBlockSize = 0; | |
TG_flushMidi = 0; | |
TG_setInterruptThreadIdAtThisTime = 0; | |
// TG_PMidiIn = 0; | |
TG_ShortMidiIn = 0; | |
TG_LongMidiIn = 0; | |
// TG_isFatalError = 0; | |
// TG_getErrorStrings = 0; | |
TG_XPgetCurTotalRunningVoices = 0; | |
// TG_XPsetSystemConfig = 0; | |
// TG_XPgetCurSystemConfig = 0; | |
TG_Process = 0; | |
dlclose(handle); | |
handle = 0; | |
} | |
} | |
return false; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _SCCore_h_ | |
#define _SCCore_h_ | |
// Static single instance - duplicate library to temp path for unique instance | |
class SCCore | |
{ | |
bool duped; | |
char * path; | |
void * handle; | |
public: | |
int (* TG_initialize)(int i); // i = 0, returns negative on failure | |
//void (* TG_terminate)(); // Unused | |
void (* TG_activate)(float sampleRate, int blockSize); | |
void (* TG_deactivate)(); // Unused - hopefully cleans up | |
void (*TG_setSampleRate)(float sampleRate); | |
void (*TG_setMaxBlockSize)(unsigned int blockSize); | |
void (*TG_flushMidi)(); // Called after applying presets | |
void (*TG_setInterruptThreadIdAtThisTime)(); | |
//void (*TG_PMidiIn)(MpPacket *, int count); // Unknown | |
void (*TG_ShortMidiIn)(unsigned int eventCode, unsigned int deltaFrames); | |
void (*TG_LongMidiIn)(const unsigned char * sysEx, unsigned int deltaFrames); | |
//void (*TG_isFatalError)(int errCode); // Unused | |
//void (*TG_getErrorStrings)(int errCode); // Unused | |
unsigned int (*TG_XPgetCurTotalRunningVoices)(); // Unused | |
//void (*TG_XPsetSystemConfig)(); | |
//void (*TG_XPgetCurSystemConfig)(); | |
void (*TG_Process)(float * left, float * right, unsigned int count); | |
SCCore(); | |
~SCCore(); | |
bool Load(const char * path, bool dupe); | |
void Unload(); | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "SCPlayer.h" | |
SCPlayer::SCPlayer() : MIDIPlayer(), initialized(false) | |
{ | |
} | |
SCPlayer::~SCPlayer() | |
{ | |
shutdown(); | |
} | |
void SCPlayer::send_event(uint32_t b, uint32_t sample_offset) | |
{ | |
if (!(b & 0x80000000)) | |
{ | |
unsigned port = (b >> 24) & 0x7F; | |
if ( port > 2 ) port = 2; | |
sampler[port].TG_ShortMidiIn(b, sample_offset); | |
} | |
else | |
{ | |
uint32_t n = b & 0xffffff; | |
const uint8_t * data; | |
std::size_t size, port; | |
mSysexMap.get_entry( n, data, size, port ); | |
if ( port > 2 ) port = 2; | |
sampler[port].TG_LongMidiIn(data, sample_offset); | |
if ( port == 0 ) | |
{ | |
sampler[1].TG_LongMidiIn(data, sample_offset); | |
sampler[2].TG_LongMidiIn(data, sample_offset); | |
} | |
} | |
} | |
void SCPlayer::render_512(float * out) | |
{ | |
float buffer[2][512]; | |
memset(out, 0, 512 * sizeof(float) * 2); | |
for (unsigned long i = 0; i < 3; ++i) | |
{ | |
memset(buffer, 0, sizeof(buffer)); | |
sampler[i].TG_setInterruptThreadIdAtThisTime(); | |
sampler[i].TG_Process(buffer[0], buffer[1], 512); | |
for (unsigned long j = 0; j < 512; ++j) | |
{ | |
out[j * 2 + 0] += buffer[0][j]; | |
out[j * 2 + 1] += buffer[1][j]; | |
} | |
} | |
} | |
void SCPlayer::shutdown() | |
{ | |
for (int i = 0; i < 3; i++) | |
{ | |
if (sampler[i].TG_deactivate) | |
sampler[i].TG_deactivate(); | |
sampler[i].Unload(); | |
} | |
initialized = false; | |
} | |
bool SCPlayer::startup() | |
{ | |
if (initialized) return true; | |
for (int i = 0; i < 3; i++) | |
{ | |
if (!sampler[i].Load("SCCore00.dylib", true)) | |
return false; | |
if (sampler[i].TG_initialize(0) < 0) | |
return false; | |
sampler[i].TG_activate(44100.0, 1024); | |
sampler[i].TG_setMaxBlockSize(256); | |
sampler[i].TG_setSampleRate((float)uSampleRate); | |
sampler[i].TG_setSampleRate((float)uSampleRate); | |
sampler[i].TG_setMaxBlockSize(512); | |
} | |
initialized = true; | |
return true; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __SCPlayer_h__ | |
#define __SCPlayer_h__ | |
#include "MIDIPlayer.h" | |
#include "SCCore.h" | |
class SCPlayer : public MIDIPlayer | |
{ | |
public: | |
// zero variables | |
SCPlayer(); | |
// close, unload | |
virtual ~SCPlayer(); | |
protected: | |
virtual void send_event(uint32_t b, uint32_t sample_offset); | |
virtual void render_512(float * out); | |
virtual void shutdown(); | |
virtual bool startup(); | |
private: | |
SCCore sampler[3]; | |
bool initialized; | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment