diff --git a/Plugins/MIDI/MIDI.xcodeproj/project.pbxproj b/Plugins/MIDI/MIDI.xcodeproj/project.pbxproj index 9051417fd..333863433 100644 --- a/Plugins/MIDI/MIDI.xcodeproj/project.pbxproj +++ b/Plugins/MIDI/MIDI.xcodeproj/project.pbxproj @@ -33,8 +33,6 @@ 83B06722180D70FE008E3612 /* MIDIDecoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83B06721180D70FE008E3612 /* MIDIDecoder.mm */; }; 83C35702180EDB74007E9DF0 /* MIDIContainer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83C35700180EDB74007E9DF0 /* MIDIContainer.mm */; }; 83C35705180EDD1C007E9DF0 /* MIDIMetadataReader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83C35703180EDD1C007E9DF0 /* MIDIMetadataReader.mm */; }; - 83DFEA071CBC87BB00BCC565 /* SCCore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83DFEA031CBC87BB00BCC565 /* SCCore.cpp */; }; - 83DFEA081CBC87BB00BCC565 /* SCPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83DFEA051CBC87BB00BCC565 /* SCPlayer.cpp */; }; 83E973471C4378880007F413 /* AUPlayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83E973451C4378880007F413 /* AUPlayer.mm */; }; /* End PBXBuildFile section */ @@ -140,10 +138,6 @@ 83C35701180EDB74007E9DF0 /* MIDIContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIDIContainer.h; sourceTree = ""; }; 83C35703180EDD1C007E9DF0 /* MIDIMetadataReader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MIDIMetadataReader.mm; sourceTree = ""; }; 83C35704180EDD1C007E9DF0 /* MIDIMetadataReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIDIMetadataReader.h; sourceTree = ""; }; - 83DFEA031CBC87BB00BCC565 /* SCCore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SCCore.cpp; sourceTree = ""; }; - 83DFEA041CBC87BB00BCC565 /* SCCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCCore.h; sourceTree = ""; }; - 83DFEA051CBC87BB00BCC565 /* SCPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SCPlayer.cpp; sourceTree = ""; }; - 83DFEA061CBC87BB00BCC565 /* SCPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPlayer.h; sourceTree = ""; }; 83E973451C4378880007F413 /* AUPlayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AUPlayer.mm; sourceTree = ""; }; 83E973461C4378880007F413 /* AUPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUPlayer.h; sourceTree = ""; }; 83FAF8A618ADD60100057CAF /* PlaylistController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlaylistController.h; path = ../../../Playlist/PlaylistController.h; sourceTree = ""; }; @@ -270,10 +264,6 @@ 83A09F5D1CFA83F2001E7D2D /* fmopl3lib */, 834BE9191DE407CB00A07DCD /* resampler.c */, 834BE91A1DE407CB00A07DCD /* resampler.h */, - 83DFEA031CBC87BB00BCC565 /* SCCore.cpp */, - 83DFEA041CBC87BB00BCC565 /* SCCore.h */, - 83DFEA051CBC87BB00BCC565 /* SCPlayer.cpp */, - 83DFEA061CBC87BB00BCC565 /* SCPlayer.h */, 83686AAD1C5C6A2700671C7A /* AUPlayerView.h */, 83686AAB1C5C69D400671C7A /* AUPlayerView.mm */, 83E973451C4378880007F413 /* AUPlayer.mm */, @@ -403,10 +393,8 @@ files = ( 83E973471C4378880007F413 /* AUPlayer.mm in Sources */, 83686AAC1C5C69D400671C7A /* AUPlayerView.mm in Sources */, - 83DFEA071CBC87BB00BCC565 /* SCCore.cpp in Sources */, 83A09F621CFA83F2001E7D2D /* i_oplmusic.cpp in Sources */, 83B06709180D64DA008E3612 /* MIDIPlayer.cpp in Sources */, - 83DFEA081CBC87BB00BCC565 /* SCPlayer.cpp in Sources */, 83A09F631CFA83F2001E7D2D /* opl3midi.cpp in Sources */, 83B06722180D70FE008E3612 /* MIDIDecoder.mm in Sources */, 83A09F6F1CFA8D6B001E7D2D /* MSPlayer.cpp in Sources */, diff --git a/Plugins/MIDI/MIDI/AUPlayer.h b/Plugins/MIDI/MIDI/AUPlayer.h index 65185876d..2efe253a6 100644 --- a/Plugins/MIDI/MIDI/AUPlayer.h +++ b/Plugins/MIDI/MIDI/AUPlayer.h @@ -31,12 +31,17 @@ public: void setComponent(OSType uSubType, OSType uManufacturer); protected: + virtual unsigned int send_event_needs_time(); virtual void send_event(uint32_t b); + virtual void send_sysex(const uint8_t * data, size_t size, size_t port); virtual void render(float * out, unsigned long count); virtual void shutdown(); virtual bool startup(); + virtual void send_event_time(uint32_t b, unsigned int time); + virtual void send_sysex_time(const uint8_t * data, size_t size, size_t port, unsigned int time); + private: void loadSoundFont(const char * name); diff --git a/Plugins/MIDI/MIDI/AUPlayer.mm b/Plugins/MIDI/MIDI/AUPlayer.mm index 3f7589c94..974ee4019 100644 --- a/Plugins/MIDI/MIDI/AUPlayer.mm +++ b/Plugins/MIDI/MIDI/AUPlayer.mm @@ -12,6 +12,8 @@ #define _countof(arr) (sizeof(arr) / sizeof((arr)[0])) +#define BLOCK_SIZE (512) + AUPlayer::AUPlayer() : MIDIPlayer() { samplerUnit[0] = NULL; @@ -38,40 +40,53 @@ AUPlayer::~AUPlayer() } void AUPlayer::send_event(uint32_t b) +{ + send_event_time(b, 0); +} + +void AUPlayer::send_sysex(const uint8_t * data, size_t size, size_t port) +{ + send_sysex_time(data, size, port, 0); +} + +void AUPlayer::send_event_time(uint32_t b, unsigned int time) { #ifdef AUPLAYERVIEW int _port = -1; #endif - if (!(b & 0x80000000)) - { - unsigned char event[ 3 ]; - event[ 0 ] = (unsigned char)b; - event[ 1 ] = (unsigned char)( b >> 8 ); - event[ 2 ] = (unsigned char)( b >> 16 ); - unsigned port = (b >> 24) & 0x7F; - if ( port > 2 ) port = 2; + unsigned char event[ 3 ]; + event[ 0 ] = (unsigned char)b; + event[ 1 ] = (unsigned char)( b >> 8 ); + event[ 2 ] = (unsigned char)( b >> 16 ); + unsigned port = (b >> 24) & 0x7F; + if ( port > 2 ) port = 2; #ifdef AUPLAYERVIEW - _port = (int)port; + _port = (int)port; #endif - MusicDeviceMIDIEvent(samplerUnit[port], event[0], event[1], event[2], 0); + MusicDeviceMIDIEvent(samplerUnit[port], event[0], event[1], event[2], time); +#ifdef AUPLAYERVIEW + if (_port >= 0 && !samplerUIinitialized[_port]) + { + samplerUIinitialized[_port] = true; + dispatch_async(dispatch_get_main_queue(), ^{ + samplerUI[_port] = new AUPluginUI(samplerUnit[_port]); + }); } - 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; -#ifdef AUPLAYERVIEW - _port = (int)port; #endif - MusicDeviceSysEx(samplerUnit[port], data, (UInt32) size); - if ( port == 0 ) - { - MusicDeviceSysEx(samplerUnit[1], data, (UInt32) size); - MusicDeviceSysEx(samplerUnit[2], data, (UInt32) size); - } - } +} + +void AUPlayer::send_sysex_time(const uint8_t * data, size_t size, size_t port, unsigned int time) +{ + if ( port > 2 ) port = 0; +#ifdef AUPLAYERVIEW + _port = (int)port; +#endif + MusicDeviceSysEx(samplerUnit[port], data, (UInt32) size); + if ( port == 0 ) + { + MusicDeviceSysEx(samplerUnit[1], data, (UInt32) size); + MusicDeviceSysEx(samplerUnit[2], data, (UInt32) size); + } #ifdef AUPLAYERVIEW if (_port >= 0 && !samplerUIinitialized[_port]) { @@ -89,7 +104,7 @@ void AUPlayer::render(float * out, unsigned long count) memset(out, 0, count * sizeof(float) * 2); while (count) { - UInt32 numberFrames = count > 512 ? 512 : (UInt32) count; + UInt32 numberFrames = count > BLOCK_SIZE ? BLOCK_SIZE : (UInt32) count; for (unsigned long i = 0; i < 3; ++i) { @@ -99,7 +114,7 @@ void AUPlayer::render(float * out, unsigned long count) { bufferList->mBuffers[j].mNumberChannels = 1; bufferList->mBuffers[j].mDataByteSize = (UInt32) (numberFrames * sizeof(float)); - bufferList->mBuffers[j].mData = audioBuffer + j * 512; + bufferList->mBuffers[j].mData = audioBuffer + j * BLOCK_SIZE; memset(bufferList->mBuffers[j].mData, 0, numberFrames * sizeof(float)); } @@ -175,6 +190,7 @@ void AUPlayer::shutdown() free(bufferList); bufferList = NULL; } + initialized = false; } void AUPlayer::enumComponents(callback cbEnum) @@ -291,7 +307,7 @@ bool AUPlayer::startup() kAudioUnitScope_Output, 0, &stream, sizeof (stream)); } - value = 512; + value = BLOCK_SIZE; AudioUnitSetProperty (samplerUnit[i], kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &value, size); @@ -348,7 +364,7 @@ bool AUPlayer::startup() if (!bufferList) return false; - audioBuffer = (float *) malloc(1024 * sizeof(float)); + audioBuffer = (float *) malloc(BLOCK_SIZE * 2 * sizeof(float)); if (!audioBuffer) return false; @@ -357,6 +373,10 @@ bool AUPlayer::startup() memset(&mTimeStamp, 0, sizeof(mTimeStamp)); mTimeStamp.mFlags = kAudioTimeStampSampleTimeValid; + initialized = true; + + setFilterMode(mode); + return true; } @@ -377,3 +397,8 @@ void AUPlayer::loadSoundFont(const char *name) CFRelease(url); } } + +unsigned int AUPlayer::send_event_needs_time() +{ + return BLOCK_SIZE; +} diff --git a/Plugins/MIDI/MIDI/MIDIDecoder.mm b/Plugins/MIDI/MIDI/MIDIDecoder.mm index 099b9be86..a997a666a 100755 --- a/Plugins/MIDI/MIDI/MIDIDecoder.mm +++ b/Plugins/MIDI/MIDI/MIDIDecoder.mm @@ -10,7 +10,6 @@ #import "AUPlayer.h" #import "SFPlayer.h" -#import "SCPlayer.h" #import "MSPlayer.h" #import "Logging.h" @@ -155,6 +154,26 @@ static OSType getOSType(const char * in_) DLog(@"Track num: %i", track_num); + MIDIPlayer::filter_mode mode = MIDIPlayer::filter_sc55; + + NSString * flavor = [[NSUserDefaults standardUserDefaults] stringForKey:@"midi.flavor"]; + if ([flavor isEqualToString:@"default"]) + mode = MIDIPlayer::filter_default; + else if ([flavor isEqualToString:@"gm"]) + mode = MIDIPlayer::filter_gm; + else if ([flavor isEqualToString:@"gm2"]) + mode = MIDIPlayer::filter_gm2; + else if ([flavor isEqualToString:@"sc55"]) + mode = MIDIPlayer::filter_sc55; + else if ([flavor isEqualToString:@"sc88"]) + mode = MIDIPlayer::filter_sc88; + else if ([flavor isEqualToString:@"sc88pro"]) + mode = MIDIPlayer::filter_sc88pro; + else if ([flavor isEqualToString:@"sc8850"]) + mode = MIDIPlayer::filter_sc8850; + else if ([flavor isEqualToString:@"xg"]) + mode = MIDIPlayer::filter_xg; + NSString * plugin = [[NSUserDefaults standardUserDefaults] stringForKey:@"midi.plugin"]; if (!plugin || [plugin isEqualToString:@"FluidSynth"]) { @@ -212,41 +231,6 @@ static OSType getOSType(const char * in_) componentSubType = getOSType(cplugin); componentManufacturer = getOSType(cplugin + 4); - if ((componentManufacturer == 'rolD' || componentManufacturer == 'RoCl') && componentSubType == 'Sc55') - { - const char * plugin_path = "/Library/Audio/Plug-Ins/Components/SOUND Canvas VA.component/Contents/Resources/SCCore00.dylib"; - - if (!dlopen_preflight(plugin_path)) - return NO; - - SCPlayer * scplayer = new SCPlayer; - - SCPlayer::sc_mode mode = SCPlayer::sc_sc55; - NSString * flavor = [[NSUserDefaults standardUserDefaults] stringForKey:@"midi.flavor"]; - if ([flavor isEqualToString:@"default"]) - mode = SCPlayer::sc_default; - else if ([flavor isEqualToString:@"gm"]) - mode = SCPlayer::sc_gm; - else if ([flavor isEqualToString:@"gm2"]) - mode = SCPlayer::sc_gm2; - else if ([flavor isEqualToString:@"sc55"]) - mode = SCPlayer::sc_sc55; - else if ([flavor isEqualToString:@"sc88"]) - mode = SCPlayer::sc_sc88; - else if ([flavor isEqualToString:@"sc88pro"]) - mode = SCPlayer::sc_sc88pro; - else if ([flavor isEqualToString:@"sc8850"]) - mode = SCPlayer::sc_sc8850; - else if ([flavor isEqualToString:@"xg"]) - mode = SCPlayer::sc_xg; - - scplayer->set_sccore_path(plugin_path); - scplayer->set_mode( mode ); - scplayer->setSampleRate( 44100 ); - - player = scplayer; - } - else { auplayer = new AUPlayer; @@ -263,6 +247,8 @@ static OSType getOSType(const char * in_) } } + player->setFilterMode( mode ); + unsigned int loop_mode = framesFade ? MIDIPlayer::loop_mode_enable | MIDIPlayer::loop_mode_force : 0; unsigned int clean_flags = midi_container::clean_flag_emidi; @@ -284,7 +270,7 @@ static OSType getOSType(const char * in_) return -1; } - player->SetLoopMode((repeatone || isLooped) ? (MIDIPlayer::loop_mode_enable | MIDIPlayer::loop_mode_force) : 0); + player->setLoopMode((repeatone || isLooped) ? (MIDIPlayer::loop_mode_enable | MIDIPlayer::loop_mode_force) : 0); if ( !repeatone && framesRead >= localTotalFrames ) return 0; @@ -302,8 +288,12 @@ static OSType getOSType(const char * in_) soundFontsAssigned = YES; } - if ( player->Play( (float *) buf, frames ) < frames ) - return -1; + UInt32 frames_done = player->Play( (float *) buf, frames ); + + if ( !frames_done ) + return 0; + + frames = frames_done; if ( !repeatone && framesRead + frames > localFramesLength ) { if ( framesFade ) { diff --git a/Plugins/MIDI/MIDI/MIDIPlayer.cpp b/Plugins/MIDI/MIDI/MIDIPlayer.cpp index 922114fd3..0e24a1b3e 100644 --- a/Plugins/MIDI/MIDI/MIDIPlayer.cpp +++ b/Plugins/MIDI/MIDI/MIDIPlayer.cpp @@ -9,6 +9,7 @@ MIDIPlayer::MIDIPlayer() uTimeCurrent = 0; uTimeEnd = 0; uTimeLoopStart = 0; + initialized = false; } void MIDIPlayer::setSampleRate(unsigned long rate) @@ -130,15 +131,28 @@ unsigned long MIDIPlayer::Play(float * out, unsigned long count) if ( !startup() ) return 0; unsigned long done = 0; + + unsigned int needs_block_size = send_event_needs_time(); + unsigned int into_block = 0; + + // This should be a multiple of block size, and have leftover - if ( uSamplesRemaining ) + while ( uSamplesRemaining ) { unsigned long todo = uSamplesRemaining; if (todo > count) todo = count; + if (needs_block_size && todo > needs_block_size) + todo = needs_block_size; + if (todo < needs_block_size) + { + uSamplesRemaining = 0; + into_block = todo; + break; + } render( out, todo ); uSamplesRemaining -= todo; done += todo; - uTimeCurrent += todo; + uTimeCurrent += todo; } while (done < count) @@ -165,42 +179,71 @@ unsigned long MIDIPlayer::Play(float * out, unsigned long count) uSamplesRemaining = samples_todo - ( count - done ); samples_todo = count - done; } - render( out + done * 2, samples_todo ); - done += samples_todo; + if (!needs_block_size && samples_todo) + { + render( out + done * 2, samples_todo ); + done += samples_todo; + uTimeCurrent += samples_todo; + } if ( uSamplesRemaining ) { - uTimeCurrent = me->m_timestamp; + uSamplesRemaining += into_block; return done; } } - send_event( me->m_event ); + if (needs_block_size) + { + into_block += samples_todo; + while (into_block >= needs_block_size) + { + render( out + done * 2, needs_block_size ); + done += needs_block_size; + into_block -= needs_block_size; + uTimeCurrent += needs_block_size; + } + send_event_time_filtered( me->m_event, into_block ); + } + else + send_event_filtered( me->m_event ); uTimeCurrent = me->m_timestamp; } } - if ( done < count ) - { - unsigned long samples_todo; - if ( uStreamPosition < mStream.size() ) samples_todo = mStream[uStreamPosition].m_timestamp; - else samples_todo = uTimeEnd; - samples_todo -= uTimeCurrent; - if ( samples_todo > count - done ) samples_todo = count - done; - render( out + done * 2, samples_todo ); - done += samples_todo; - } + if ( done < count ) + { + unsigned long samples_todo; + if ( uStreamPosition < mStream.size() ) samples_todo = +mStream[uStreamPosition].m_timestamp; + else samples_todo = uTimeEnd; + samples_todo -= uTimeCurrent; + if ( samples_todo > count - done ) samples_todo = count +- done; + if ( needs_block_size && samples_todo > needs_block_size ) + samples_todo = needs_block_size; + if ( samples_todo >= needs_block_size ) + { + render( out + done * 2, samples_todo ); + done += samples_todo; + uTimeCurrent += samples_todo; + } + } + + if (!needs_block_size) + uTimeCurrent = time_target; - uTimeCurrent = time_target; - - if (uTimeCurrent >= uTimeEnd) + if (time_target >= uTimeEnd) { if ( uStreamPosition < mStream.size() ) { for (; uStreamPosition < mStream.size(); uStreamPosition++) { - send_event( mStream[ uStreamPosition ].m_event ); + if ( needs_block_size ) + send_event_time_filtered( mStream[ uStreamPosition ].m_event, into_block ); + else + send_event_filtered( mStream[ uStreamPosition ].m_event ); } } @@ -219,7 +262,9 @@ unsigned long MIDIPlayer::Play(float * out, unsigned long count) } else break; } - } + } + + uSamplesRemaining = into_block; return done; } @@ -292,22 +337,51 @@ void MIDIPlayer::Seek(unsigned long sample) } } - float temp[32]; - bool needs_time = send_event_needs_time(); + float * temp; + unsigned int needs_time = send_event_needs_time(); - for (i = 0; i < stream_start; i++) - { - if (me[i].m_event) + if (needs_time) + { + temp = (float *) malloc(needs_time * 2 * sizeof(float)); + if (temp) { - send_event(me[i].m_event); - if (needs_time) - render(temp, 16); + unsigned int render_junk = 0; + for (i = 0; i < stream_start; i++) + { + if (me[i].m_event) + { + send_event_time_filtered(me[i].m_event, render_junk); + render_junk += 16; + if (render_junk >= needs_time) + { + render(temp, needs_time); + render_junk -= needs_time; + } + } + } + uSamplesRemaining = render_junk; + free(temp); } - } + } + else + { + temp = (float *) malloc(16 * 2 * sizeof(float)); + if (temp) + { + for (i = 0; i < stream_start; i++) + { + if (me[i].m_event) + { + send_event_filtered(me[i].m_event); + } + } + free(temp); + } + } } } -void MIDIPlayer::SetLoopMode(unsigned int mode) +void MIDIPlayer::setLoopMode(unsigned int mode) { if (uLoopMode != mode) { @@ -318,3 +392,247 @@ void MIDIPlayer::SetLoopMode(unsigned int mode) } uLoopMode = mode; } + +void MIDIPlayer::send_event_filtered(uint32_t b) +{ + if (!(b & 0x80000000u)) + { + send_event(b); + } + else + { + unsigned int p_index = b & 0xffffff; + const uint8_t * p_data; + size_t p_size, p_port; + mSysexMap.get_entry(p_index, p_data, p_size, p_port); + send_sysex_filtered(p_data, p_size, p_port); + } +} + +void MIDIPlayer::send_event_time_filtered(uint32_t b, unsigned int time) +{ + if (!(b & 0x80000000u)) + { + send_event_time(b, time); + } + else + { + unsigned int p_index = b & 0xffffff; + const uint8_t * p_data; + size_t p_size, p_port; + mSysexMap.get_entry(p_index, p_data, p_size, p_port); + send_sysex_time_filtered(p_data, p_size, p_port, time); + } +} + +void MIDIPlayer::setFilterMode(filter_mode m) +{ + mode = m; + if (initialized) + { + sysex_reset(0, 0); + sysex_reset(1, 0); + sysex_reset(2, 0); + } +} + +static const uint8_t syx_reset_gm[] = { 0xF0, 0x7E, 0x7F, 0x09, 0x01, 0xF7 }; +static const uint8_t syx_reset_gm2[] = { 0xF0, 0x7E, 0x7F, 0x09, 0x03, 0xF7 }; +static const uint8_t syx_reset_gs[] = { 0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7 }; +static const uint8_t syx_reset_xg[] = { 0xF0, 0x43, 0x10, 0x4C, 0x00, 0x00, 0x7E, 0x00, 0xF7 }; + +static const uint8_t syx_gs_limit_bank_lsb[] = { 0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x41, 0x00, 0x03, 0x00, 0xF7 }; + +static bool syx_equal(const uint8_t * a, const uint8_t * b) +{ + while (*a != 0xF7 && *b != 0xF7 && *a == *b) + { + a++; b++; + } + + return *a == *b; +} + +static bool syx_is_reset(const uint8_t * data) +{ + return syx_equal(data, syx_reset_gm) || syx_equal(data, syx_reset_gm2) || syx_equal(data, syx_reset_gs) || syx_equal(data, syx_reset_xg); +} + +void MIDIPlayer::sysex_send_gs(size_t port, uint8_t * data, size_t size, unsigned int time) +{ + unsigned long i; + unsigned char checksum = 0; + for (i = 5; i + 1 < size && data[i+1] != 0xF7; ++i) + checksum += data[i]; + checksum = (128 - checksum) & 127; + data[i] = checksum; + if (time) + send_sysex_time(data, size, port, time); + else + send_sysex(data, size, port); +} + +void MIDIPlayer::sysex_reset_sc(uint32_t port, unsigned int time) +{ + unsigned int i; + uint8_t message[11]; + + memcpy(message, syx_gs_limit_bank_lsb, 11); + + message[7] = 1; + + switch (mode) + { + default: break; + + case filter_sc55: + message[8] = 1; + break; + + case filter_sc88: + message[8] = 2; + break; + + case filter_sc88pro: + message[8] = 3; + break; + + case filter_sc8850: + case filter_default: + message[8] = 4; + break; + } + + for (i = 0x41; i <= 0x49; ++i) + { + message[6] = i; + sysex_send_gs(port, message, sizeof(message), time); + } + message[6] = 0x40; + sysex_send_gs(port, message, sizeof(message), time); + for (i = 0x4A; i <= 0x4F; ++i) + { + message[6] = i; + sysex_send_gs(port, message, sizeof(message), time); + } +} + +void MIDIPlayer::sysex_reset(size_t port, unsigned int time) +{ + if (initialized) + { + if (time) + { + send_sysex_time(syx_reset_xg, sizeof(syx_reset_xg), port, time); + send_sysex_time(syx_reset_gm2, sizeof(syx_reset_gm2), port, time); + send_sysex_time(syx_reset_gm, sizeof(syx_reset_gm), port, time); + } + else + { + send_sysex(syx_reset_xg, sizeof(syx_reset_xg), port); + send_sysex(syx_reset_gm2, sizeof(syx_reset_gm2), port); + send_sysex(syx_reset_gm, sizeof(syx_reset_gm), port); + } + + switch (mode) + { + case filter_gm: + /* + if (time) + send_sysex_time(syx_reset_gm, sizeof(syx_reset_gm), port, time); + else + send_sysex(syx_reset_gm, sizeof(syx_reset_gm), port); + */ + break; + + case filter_gm2: + if (time) + send_sysex_time(syx_reset_gm2, sizeof(syx_reset_gm2), port, time); + else + send_sysex(syx_reset_gm2, sizeof(syx_reset_gm2), port); + break; + + case filter_sc55: + case filter_sc88: + case filter_sc88pro: + case filter_sc8850: + case filter_default: + if (time) + send_sysex_time(syx_reset_gs, sizeof(syx_reset_gs), port, time); + else + send_sysex(syx_reset_gs, sizeof(syx_reset_gs), port); + sysex_reset_sc(port, time); + break; + + case filter_xg: + if (time) + send_sysex_time(syx_reset_xg, sizeof(syx_reset_xg), port, time); + else + send_sysex(syx_reset_xg, sizeof(syx_reset_xg), port); + break; + } + + { + unsigned int i; + for (i = 0; i < 16; ++i) + { + if (time) + { + send_event_time(0x78B0 + i + (port << 24), time); + send_event_time(0x79B0 + i + (port << 24), time); + if (mode != filter_xg || i != 9) + { + send_event_time(0x20B0 + i + (port << 24), time); + send_event_time(0x00B0 + i + (port << 24), time); + send_event_time(0xC0 + i + (port << 24), time); + } + } + else + { + send_event(0x78B0 + i + (port << 24)); + send_event(0x79B0 + i + (port << 24)); + if (mode != filter_xg || i != 9) + { + send_event(0x20B0 + i + (port << 24)); + send_event(0x00B0 + i + (port << 24)); + send_event(0xC0 + i + (port << 24)); + } + } + } + } + + if (mode == filter_xg) + { + if (time) + { + send_event_time(0x20B9 + (port << 24), time); + send_event_time(0x7F00B9 + (port << 24), time); + send_event_time(0xC9 + (port << 24), time); + } + else + { + send_event(0x20B9 + (port << 24)); + send_event(0x7F00B9 + (port << 24)); + send_event(0xC9 + (port << 24)); + } + } + } +} + +void MIDIPlayer::send_sysex_filtered(const uint8_t *data, size_t size, size_t port) +{ + send_sysex(data, size, port); + if (syx_is_reset(data) && mode != filter_default) + { + sysex_reset(port, 0); + } +} + +void MIDIPlayer::send_sysex_time_filtered(const uint8_t *data, size_t size, size_t port, unsigned int time) +{ + send_sysex_time(data, size, port, time); + if (syx_is_reset(data) && mode != filter_default) + { + sysex_reset(port, time); + } +} diff --git a/Plugins/MIDI/MIDI/MIDIPlayer.h b/Plugins/MIDI/MIDI/MIDIPlayer.h index 1750f5d0c..c2f25353a 100644 --- a/Plugins/MIDI/MIDI/MIDIPlayer.h +++ b/Plugins/MIDI/MIDI/MIDIPlayer.h @@ -12,6 +12,19 @@ public: loop_mode_force = 1 << 1 }; + typedef enum + { + filter_default = 0, + filter_gm, + filter_gm2, + filter_sc55, + filter_sc88, + filter_sc88pro, + filter_sc8850, + filter_xg + } + filter_mode; + // zero variables MIDIPlayer(); @@ -20,28 +33,46 @@ public: // setup void setSampleRate(unsigned long rate); - void SetLoopMode(unsigned int mode); + void setLoopMode(unsigned int mode); + void setFilterMode(filter_mode m); bool Load(const midi_container & midi_file, unsigned subsong, unsigned loop_mode, unsigned clean_flags); unsigned long Play(float * out, unsigned long count); void Seek(unsigned long sample); protected: - virtual bool send_event_needs_time() { return false; } + // this should return the block size that the renderer expects, otherwise 0 + virtual unsigned int send_event_needs_time() { return 0; } virtual void send_event(uint32_t b) {} + virtual void send_sysex(const uint8_t * event, size_t size, size_t port) {}; virtual void render(float * out, unsigned long count) {} virtual void shutdown() {}; virtual bool startup() {return false;} + + // time should only be block level offset + virtual void send_event_time(uint32_t b, unsigned int time) {}; + virtual void send_sysex_time(const uint8_t * event, size_t size, size_t port, unsigned int time) {}; unsigned long uSampleRate; system_exclusive_table mSysexMap; + bool initialized; + filter_mode mode; private: + void send_event_filtered(uint32_t b); + void send_sysex_filtered(const uint8_t * event, size_t size, size_t port); + void send_event_time_filtered(uint32_t b, unsigned int time); + void send_sysex_time_filtered(const uint8_t * event, size_t size, size_t port, unsigned int time); + + void sysex_reset(size_t port, unsigned int time); + void sysex_send_gs(size_t port, uint8_t * data, size_t size, unsigned int time); + void sysex_reset_sc(uint32_t port, unsigned int time); + unsigned long uSamplesRemaining; unsigned uLoopMode; - + std::vector mStream; unsigned long uStreamPosition; diff --git a/Plugins/MIDI/MIDI/MSPlayer.cpp b/Plugins/MIDI/MIDI/MSPlayer.cpp index ad8685029..4ec350afa 100644 --- a/Plugins/MIDI/MIDI/MSPlayer.cpp +++ b/Plugins/MIDI/MIDI/MSPlayer.cpp @@ -33,10 +33,11 @@ void MSPlayer::set_extp(unsigned int extp) void MSPlayer::send_event(uint32_t b) { - if (!(b & 0x80000000)) - { - synth->midi_write(b); - } + synth->midi_write(b); +} + +void MSPlayer::send_sysex(const uint8_t * data, size_t size, size_t port) +{ } void MSPlayer::render(float * out, unsigned long count) @@ -60,6 +61,7 @@ void MSPlayer::shutdown() { delete synth; synth = 0; + initialized = false; } bool MSPlayer::startup() @@ -83,6 +85,10 @@ bool MSPlayer::startup() if (!synth->midi_init((unsigned int)uSampleRate, bank_id, extp)) return false; + initialized = true; + + setFilterMode(mode); + return true; } diff --git a/Plugins/MIDI/MIDI/MSPlayer.h b/Plugins/MIDI/MIDI/MSPlayer.h index 3a51e2a34..c5c65d2e1 100644 --- a/Plugins/MIDI/MIDI/MSPlayer.h +++ b/Plugins/MIDI/MIDI/MSPlayer.h @@ -26,6 +26,7 @@ public: protected: virtual void send_event(uint32_t b); + virtual void send_sysex(const uint8_t * data, size_t size, size_t port); virtual void render(float * out, unsigned long count); virtual void shutdown(); diff --git a/Plugins/MIDI/MIDI/SCPlayer.cpp b/Plugins/MIDI/MIDI/SCPlayer.cpp index 2b8cfa348..0dc82885f 100644 --- a/Plugins/MIDI/MIDI/SCPlayer.cpp +++ b/Plugins/MIDI/MIDI/SCPlayer.cpp @@ -7,6 +7,8 @@ #include "SCPlayer.h" +#define BLOCK_SIZE (512) + // YAY! OS X doesn't unload dylibs on dlclose, so we cache up to two sets of instances here static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; @@ -14,7 +16,7 @@ static const unsigned int g_max_instances = 2; static std::vector g_instances_open; static SCCore g_sampler[3 * g_max_instances]; -SCPlayer::SCPlayer() : MIDIPlayer(), initialized(false), mode(sc_default), sccore_path(0) +SCPlayer::SCPlayer() : MIDIPlayer(), initialized(false), sccore_path(0) { pthread_mutex_lock(&g_lock); while (g_instances_open.size() >= g_max_instances) @@ -49,180 +51,6 @@ SCPlayer::~SCPlayer() } } -static const uint8_t syx_reset_gm[] = { 0xF0, 0x7E, 0x7F, 0x09, 0x01, 0xF7 }; -static const uint8_t syx_reset_gm2[] = { 0xF0, 0x7E, 0x7F, 0x09, 0x03, 0xF7 }; -static const uint8_t syx_reset_gs[] = { 0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7 }; -static const uint8_t syx_reset_xg[] = { 0xF0, 0x43, 0x10, 0x4C, 0x00, 0x00, 0x7E, 0x00, 0xF7 }; - -static const uint8_t syx_gs_limit_bank_lsb[] = { 0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x41, 0x00, 0x03, 0x00, 0xF7 }; - -static bool syx_equal(const uint8_t * a, const uint8_t * b) -{ - while (*a != 0xF7 && *b != 0xF7 && *a == *b) - { - a++; b++; - } - - return *a == *b; -} - -static bool syx_is_reset(const uint8_t * data) -{ - return syx_equal(data, syx_reset_gm) || syx_equal(data, syx_reset_gm2) || syx_equal(data, syx_reset_gs) || syx_equal(data, syx_reset_xg); -} - -void SCPlayer::send_sysex(uint32_t port, const uint8_t * data) -{ - sampler[port].TG_LongMidiIn( data, 0 ); - if (syx_is_reset(data) && mode != sc_default) - { - reset(port); - } -} - -void SCPlayer::send_gs(uint32_t port, uint8_t * data) -{ - unsigned long i; - unsigned char checksum = 0; - for (i = 5; data[i+1] != 0xF7; ++i) - checksum += data[i]; - checksum = (128 - checksum) & 127; - data[i] = checksum; - sampler[port].TG_LongMidiIn( data, 0 ); -} - -void SCPlayer::reset_sc(uint32_t port) -{ - unsigned int i; - uint8_t message[11]; - - memcpy(message, syx_gs_limit_bank_lsb, 11); - - message[7] = 1; - - switch (mode) - { - default: break; - - case sc_sc55: - message[8] = 1; - break; - - case sc_sc88: - message[8] = 2; - break; - - case sc_sc88pro: - message[8] = 3; - break; - - case sc_sc8850: - case sc_default: - message[8] = 4; - break; - } - - for (i = 0x41; i <= 0x49; ++i) - { - message[6] = i; - send_gs(port, message); - } - message[6] = 0x40; - send_gs(port, message); - for (i = 0x4A; i <= 0x4F; ++i) - { - message[6] = i; - send_gs(port, message); - } -} - -void SCPlayer::reset(uint32_t port) -{ - if (initialized) - { - sampler[port].TG_LongMidiIn(syx_reset_xg, 0); junk(port, 1024); - sampler[port].TG_LongMidiIn(syx_reset_gm2, 0); junk(port, 1024); - sampler[port].TG_LongMidiIn(syx_reset_gm, 0); junk(port, 1024); - - switch (mode) - { - case sc_gm: - /*sampler[port].TG_LongMidiIn( syx_reset_gm, 0 );*/ - break; - - case sc_gm2: - sampler[port].TG_LongMidiIn( syx_reset_gm2, 0 ); - break; - - case sc_sc55: - case sc_sc88: - case sc_sc88pro: - case sc_sc8850: - case sc_default: - sampler[port].TG_LongMidiIn( syx_reset_gs, 0 ); junk(port, 1024); - reset_sc(port); - break; - - case sc_xg: - sampler[port].TG_LongMidiIn( syx_reset_xg, 0 ); - break; - } - - junk(port, 1024); - - { - unsigned int i; - for (i = 0; i < 16; ++i) - { - sampler[port].TG_ShortMidiIn(0x78B0 + i, 0); - sampler[port].TG_ShortMidiIn(0x79B0 + i, 0); - if (mode != sc_xg || i != 9) - { - sampler[port].TG_ShortMidiIn(0x20B0 + i, 0); - sampler[port].TG_ShortMidiIn(0x00B0 + i, 0); - sampler[port].TG_ShortMidiIn(0xC0 + i, 0); - } - } - } - - if (mode == sc_xg) - { - sampler[port].TG_ShortMidiIn(0x20B9, 0); - sampler[port].TG_ShortMidiIn(0x7F00B9, 0); - sampler[port].TG_ShortMidiIn(0xC9, 0); - } - - junk(port, uSampleRate * 2 / 3); - } -} - -void SCPlayer::junk(uint32_t port, unsigned long count) -{ - float temp[2][1024]; - unsigned long i, j; - for (i = 0, j = count / 1024; i < j; ++i) - { - memset(temp, 0, sizeof(temp)); - sampler[port].TG_setInterruptThreadIdAtThisTime(); - sampler[port].TG_Process(temp[0], temp[1], 1024); - } - count %= 1024; - if (count) - { - memset(temp, 0, sizeof(temp)); - sampler[port].TG_setInterruptThreadIdAtThisTime(); - sampler[port].TG_Process(temp[0], temp[1], (unsigned int) count); - } -} - -void SCPlayer::set_mode(sc_mode m) -{ - mode = m; - reset(0); - reset(1); - reset(2); -} - void SCPlayer::set_sccore_path(const char *path) { size_t len; @@ -235,26 +63,30 @@ void SCPlayer::set_sccore_path(const char *path) void SCPlayer::send_event(uint32_t b) { - if (!(b & 0x80000000)) - { - unsigned port = (b >> 24) & 0x7F; - if ( port > 2 ) port = 2; - sampler[port].TG_ShortMidiIn(b, 0); - } - 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; - send_sysex( (uint32_t) port, data ); - if ( port == 0 ) - { - send_sysex( 1, data ); - send_sysex( 2, data ); - } - } + send_event_time(b, 0); +} + +void SCPlayer::send_sysex(const uint8_t * data, size_t size, size_t port) +{ + send_sysex_time(data, size, port, 0); +} + +void SCPlayer::send_event_time(uint32_t b, unsigned int time) +{ + unsigned port = (b >> 24) & 0x7F; + if ( port > 2 ) port = 0; + sampler[port].TG_ShortMidiIn(b, time); +} + +void SCPlayer::send_sysex_time(const uint8_t * data, size_t size, size_t port, unsigned int time) +{ + if ( port > 2 ) port = 0; + sampler[port].TG_LongMidiIn(data, time); + if (port == 0) + { + sampler[1].TG_LongMidiIn(data, time); + sampler[2].TG_LongMidiIn(data, time); + } } void SCPlayer::render(float * out, unsigned long count) @@ -262,8 +94,8 @@ void SCPlayer::render(float * out, unsigned long count) memset(out, 0, count * sizeof(float) * 2); while (count) { - float buffer[2][4096]; - unsigned long todo = count > 4096 ? 4096 : count; + float buffer[2][BLOCK_SIZE]; + unsigned long todo = count > BLOCK_SIZE ? BLOCK_SIZE : count; for (unsigned long i = 0; i < 3; ++i) { memset(buffer[0], 0, todo * sizeof(float)); @@ -319,14 +151,14 @@ bool SCPlayer::startup() sampler[i].TG_setMaxBlockSize(256); sampler[i].TG_setSampleRate((float)uSampleRate); sampler[i].TG_setSampleRate((float)uSampleRate); - sampler[i].TG_setMaxBlockSize(4096); + sampler[i].TG_setMaxBlockSize(BLOCK_SIZE); } initialized = true; for (int i = 0; i < 3; i++) { - reset(i); + reset(i, 0); } return true; @@ -346,7 +178,7 @@ unsigned int SCPlayer::get_playing_note_count() return total; } -bool SCPlayer::send_event_needs_time() +unsigned int SCPlayer::send_event_needs_time() { - return true; + return BLOCK_SIZE; } diff --git a/Plugins/MIDI/MIDI/SCPlayer.h b/Plugins/MIDI/MIDI/SCPlayer.h index e771dd816..d6f9d47f2 100644 --- a/Plugins/MIDI/MIDI/SCPlayer.h +++ b/Plugins/MIDI/MIDI/SCPlayer.h @@ -16,46 +16,25 @@ public: unsigned int get_playing_note_count(); - typedef enum - { - sc_default = 0, - sc_gm, - sc_gm2, - sc_sc55, - sc_sc88, - sc_sc88pro, - sc_sc8850, - sc_xg - } - sc_mode; - - void set_mode(sc_mode m); - void set_sccore_path(const char * path); protected: - virtual bool send_event_needs_time(); + virtual unsigned int send_event_needs_time(); virtual void send_event(uint32_t b); + virtual void send_sysex(const uint8_t * data, size_t size, size_t port); virtual void render(float * out, unsigned long count); virtual void shutdown(); virtual bool startup(); -private: - void send_sysex(uint32_t port, const uint8_t * data); - void send_gs(uint32_t port, uint8_t * data); - void reset_sc(uint32_t port); - - void reset(uint32_t port); - - void junk(uint32_t port, unsigned long count); + virtual void send_event_time(uint32_t b, unsigned int time); + virtual void send_sysex_time(const uint8_t * data, size_t size, size_t port, unsigned int time); +private: unsigned int instance_id; bool initialized; SCCore * sampler; - sc_mode mode; - char * sccore_path; }; diff --git a/Plugins/MIDI/MIDI/SFPlayer.cpp b/Plugins/MIDI/MIDI/SFPlayer.cpp index de3933d55..8d9082889 100644 --- a/Plugins/MIDI/MIDI/SFPlayer.cpp +++ b/Plugins/MIDI/MIDI/SFPlayer.cpp @@ -56,58 +56,52 @@ void SFPlayer::setDynamicLoading(bool enabled) void SFPlayer::send_event(uint32_t b) { - if (!(b & 0x80000000)) + int param2 = (b >> 16) & 0xFF; + int param1 = (b >> 8) & 0xFF; + int cmd = b & 0xF0; + int chan = b & 0x0F; + int port = (b >> 24) & 0x7F; + fluid_synth_t* _synth = this->_synth[0]; + + if ( port && port < 3 ) + _synth = this->_synth[port]; + + switch (cmd) { - int param2 = (b >> 16) & 0xFF; - int param1 = (b >> 8) & 0xFF; - int cmd = b & 0xF0; - int chan = b & 0x0F; - int port = (b >> 24) & 0x7F; - fluid_synth_t* _synth = this->_synth[0]; - - if ( port && port < 3 ) - _synth = this->_synth[port]; - - switch (cmd) - { - case 0x80: - fluid_synth_noteoff(_synth, chan, param1); - break; - case 0x90: - fluid_synth_noteon(_synth, chan, param1, param2); - break; - case 0xA0: - break; - case 0xB0: - fluid_synth_cc(_synth, chan, param1, param2); - break; - case 0xC0: - fluid_synth_program_change(_synth, chan, param1); - break; - case 0xD0: - fluid_synth_channel_pressure(_synth, chan, param1); - break; - case 0xE0: - fluid_synth_pitch_bend(_synth, chan, (param2 << 7) | param1); - break; - } + case 0x80: + fluid_synth_noteoff(_synth, chan, param1); + break; + case 0x90: + fluid_synth_noteon(_synth, chan, param1, param2); + break; + case 0xA0: + break; + case 0xB0: + fluid_synth_cc(_synth, chan, param1, param2); + break; + case 0xC0: + fluid_synth_program_change(_synth, chan, param1); + break; + case 0xD0: + fluid_synth_channel_pressure(_synth, chan, param1); + break; + case 0xE0: + fluid_synth_pitch_bend(_synth, chan, (param2 << 7) | param1); + break; } - else +} + +void SFPlayer::send_sysex(const uint8_t *data, size_t size, size_t port) +{ + if (port >= 3) + port = 0; + if (data && size > 2 && data[0] == 0xF0 && data[size-1] == 0xF7) { - uint32_t n = b & 0xffffff; - const uint8_t * data; - size_t size, port; - mSysexMap.get_entry( n, data, size, port ); - if (port >= 3) - port = 0; - if (data && size > 2 && data[0] == 0xF0 && data[size-1] == 0xF7) - { - ++data; - size -= 2; - fluid_synth_sysex(_synth[0], (const char *)data, size, NULL, NULL, NULL, 0); - fluid_synth_sysex(_synth[1], (const char *)data, size, NULL, NULL, NULL, 0); - fluid_synth_sysex(_synth[2], (const char *)data, size, NULL, NULL, NULL, 0); - } + ++data; + size -= 2; + fluid_synth_sysex(_synth[0], (const char *)data, size, NULL, NULL, NULL, 0); + fluid_synth_sysex(_synth[1], (const char *)data, size, NULL, NULL, NULL, 0); + fluid_synth_sysex(_synth[2], (const char *)data, size, NULL, NULL, NULL, 0); } } @@ -155,6 +149,7 @@ void SFPlayer::shutdown() if (_synth[i]) delete_fluid_synth(_synth[i]); _synth[i] = 0; } + initialized = false; } bool SFPlayer::startup() @@ -257,6 +252,10 @@ bool SFPlayer::startup() } _last_error = ""; + + initialized = true; + + setFilterMode(mode); return true; } diff --git a/Plugins/MIDI/MIDI/SFPlayer.h b/Plugins/MIDI/MIDI/SFPlayer.h index 8390df454..4801cdf97 100644 --- a/Plugins/MIDI/MIDI/SFPlayer.h +++ b/Plugins/MIDI/MIDI/SFPlayer.h @@ -32,12 +32,13 @@ public: private: virtual void send_event(uint32_t b); + virtual void send_sysex(const uint8_t * data, size_t size, size_t port); virtual void render(float * out, unsigned long count); virtual void shutdown(); virtual bool startup(); - std::string _last_error; + std::string _last_error; fluid_settings_t * _settings[3]; fluid_synth_t * _synth[3]; diff --git a/Preferences/Preferences/Base.lproj/Preferences.xib b/Preferences/Preferences/Base.lproj/Preferences.xib index 4a8f7e223..4f42e34aa 100644 --- a/Preferences/Preferences/Base.lproj/Preferences.xib +++ b/Preferences/Preferences/Base.lproj/Preferences.xib @@ -1,7 +1,8 @@ - + - + + @@ -326,6 +327,7 @@ name url + @@ -333,6 +335,7 @@ slug preference + @@ -340,6 +343,7 @@ slug preference + @@ -531,7 +535,7 @@ - + @@ -547,11 +551,6 @@ - - - MIDIPluginFlavorTransformer - - @@ -584,6 +583,7 @@ slug preference + @@ -591,6 +591,7 @@ slug preference + @@ -598,6 +599,7 @@ slug preference + diff --git a/Preferences/Preferences/GeneralPreferencesPlugin.m b/Preferences/Preferences/GeneralPreferencesPlugin.m index 3f2a6af93..5f01b1d05 100644 --- a/Preferences/Preferences/GeneralPreferencesPlugin.m +++ b/Preferences/Preferences/GeneralPreferencesPlugin.m @@ -8,7 +8,6 @@ #import "GeneralPreferencesPlugin.h" #import "PathToFileTransformer.h" -#import "MIDIPluginFlavorTransformer.h" @implementation GeneralPreferencesPlugin @@ -17,9 +16,6 @@ NSValueTransformer *pathToFileTransformer = [[PathToFileTransformer alloc] init]; [NSValueTransformer setValueTransformer:pathToFileTransformer forName:@"PathToFileTransformer"]; - NSValueTransformer *midiPluginFlavorTransformer = [[MIDIPluginFlavorTransformer alloc] init]; - [NSValueTransformer setValueTransformer:midiPluginFlavorTransformer - forName:@"MIDIPluginFlavorTransformer"]; } + (NSArray *)preferencePanes diff --git a/Preferences/Preferences/MIDIPane.m b/Preferences/Preferences/MIDIPane.m index d308fb1a0..4df9746bd 100644 --- a/Preferences/Preferences/MIDIPane.m +++ b/Preferences/Preferences/MIDIPane.m @@ -43,9 +43,6 @@ - (IBAction)setMidiPlugin:(id)sender { - NSString * plugin = [[NSUserDefaults standardUserDefaults] stringForKey:@"midi.plugin"]; - BOOL enabled = [plugin isEqualToString:@"Sc55rolD"] || [plugin isEqualToString:@"Sc55RoCl"]; - [midiFlavorControl setEnabled:enabled]; } @end diff --git a/Preferences/Preferences/Preferences.xcodeproj/project.pbxproj b/Preferences/Preferences/Preferences.xcodeproj/project.pbxproj index 982b7f541..3e7ec2945 100644 --- a/Preferences/Preferences/Preferences.xcodeproj/project.pbxproj +++ b/Preferences/Preferences/Preferences.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ 17E41DB80C130AA500AC744D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 17E41DB70C130AA500AC744D /* Localizable.strings */; }; 17E78A7E0D68BE3C005C5A59 /* file_tree.png in Resources */ = {isa = PBXBuildFile; fileRef = 17E78A7D0D68BE3C005C5A59 /* file_tree.png */; }; 17E78B6A0D68C1E3005C5A59 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17E78B680D68C1E3005C5A59 /* Preferences.xib */; }; + 83651DA527322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83651DA327322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m */; }; 836C314125EC8A7000692622 /* MASShortcut.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = ED69CBAE25BE32500090B90D /* MASShortcut.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 8372053718E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8372053618E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m */; }; 837C0D401C50954000CAE18F /* MIDIPluginBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 837C0D3F1C50954000CAE18F /* MIDIPluginBehaviorArrayController.m */; }; @@ -25,9 +26,7 @@ 8384917818084D9F00E7332D /* growl.png in Resources */ = {isa = PBXBuildFile; fileRef = 8384917618084D9F00E7332D /* growl.png */; }; 83B06729180D85B8008E3612 /* MIDIPane.m in Sources */ = {isa = PBXBuildFile; fileRef = 83B06728180D85B8008E3612 /* MIDIPane.m */; }; 83B0672B180D8B39008E3612 /* midi.png in Resources */ = {isa = PBXBuildFile; fileRef = 83B0672A180D8B39008E3612 /* midi.png */; }; - 83DFEA0B1CBC94DE00BCC565 /* MIDIFlavorBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83DFEA0A1CBC94DE00BCC565 /* MIDIFlavorBehaviorArrayController.m */; }; 83EF495F17FBC96A00642E3C /* VolumeBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83EF495E17FBC96A00642E3C /* VolumeBehaviorArrayController.m */; }; - 83F127AA1DEE47E90010CB8F /* MIDIPluginFlavorTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 83F127A81DEE47E90010CB8F /* MIDIPluginFlavorTransformer.m */; }; 83F27E6B1810DD3A00CEF538 /* appearance@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 83F27E651810DD3A00CEF538 /* appearance@2x.png */; }; 83F27E6C1810DD3A00CEF538 /* growl@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 83F27E661810DD3A00CEF538 /* growl@2x.png */; }; 83F27E6D1810DD3A00CEF538 /* lastfm@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 83F27E671810DD3A00CEF538 /* lastfm@2x.png */; }; @@ -114,6 +113,8 @@ 8347435F20E6D5A000063D45 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Preferences.strings; sourceTree = ""; }; 835C888922CC1880001B4B3F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 835C888A22CC1880001B4B3F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 83651DA327322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIDIFlavorBehaviorArrayController.m; sourceTree = ""; }; + 83651DA427322C8700A2C097 /* MIDIFlavorBehaviorArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIDIFlavorBehaviorArrayController.h; sourceTree = ""; }; 8372053518E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResamplerBehaviorArrayController.h; sourceTree = ""; }; 8372053618E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ResamplerBehaviorArrayController.m; sourceTree = ""; }; 837C0D3E1C50954000CAE18F /* MIDIPluginBehaviorArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIDIPluginBehaviorArrayController.h; sourceTree = ""; }; @@ -125,12 +126,8 @@ 83B06728180D85B8008E3612 /* MIDIPane.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIDIPane.m; sourceTree = ""; }; 83B0672A180D8B39008E3612 /* midi.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = midi.png; path = Icons/midi.png; sourceTree = ""; }; 83BC5AB320E4C90F00631CD4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/Preferences.xib; sourceTree = ""; }; - 83DFEA091CBC94DE00BCC565 /* MIDIFlavorBehaviorArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIDIFlavorBehaviorArrayController.h; sourceTree = ""; }; - 83DFEA0A1CBC94DE00BCC565 /* MIDIFlavorBehaviorArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIDIFlavorBehaviorArrayController.m; sourceTree = ""; }; 83EF495D17FBC96A00642E3C /* VolumeBehaviorArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VolumeBehaviorArrayController.h; sourceTree = ""; }; 83EF495E17FBC96A00642E3C /* VolumeBehaviorArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VolumeBehaviorArrayController.m; sourceTree = ""; }; - 83F127A81DEE47E90010CB8F /* MIDIPluginFlavorTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIDIPluginFlavorTransformer.m; sourceTree = ""; }; - 83F127A91DEE47E90010CB8F /* MIDIPluginFlavorTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIDIPluginFlavorTransformer.h; sourceTree = ""; }; 83F27E651810DD3A00CEF538 /* appearance@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "appearance@2x.png"; path = "Icons/appearance@2x.png"; sourceTree = ""; }; 83F27E661810DD3A00CEF538 /* growl@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "growl@2x.png"; path = "Icons/growl@2x.png"; sourceTree = ""; }; 83F27E671810DD3A00CEF538 /* lastfm@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "lastfm@2x.png"; path = "Icons/lastfm@2x.png"; sourceTree = ""; }; @@ -256,18 +253,18 @@ 17D503410ABDB1660022D1E8 /* Custom */ = { isa = PBXGroup; children = ( - 83DFEA091CBC94DE00BCC565 /* MIDIFlavorBehaviorArrayController.h */, - 83DFEA0A1CBC94DE00BCC565 /* MIDIFlavorBehaviorArrayController.m */, - 837C0D3E1C50954000CAE18F /* MIDIPluginBehaviorArrayController.h */, - 837C0D3F1C50954000CAE18F /* MIDIPluginBehaviorArrayController.m */, - 8372053518E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.h */, - 8372053618E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m */, 170744AB0BFF3938002475C9 /* AppcastArrayController.h */, 170744AC0BFF3938002475C9 /* AppcastArrayController.m */, + 83651DA427322C8700A2C097 /* MIDIFlavorBehaviorArrayController.h */, + 83651DA327322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m */, + 837C0D3E1C50954000CAE18F /* MIDIPluginBehaviorArrayController.h */, + 837C0D3F1C50954000CAE18F /* MIDIPluginBehaviorArrayController.m */, 17C643370B8A77CC00C53518 /* OutputsArrayController.h */, 17C643360B8A77CC00C53518 /* OutputsArrayController.m */, 99F1813D0DE01D7A00FD5FFB /* PlaylistBehaviorArrayController.h */, 99F1813E0DE01D7A00FD5FFB /* PlaylistBehaviorArrayController.m */, + 8372053518E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.h */, + 8372053618E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m */, 83EF495D17FBC96A00642E3C /* VolumeBehaviorArrayController.h */, 83EF495E17FBC96A00642E3C /* VolumeBehaviorArrayController.m */, ); @@ -304,8 +301,6 @@ 83F27E711810E41A00CEF538 /* Transformers */ = { isa = PBXGroup; children = ( - 83F127A81DEE47E90010CB8F /* MIDIPluginFlavorTransformer.m */, - 83F127A91DEE47E90010CB8F /* MIDIPluginFlavorTransformer.h */, 83F27E721810E45D00CEF538 /* PathToFileTransformer.h */, 83F27E731810E45D00CEF538 /* PathToFileTransformer.m */, ); @@ -376,7 +371,7 @@ LastUpgradeCheck = 1230; TargetAttributes = { 8D5B49AC048680CD000E48DA = { - DevelopmentTeam = ""; + DevelopmentTeam = N6E749HJ2X; ProvisioningStyle = Automatic; }; }; @@ -469,17 +464,16 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 83651DA527322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m in Sources */, 83B06729180D85B8008E3612 /* MIDIPane.m in Sources */, 8E07AA880AAC8EA200A4B32F /* HotKeyPane.m in Sources */, 83F27E741810E45D00CEF538 /* PathToFileTransformer.m in Sources */, 8E07AA890AAC8EA200A4B32F /* GeneralPreferencePane.m in Sources */, 8E07AA8A0AAC8EA200A4B32F /* GeneralPreferencesPlugin.m in Sources */, - 83DFEA0B1CBC94DE00BCC565 /* MIDIFlavorBehaviorArrayController.m in Sources */, 83EF495F17FBC96A00642E3C /* VolumeBehaviorArrayController.m in Sources */, 17C643380B8A77CC00C53518 /* OutputsArrayController.m in Sources */, 837C0D401C50954000CAE18F /* MIDIPluginBehaviorArrayController.m in Sources */, 17C6433F0B8A783F00C53518 /* OutputPane.m in Sources */, - 83F127AA1DEE47E90010CB8F /* MIDIPluginFlavorTransformer.m in Sources */, 170744AD0BFF3938002475C9 /* AppcastArrayController.m in Sources */, 99F1813F0DE01D7A00FD5FFB /* PlaylistBehaviorArrayController.m in Sources */, 8372053718E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m in Sources */,