@@ -34,9 +34,20 @@ bool Pawfal_YesNo(const char *a,...) | |||||
::vsnprintf(buffer, 1024, a, ap); | ::vsnprintf(buffer, 1024, a, ap); | ||||
} | } | ||||
va_end(ap); | va_end(ap); | ||||
#if !__APPLE__ | |||||
PawfalYesNo pi(300, 100,buffer); | PawfalYesNo pi(300, 100,buffer); | ||||
if (pi.go()) return true; | if (pi.go()) return true; | ||||
#else | |||||
Str255 copy; | |||||
strncpy((char*)copy + 1, buffer, 253); | |||||
copy[0] = strlen((char*)copy+1); | |||||
AlertStdAlertParamRec rec = { true, false, NULL, | |||||
(StringPtr)-1, (StringPtr)-1, NULL, | |||||
kAlertStdAlertOKButton, 0, kWindowAlertPositionParentWindowScreen }; | |||||
SInt16 ret = 0; | |||||
StandardAlert(kAlertCautionAlert, copy, NULL, &rec, &ret); | |||||
return ret == kAlertStdAlertOKButton; | |||||
#endif | |||||
return false; | return false; | ||||
} | } | ||||
@@ -45,6 +45,10 @@ static int NKEYS = 30; | |||||
MidiDevice *MidiDevice::m_Singleton; | MidiDevice *MidiDevice::m_Singleton; | ||||
string MidiDevice::m_DeviceName; | string MidiDevice::m_DeviceName; | ||||
#if __APPLE__ | |||||
#define read AppleRead | |||||
#endif | |||||
MidiDevice::MidiDevice() : | MidiDevice::MidiDevice() : | ||||
m_Poly(1) | m_Poly(1) | ||||
{ | { | ||||
@@ -52,9 +56,7 @@ m_Poly(1) | |||||
seq_handle=AlsaOpen(); | seq_handle=AlsaOpen(); | ||||
#else | #else | ||||
Open(); | Open(); | ||||
#endif | |||||
#endif | |||||
#ifdef KEYBOARD_SUPPORT | #ifdef KEYBOARD_SUPPORT | ||||
m_Oct=4; | m_Oct=4; | ||||
@@ -78,6 +80,9 @@ MidiDevice::~MidiDevice() | |||||
void MidiDevice::Close() | void MidiDevice::Close() | ||||
{ | { | ||||
#if __APPLE__ | |||||
AppleClose(); | |||||
#else | |||||
pthread_mutex_lock(m_Mutex); | pthread_mutex_lock(m_Mutex); | ||||
pthread_cancel(m_MidiReader); | pthread_cancel(m_MidiReader); | ||||
pthread_mutex_unlock(m_Mutex); | pthread_mutex_unlock(m_Mutex); | ||||
@@ -86,11 +91,15 @@ void MidiDevice::Close() | |||||
close(m_MidiFd); | close(m_MidiFd); | ||||
close(m_MidiWrFd); | close(m_MidiWrFd); | ||||
cerr<<"Closed midi device"<<endl; | cerr<<"Closed midi device"<<endl; | ||||
#endif // !__APPLE__ | |||||
} | } | ||||
void MidiDevice::Open() | void MidiDevice::Open() | ||||
{ | { | ||||
#if __APPLE__ | |||||
AppleOpen(); | |||||
#else | |||||
//if (!SpiralInfo::WANTMIDI) return; | //if (!SpiralInfo::WANTMIDI) return; | ||||
m_MidiFd = open(m_DeviceName.c_str(),O_RDONLY|O_SYNC); | m_MidiFd = open(m_DeviceName.c_str(),O_RDONLY|O_SYNC); | ||||
@@ -108,6 +117,7 @@ void MidiDevice::Open() | |||||
} | } | ||||
cerr<<"Opened midi device ["<<m_DeviceName<<"]"<<endl; | cerr<<"Opened midi device ["<<m_DeviceName<<"]"<<endl; | ||||
#endif // !__APPLE__ | |||||
m_Mutex = new pthread_mutex_t; | m_Mutex = new pthread_mutex_t; | ||||
pthread_mutex_init(m_Mutex, NULL); | pthread_mutex_init(m_Mutex, NULL); | ||||
@@ -402,3 +412,89 @@ snd_seq_t *MidiDevice::AlsaOpen() | |||||
#endif | #endif | ||||
#if __APPLE__ | |||||
void MidiDevice::AppleOpen() | |||||
{ | |||||
m_ReadFillIndex = m_ReadReadIndex = 0; | |||||
OSStatus err = 0; | |||||
mMIDISource = NULL; | |||||
mMIDIClient = NULL; | |||||
mMIDIDestination = NULL; | |||||
err = MIDIClientCreate(CFSTR("org.pawpal.ssm"), NULL, NULL, &mMIDIClient); | |||||
if (err) printf("MIDIClientCreate failed returned %d\n", err); | |||||
if (!err) { | |||||
err = MIDISourceCreate(mMIDIClient, CFSTR("SpiralSynth"), &mMIDISource); | |||||
if (err) printf("MIDIInputPortCreate failed returned %d\n", err); | |||||
} | |||||
if (!err) { | |||||
err = MIDIDestinationCreate(mMIDIClient, CFSTR("SpiralSynth"), sMIDIRead, this, &mMIDIDestination); | |||||
MIDIObjectSetIntegerProperty(mMIDIDestination, kMIDIPropertyUniqueID, 'SSmP'); | |||||
} | |||||
} | |||||
void MidiDevice::AppleClose() | |||||
{ | |||||
if (mMIDIDestination) | |||||
MIDIEndpointDispose(mMIDIDestination); | |||||
if (mMIDISource) | |||||
MIDIEndpointDispose(mMIDISource); | |||||
mMIDISource = NULL; | |||||
if (mMIDIClient) | |||||
MIDIClientDispose(mMIDIClient); | |||||
mMIDIClient = NULL; | |||||
} | |||||
int MidiDevice::AppleWrite(int dummy, unsigned char *outbuffer, int maxlen) | |||||
{ | |||||
return 0; | |||||
} | |||||
int MidiDevice::AppleRead(int dummy, unsigned char *outbuffer, int maxlen) | |||||
{ | |||||
if (!mMIDIClient) | |||||
return -1; | |||||
int len = 0; | |||||
do { | |||||
while (m_ReadReadIndex == m_ReadFillIndex) | |||||
usleep(1000); // 1ms | |||||
int readl = m_ReadFillIndex - m_ReadReadIndex; | |||||
if (readl < 0) | |||||
readl += midi_ReadSize; // wrapped | |||||
while (len < maxlen && readl-- > 0) { | |||||
int r = m_ReadReadIndex; | |||||
outbuffer[len++] = m_ReadBuffer[r]; | |||||
r++; | |||||
m_ReadReadIndex = r % midi_ReadSize; | |||||
} | |||||
} while (len < maxlen); | |||||
return len; | |||||
} | |||||
void MidiDevice::sMIDIRead(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon) | |||||
{ | |||||
MidiDevice & t = *((MidiDevice*)readProcRefCon); | |||||
const MIDIPacket *packet = &pktlist->packet[0]; | |||||
for (int i = 0; i < (int)pktlist->numPackets; i++) { | |||||
const MIDIPacket & p = *packet; | |||||
for (int b = 0; b < p.length; b++) { | |||||
// printf("%02x ", p.data[b]); | |||||
int d = t.m_ReadFillIndex; | |||||
t.m_ReadBuffer[d] = p.data[b]; | |||||
d++; | |||||
t.m_ReadFillIndex = d % midi_ReadSize; | |||||
} | |||||
// printf("\n"); | |||||
packet = MIDIPacketNext(packet); | |||||
} | |||||
} | |||||
#endif |
@@ -36,6 +36,10 @@ using namespace std; | |||||
#include <alsa/asoundlib.h> | #include <alsa/asoundlib.h> | ||||
#endif | #endif | ||||
#if __APPLE__ | |||||
#include <CoreMIDI/MIDIServices.h> | |||||
#endif | |||||
class MidiEvent | class MidiEvent | ||||
{ | { | ||||
public: | public: | ||||
@@ -97,6 +101,25 @@ private: | |||||
snd_seq_t *seq_handle; | snd_seq_t *seq_handle; | ||||
snd_seq_t *AlsaOpen(); | snd_seq_t *AlsaOpen(); | ||||
#endif | #endif | ||||
#if __APPLE__ | |||||
MIDIClientRef mMIDIClient; | |||||
MIDIEndpointRef mMIDISource; | |||||
MIDIEndpointRef mMIDIDestination; | |||||
#define midi_ReadSize 4096 | |||||
unsigned char m_ReadBuffer[midi_ReadSize]; | |||||
volatile int m_ReadFillIndex; | |||||
volatile int m_ReadReadIndex; | |||||
void MidiDevice::AppleOpen(); | |||||
void MidiDevice::AppleClose(); | |||||
int MidiDevice::AppleWrite(int dummy, unsigned char *outbuffer, int maxlen); | |||||
int MidiDevice::AppleRead(int dummy, unsigned char *outbuffer, int maxlen); | |||||
static void MidiDevice::sMIDIRead(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon); | |||||
#endif | |||||
}; | }; | ||||
#endif | #endif |
@@ -35,7 +35,8 @@ class LFOPlugin : public SpiralPlugin { | |||||
virtual void StreamOut (ostream &s); | virtual void StreamOut (ostream &s); | ||||
virtual void StreamIn (istream &s); | virtual void StreamIn (istream &s); | ||||
enum Type {SINE, TRIANGLE, SQUARE, SAW}; | |||||
typedef char Type; | |||||
enum {SINE, TRIANGLE, SQUARE, SAW}; | |||||
void WriteWaves(); | void WriteWaves(); | ||||
void NoteTrigger (int V, int s, int v); | void NoteTrigger (int V, int s, int v); | ||||
@@ -34,7 +34,8 @@ public: | |||||
virtual void StreamOut(ostream &s); | virtual void StreamOut(ostream &s); | ||||
virtual void StreamIn(istream &s); | virtual void StreamIn(istream &s); | ||||
enum Type{NONE,SQUARE,SAW,NOISE}; | |||||
typedef char Type; | |||||
enum {NONE,SQUARE,SAW,NOISE}; | |||||
void ModulateFreq(Sample *data) {m_FreqModBuf=data;} | void ModulateFreq(Sample *data) {m_FreqModBuf=data;} | ||||
void ModulatePulseWidth(Sample *data) {m_PulseWidthModBuf=data;} | void ModulatePulseWidth(Sample *data) {m_PulseWidthModBuf=data;} | ||||
@@ -186,8 +186,10 @@ void Fl_Loop::DrawPosMarker() | |||||
if (m_Pos) | if (m_Pos) | ||||
{ | { | ||||
float Angle=(*m_Pos/m_Length)*360.0; | float Angle=(*m_Pos/m_Length)*360.0; | ||||
fl_line_style(FL_SOLID, 3, NULL); | |||||
fl_line_style(FL_SOLID, 3, NULL); | |||||
#if !__APPLE__ | |||||
XSetFunction(fl_display,fl_gc,GXxor); | XSetFunction(fl_display,fl_gc,GXxor); | ||||
#endif | |||||
fl_line(m_IndSX,m_IndSY,m_IndEX,m_IndEY); | fl_line(m_IndSX,m_IndSY,m_IndEX,m_IndEY); | ||||
fl_color(FL_BLUE); | fl_color(FL_BLUE); | ||||
@@ -200,7 +202,9 @@ void Fl_Loop::DrawPosMarker() | |||||
fl_line(m_IndSX,m_IndSY,m_IndEX,m_IndEY); | fl_line(m_IndSX,m_IndSY,m_IndEX,m_IndEY); | ||||
fl_line_style(FL_SOLID, 1, NULL); | fl_line_style(FL_SOLID, 1, NULL); | ||||
#if !__APPLE__ | |||||
XSetFunction(fl_display,fl_gc,GXcopy); | XSetFunction(fl_display,fl_gc,GXcopy); | ||||
#endif | |||||
} | } | ||||
if (m_PosMarkerCount>POSMARKER_MAX) | if (m_PosMarkerCount>POSMARKER_MAX) | ||||
@@ -40,7 +40,8 @@ public: | |||||
// has to be defined in the plugin | // has to be defined in the plugin | ||||
virtual void UpdateGUI() { Fl::check(); } | virtual void UpdateGUI() { Fl::check(); } | ||||
enum Type{SINE,SQUARE,SAW,REVSAW,TRIANGLE,PULSE1,PULSE2,INVSINE}; | |||||
typedef char Type; | |||||
enum {SINE,SQUARE,SAW,REVSAW,TRIANGLE,PULSE1,PULSE2,INVSINE}; | |||||
void WriteWaves(); | void WriteWaves(); | ||||
void NoteTrigger(int V,int s,int v); | void NoteTrigger(int V,int s,int v); | ||||
@@ -34,8 +34,8 @@ int LINE_COLOUR;// = 140; | |||||
//////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////// | ||||
Fl_EventMap::Fl_EventMap(int x, int y, int w, int h, const char* label) : | |||||
Fl_Group(x,y,w,h,label), | |||||
Fl_EventMap::Fl_EventMap(int x, int y, int ww, int h, const char* label) : | |||||
Fl_Group(x,y,ww,h,label), | |||||
m_Type(ARRANGE_MAP), | m_Type(ARRANGE_MAP), | ||||
m_Update(true), | m_Update(true), | ||||
m_Zoom(1.0f), | m_Zoom(1.0f), | ||||
@@ -62,6 +62,7 @@ m_FirstUpdate(true) | |||||
LINE_COLOUR=fl_color(); | LINE_COLOUR=fl_color(); | ||||
fl_color(200,200,200); | fl_color(200,200,200); | ||||
// SpiralSound/Plugins/Widgets/Fl_EventMap.C:65: declaration of `w' shadows a parameter | |||||
int w=fl_color(); | int w=fl_color(); | ||||
fl_color(50,50,50); | fl_color(50,50,50); | ||||
int b=fl_color(); | int b=fl_color(); | ||||
@@ -263,12 +264,14 @@ void Fl_EventMap::SetTime(float Time) | |||||
int Depth=parent()->h(); | int Depth=parent()->h(); | ||||
if (DrawPos>Left && DrawPos<Left+Width) | if (DrawPos>Left && DrawPos<Left+Width) | ||||
{ | |||||
{ | |||||
#if !__APPLE__ | |||||
XSetFunction(fl_display,fl_gc,GXxor); | XSetFunction(fl_display,fl_gc,GXxor); | ||||
XSetForeground(fl_display, fl_gc, 0xff00ffff); | XSetForeground(fl_display, fl_gc, 0xff00ffff); | ||||
if (!m_FirstUpdate) fl_line(m_LastPos,Top,m_LastPos,Depth); | if (!m_FirstUpdate) fl_line(m_LastPos,Top,m_LastPos,Depth); | ||||
fl_line(DrawPos,Top,DrawPos,Depth); | fl_line(DrawPos,Top,DrawPos,Depth); | ||||
XSetFunction(fl_display,fl_gc,GXcopy); | XSetFunction(fl_display,fl_gc,GXcopy); | ||||
#endif | |||||
m_LastPos=DrawPos; | m_LastPos=DrawPos; | ||||
} | } | ||||
} | } | ||||
@@ -32,9 +32,11 @@ | |||||
const int HEADERLEN = (4+24+8); | const int HEADERLEN = (4+24+8); | ||||
#if __BYTE_ORDER == BIG_ENDIAN | #if __BYTE_ORDER == BIG_ENDIAN | ||||
#define SWAPSHORT(a) (a)=(((a)<<8)|((a)>>8)) | |||||
#define SWAPSHORT(a) (a)=(((a)<<8)|(((a)>>8)&0xff)) | |||||
#define SWAPINT(a) (a)=(((a)&0x000000ff)<<24)|(((a)&0x0000ff00)<<8)|(((a)&0x00ff0000)>>8)|(((a)&0xff000000)>>24) | #define SWAPINT(a) (a)=(((a)&0x000000ff)<<24)|(((a)&0x0000ff00)<<8)|(((a)&0x00ff0000)>>8)|(((a)&0xff000000)>>24) | ||||
#else | |||||
#define SWAPSHORT(a) | |||||
#define SWAPINT(a) | |||||
#endif | #endif | ||||
int WavFile::Open(string FileName, Mode mode, Channels channels) | int WavFile::Open(string FileName, Mode mode, Channels channels) | ||||
@@ -92,7 +94,6 @@ int WavFile::Open(string FileName, Mode mode, Channels channels) | |||||
m_DataHeader.DataLengthBytes=0; | m_DataHeader.DataLengthBytes=0; | ||||
#if __BYTE_ORDER == BIG_ENDIAN | |||||
SWAPINT(m_Header.RiffFileLength); | SWAPINT(m_Header.RiffFileLength); | ||||
SWAPINT(m_Header.FmtLength); | SWAPINT(m_Header.FmtLength); | ||||
SWAPSHORT(m_Header.FmtTag); | SWAPSHORT(m_Header.FmtTag); | ||||
@@ -102,7 +103,6 @@ int WavFile::Open(string FileName, Mode mode, Channels channels) | |||||
SWAPSHORT(m_Header.FmtBlockAlign); | SWAPSHORT(m_Header.FmtBlockAlign); | ||||
SWAPSHORT(m_Header.FmtBitsPerSample); | SWAPSHORT(m_Header.FmtBitsPerSample); | ||||
SWAPINT(m_DataHeader.DataLengthBytes); | SWAPINT(m_DataHeader.DataLengthBytes); | ||||
#endif | |||||
fwrite(&m_Header,1,sizeof(CanonicalWavHeader),m_Stream); | fwrite(&m_Header,1,sizeof(CanonicalWavHeader),m_Stream); | ||||
fwrite(&m_DataHeader,1,sizeof(DataHeader),m_Stream); | fwrite(&m_DataHeader,1,sizeof(DataHeader),m_Stream); | ||||
@@ -113,7 +113,16 @@ int WavFile::Open(string FileName, Mode mode, Channels channels) | |||||
if (mode==READ) | if (mode==READ) | ||||
{ | { | ||||
fread(&m_Header,sizeof(CanonicalWavHeader),1,m_Stream); | fread(&m_Header,sizeof(CanonicalWavHeader),1,m_Stream); | ||||
SWAPINT(m_Header.RiffFileLength); | |||||
SWAPINT(m_Header.FmtLength); | |||||
SWAPSHORT(m_Header.FmtTag); | |||||
SWAPSHORT(m_Header.FmtChannels); | |||||
SWAPINT(m_Header.FmtSamplerate); | |||||
SWAPINT(m_Header.FmtBytesPerSec); | |||||
SWAPSHORT(m_Header.FmtBlockAlign); | |||||
SWAPSHORT(m_Header.FmtBitsPerSample); | |||||
#ifdef TRACE_OUT | #ifdef TRACE_OUT | ||||
cerr<<FileName<<endl; | cerr<<FileName<<endl; | ||||
cerr<<"RiffFileLength "<<m_Header.RiffFileLength<<endl; | cerr<<"RiffFileLength "<<m_Header.RiffFileLength<<endl; | ||||
@@ -133,7 +142,9 @@ int WavFile::Open(string FileName, Mode mode, Channels channels) | |||||
} | } | ||||
fread(&m_DataHeader,sizeof(DataHeader),1,m_Stream); | fread(&m_DataHeader,sizeof(DataHeader),1,m_Stream); | ||||
SWAPINT(m_DataHeader.DataLengthBytes); | |||||
while (m_DataHeader.DataName[0]!='d' || | while (m_DataHeader.DataName[0]!='d' || | ||||
m_DataHeader.DataName[1]!='a' || | m_DataHeader.DataName[1]!='a' || | ||||
m_DataHeader.DataName[2]!='t' || | m_DataHeader.DataName[2]!='t' || | ||||
@@ -206,10 +217,15 @@ int WavFile::Save(Sample &data) | |||||
float v=data[n]; | float v=data[n]; | ||||
if (v<-1) v=-1; if (v>1) v=1; | if (v<-1) v=-1; if (v>1) v=1; | ||||
temp[n]=(short)(v*SHRT_MAX); | temp[n]=(short)(v*SHRT_MAX); | ||||
SWAPSHORT(temp[n]); | |||||
} | } | ||||
m_DataHeader.DataLengthBytes+=data.GetLength()*2; | m_DataHeader.DataLengthBytes+=data.GetLength()*2; | ||||
fwrite(temp,sizeof(&temp),data.GetLength()/2,m_Stream); | fwrite(temp,sizeof(&temp),data.GetLength()/2,m_Stream); | ||||
// leak! | |||||
delete[] temp; | |||||
return 1; | return 1; | ||||
} | } | ||||
@@ -270,7 +286,9 @@ int WavFile::Load(Sample &data) | |||||
long value=0; | long value=0; | ||||
for (int i=0; i<m_Header.FmtChannels; i++) | for (int i=0; i<m_Header.FmtChannels; i++) | ||||
{ | { | ||||
value+=TempBuf[(n*m_Header.FmtChannels)+i]; | |||||
short s = TempBuf[(n*m_Header.FmtChannels)+i]; | |||||
SWAPSHORT(s); | |||||
value+=s; | |||||
} | } | ||||
value/=m_Header.FmtChannels; | value/=m_Header.FmtChannels; | ||||
@@ -280,7 +298,7 @@ int WavFile::Load(Sample &data) | |||||
m_DataHeader.DataLengthBytes /= m_Header.FmtChannels; | m_DataHeader.DataLengthBytes /= m_Header.FmtChannels; | ||||
m_Header.FmtChannels=1; | m_Header.FmtChannels=1; | ||||
delete TempBuf; | |||||
delete[] TempBuf; | |||||
} | } | ||||
else // it's mono. | else // it's mono. | ||||
{ | { | ||||
@@ -294,10 +312,12 @@ int WavFile::Load(Sample &data) | |||||
for (int n=0; n<GetSize(); n++) | for (int n=0; n<GetSize(); n++) | ||||
{ | { | ||||
data.Set(n,TempBuf[n]/(float)SHRT_MAX); | |||||
short s = TempBuf[n]; | |||||
SWAPSHORT(s); | |||||
data.Set(n,s/(float)SHRT_MAX); | |||||
} | } | ||||
delete TempBuf; | |||||
delete[] TempBuf; | |||||
} | } | ||||
return 1; | return 1; | ||||
@@ -324,7 +344,9 @@ int WavFile::Load(short *data) | |||||
long value=0; | long value=0; | ||||
for (int i=0; i<m_Header.FmtChannels; i++) | for (int i=0; i<m_Header.FmtChannels; i++) | ||||
{ | { | ||||
value+=TempBuf[(n*m_Header.FmtChannels)+i]; | |||||
short s = TempBuf[(n*m_Header.FmtChannels)+i]; | |||||
SWAPSHORT(s); | |||||
value+=s; | |||||
} | } | ||||
value/=m_Header.FmtChannels; | value/=m_Header.FmtChannels; | ||||
@@ -334,13 +356,18 @@ int WavFile::Load(short *data) | |||||
m_DataHeader.DataLengthBytes /= m_Header.FmtChannels; | m_DataHeader.DataLengthBytes /= m_Header.FmtChannels; | ||||
m_Header.FmtChannels=1; | m_Header.FmtChannels=1; | ||||
delete TempBuf; | |||||
delete[] TempBuf; | |||||
} | } | ||||
else // we can read the data directly in, it's mono. | else // we can read the data directly in, it's mono. | ||||
{ | { | ||||
if (m_DataHeader.DataLengthBytes== | if (m_DataHeader.DataLengthBytes== | ||||
(int)fread(data,1,m_DataHeader.DataLengthBytes,m_Stream)) | (int)fread(data,1,m_DataHeader.DataLengthBytes,m_Stream)) | ||||
{ | { | ||||
#if __BYTE_ORDER == BIG_ENDIAN | |||||
short *TempBuf = (short*)data; | |||||
for (int n=0; n < m_DataHeader.DataLengthBytes / 2; n++) | |||||
SWAPSHORT(TempBuf[n]); | |||||
#endif | |||||
return 1; | return 1; | ||||
} | } | ||||
@@ -389,7 +416,7 @@ int WavFile::LoadChunk(int NumSamples, Sample &ldata, Sample &rdata) | |||||
rdata.Set(n,TempBuf[(n*2)+1]/(float)SHRT_MAX); | rdata.Set(n,TempBuf[(n*2)+1]/(float)SHRT_MAX); | ||||
} | } | ||||
delete TempBuf; | |||||
delete[] TempBuf; | |||||
} | } | ||||
else // we can read the data directly in, it's mono. | else // we can read the data directly in, it's mono. | ||||
{ | { | ||||
@@ -24,6 +24,12 @@ | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include "Sample.h" | #include "Sample.h" | ||||
#if __APPLE__ | |||||
// this is the traditional way of setting 2 bytes alignment | |||||
// else the apple compiler might use 4, or even 8 | |||||
#pragma options align=mac68k | |||||
#endif | |||||
struct CanonicalWavHeader | struct CanonicalWavHeader | ||||
{ | { | ||||
char RiffName[4]; | char RiffName[4]; | ||||
@@ -46,6 +52,10 @@ struct DataHeader | |||||
int DataLengthBytes; | int DataLengthBytes; | ||||
}; | }; | ||||
#if __APPLE__ | |||||
#pragma options align=reset | |||||
#endif | |||||
class WavFile | class WavFile | ||||
{ | { | ||||
public: | public: | ||||
@@ -125,6 +125,11 @@ void SpiralSynthModularInfo::StreamInPrefs(istream &s) | |||||
s>>st; | s>>st; | ||||
if (st!="end") PLUGINVEC.push_back(st); | if (st!="end") PLUGINVEC.push_back(st); | ||||
} | } | ||||
#if __APPLE__ | |||||
// ignore custom paths, plugins are encapsulated in the app anyway | |||||
// this prevents the program to fail if the user move the application icon | |||||
PLUGIN_PATH = PLUGIN_PATH_LOCATION; | |||||
#endif | |||||
} | } | ||||
void SpiralSynthModularInfo::StreamOutPrefs(ostream &s) | void SpiralSynthModularInfo::StreamOutPrefs(ostream &s) | ||||
@@ -99,9 +99,29 @@ void audioloop(void* o) | |||||
} | } | ||||
////////////////////////////////////////////////////// | ////////////////////////////////////////////////////// | ||||
#if __APPLE__ | |||||
#include <CoreFoundation/CFBundle.h> | |||||
#include <libgen.h> | |||||
#endif | |||||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||||
{ | |||||
{ | |||||
#if __APPLE__ | |||||
// --with-plugindir=./Libraries | |||||
system("pwd"); | |||||
CFBundleRef main = CFBundleGetMainBundle(); | |||||
CFURLRef url = main ? CFBundleCopyExecutableURL(main) : NULL; | |||||
CFStringRef path = url ? CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle) : NULL; | |||||
char * dst = (char*)CFStringGetCStringPtr(path, 0); | |||||
printf("main %p url %p path %p dst %p", main, url, path, dst); | |||||
if (dst) { | |||||
printf("Have a valid name '%s'\n", dst); | |||||
chdir(dirname(dst)); | |||||
chdir(".."); | |||||
} else | |||||
printf("No base pathname\n"); | |||||
#endif | |||||
srand(time(NULL)); | srand(time(NULL)); | ||||
SpiralSynthModularInfo::Get()->LoadPrefs(); | SpiralSynthModularInfo::Get()->LoadPrefs(); | ||||