petegoodliffe / pgmidi Goto Github PK
View Code? Open in Web Editor NEWPGMidi iOS MIDI library and example code
PGMidi iOS MIDI library and example code
I only need to use PGMidi in one part of my app, so I'd like to shut it down when I'm done using it.
I tweaked the enableNetwork method so that session.enabled is set to enabled, instead of YES, so I can call enableNetwork:NO. I also changed the connectionPolicy to MIDINetworkConnectionPolicy_NoOne when enabled=NO. But after I call enableNetwork:NO, the app still receives incoming MIDI messages. If I've released the PGMidi object, this causes a crash.
What else should I do when I'm finished using PGMidi?
There appears to be a memory leak in the example app code or the PGMidi library. I'm trying to port the example code to RubyMotion and the app is crashing when running on the device with 'EXC_CRASH (SIGABRT)' shown as the reason in the device log. According to SO, that crash code indicates a memory leak?
I'm brand new to iOS app development and unfortunately have no idea how to fix the issue. But I'm nervous to keep banging my head against the wall trying to get the example app ported to RubyMotion knowing that there's a possible bug. I'm not sure how severe the issue is or if it could be causing the EXC_CRASH crashes. Since I can't fix the issue, I've tried to do as much of the debugging footwork as possible for you.
Thanks so much for taking a look and for releasing PGMidi. I sure appreciate it!
I was able to hook up a wireless MIDI device to the simulator so I could reproduce the bug in a better debugging environment. Here is the output in the debugging panel when choosing 'Product -> Run':
objc[57951]: Object 0x8a94b30 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[57951]: Object 0x8a94e50 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[57951]: Object 0x688a390 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[57951]: Object 0x688c440 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
I also was able to get a backtrace on the leak by running the app with Instruments. Here is the leak backtrace:
# Address Category Event Type RefCt Timestamp Size Responsible Library Responsible Caller
0 0x6874150 CFString (immutable) Malloc 1 00:19.148.096 32 Foundation -[NSPlaceholderString initWithFormat:locale:arguments:]
1 0x6874150 CFString (immutable) Autorelease <null> 00:19.148.101 0 Foundation +[NSString stringWithFormat:]
2 0x6874150 CFString (immutable) CFRetain 2 00:19.148.131 0 MidiMonitor -[MidiMonitorViewController midiSource:midiReceived:]
3 0x6874150 CFString (immutable) CFRetain 3 00:19.148.135 0 Foundation -[NSObject(NSThreadPerformAdditions) performSelector:onThread:withObject:waitUntilDone:modes:]
4 0x6874150 CFString (immutable) CFRelease 2 00:19.148.147 0 MidiMonitor -[MidiMonitorViewController midiSource:midiReceived:]
5 0x6874150 CFString (immutable) CFRetain 3 00:19.149.480 0 MidiMonitor -[MidiMonitorViewController addString:]
6 0x6874150 CFString (immutable) CFRetain 4 00:19.149.513 0 Foundation -[NSPlaceholderString initWithFormat:locale:arguments:]
7 0x6874150 CFString (immutable) CFRelease 3 00:19.149.515 0 Foundation -[NSPlaceholderString initWithFormat:locale:arguments:]
8 0x6874150 CFString (immutable) CFRelease 2 00:19.150.312 0 MidiMonitor -[MidiMonitorViewController addString:]
9 0x6874150 CFString (immutable) CFRelease 1 00:19.150.315 0 GraphicsServices GSEventRunModal
The MIDIPacketListAdd() call in [PGMidi sendBytes:size:] always sends 0 as a timestamp. If you would send the actual time over here, this method is also suitable for sending midi clock signals.
So I'm wondering: Is there any reason you're sending 0 here or do you think it is a good idea to change this?
Cheers
Took a glance at the header file, did't find an interface to load & play an existing MIDI file. How could I do with it? Thanks.
If I lock my iPad (i.e. put it to sleep using the power button). After a short while, after awaking it, the MIDI interface is inoperable. The MIDI app does see the interface but send MIDI doesn't work at all.
This can create a retain loop between the delegate and PGMidi/PGMidiSource. Weak references should be used instead, per the iOS convention.
First of all, thanks so much for PGMidi, it helped me so much to get started with CoreMidi.
It would be awesome if you could add support for virtual MIDI ports. I've been trying to figure it out for days in my free time and I seem to come always closer but I just cant get it to work. I think other people would greatly benefit if PGMidi would support virtual as well out of the box.
-Luke
Need to cancel the sending of packets that were previously scheduled for future delivery.
Tried with this:
for (int i=0;i<midi.destinations.count;i++){
PGMidiDestination *destination = [[midi destinations] objectAtIndex:i];
[destination flushOutput];
}
Not working, then, I add these methods to PGMidi.mm
(void) flushOutput {
MIDIFlushOutput(0);
}
(void) flushOutput2
{
for (ItemCount index = 0; index < MIDIGetNumberOfDestinations(); ++index)
{
MIDIEndpointRef outputEndpoint = MIDIGetDestination(index);
if (outputEndpoint) {MIDIFlushOutput(outputEndpoint); }
}
}
Not working, the sended notes still playing after flush. Any ideas ?
PGMidi crashes when MIDI data is sent too quickly.
I'm connecting microKORG via iRig MIDI interface and as soon as first few clock signals are sent to PGMidi it crashes. Even if clock is disabled playing chords and notes quickly crashes it.
I've disabled ARC but that didn't help.
Any ideas?
https://github.com/petegoodliffe/PGMidi/blob/master/Sources/PGMidi/PGMidi.mm#L437
The assignment is useless, I suspect it should be
self.virtualDestinationEnabled = NO;
[edit] well actually I would even move this statement to the next line, or
self.virtualDestinationEnabled = virtualDestinationEnabled;
will never be affected.
[edit 2]
Ok it seems self.virtualDestinationEnabled is taken through an accessor which itself check if
-(BOOL)virtualDestinationEnabled
{
return virtualDestinationSource != nil;
}
so just no need for the line L437
Instead of searching for a bug in the MIDI framework I've been using for the last 2 years I thought it'd be a good idea to just rip off someone else's work to make money.
MidiMonitorAppDelegate.m line 23 contains
[window addSubview:viewController.view];
which doesn't work anymore. Please replace with
[window setRootViewController:viewController];
otherwise you will get
Assertion failure in -[UIApplication _runWithMainScene:transitionContext:completion:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3590.1/UIApplication.m:3676
2016-08-24 14:14:10.651022 MidiMonitor[1413:428747] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Application windows are expected to have a root view controller at the end of application launch'
*** First throw call stack:
(0x1b20c2a7 0x1a927097 0x1b20c181 0x1ba72e55 0x204d148b 0x204e3bb1 0x204ce375 0x1ca5fac3 0x1ca5f97d 0x1ca5fc67 0x1b1c8b63 0x1b1c866d 0x1b1c6943 0x1b117483 0x1b117291 0x202b909b 0x202b375f 0xe0c9b 0x1ad9650b)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
on a SIGABRT in the line 18 of the main int retVal = UIApplicationMain(argc, argv, nil, nil);
I added the full text just in case someone googles it
Hi Pete,
actually I'm not sure if this is really a problem in PGMidi or if it's somewhere else down the line, but maybe someone around here is able to help me out here: I'm using PGMidi in my app to connect to MIDI devices that are connected via USB and Bluetooth. When I connect with Bluetooth the iPad is usually the Central and connects to a Peripheral - upon connection all events are correctly triggered and I get a message that a new device has connected (same as with USB connections). So far PG Midi has really helped me out on a lot of stuff, I appreciate that you're publishing your code here!
Now I want to do the same with the iPad as a Peripheral controller to connect to another device acting as Central, but nothing happens (using CABTMIDILocalPeripheralViewController). The Central device sees the iPad which is advertising and can connect to it - but I can't find a way to see it on the iPad :( there's no event triggered as I would have expected it, also when I output the available devices there's nothing new showing up... guess I am missing something here?
PGMidi has strong references to PGMidiConnections. When compiled with ARC, PGMidiConnection has a strong reference back to PGMidi. Thus, neither are deallocated.
2016-02-12 16:48:24.804 MidiMonitor[88004:1246323] *** Assertion failure in -[UIApplication _runWithMainScene:transitionContext:completion:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.30.14/UIApplication.m:3315
2016-02-12 16:48:24.807 MidiMonitor[88004:1246323] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Application windows are expected to have a root view controller at the end of application launch'
*** First throw call stack:
(
0 CoreFoundation 0x00000001092f0e65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000108cb4deb objc_exception_throw + 48
2 CoreFoundation 0x00000001092f0cca +[NSException raise:format:arguments:] + 106
3 Foundation 0x000000010713c4de -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 198
4 UIKit 0x000000010750f218 -[UIApplication _runWithMainScene:transitionContext:completion:] + 3122
5 UIKit 0x000000010750be7b -[UIApplication workspaceDidEndTransaction:] + 188
6 FrontBoardServices 0x000000010ab28754 -[FBSSerialQueue _performNext] + 192
7 FrontBoardServices 0x000000010ab28ac2 -[FBSSerialQueue _performNextFromRunLoopSource] + 45
8 CoreFoundation 0x000000010921ca31 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17
9 CoreFoundation 0x000000010921295c __CFRunLoopDoSources0 + 556
10 CoreFoundation 0x0000000109211e13 __CFRunLoopRun + 867
11 CoreFoundation 0x0000000109211828 CFRunLoopRunSpecific + 488
12 UIKit 0x000000010750b7cd -[UIApplication _run] + 402
13 UIKit 0x0000000107510610 UIApplicationMain + 171
14 MidiMonitor 0x0000000106fd5bde main + 62
15 libdyld.dylib 0x000000010a4e892d start + 1
16 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Emulator (iPhone 6 Plus iOS 9.2)
It works on iOS 10 devices but running the app in the simulator I can connect it (in Audio MIDI Setup) but it won't let me send any MIDI. Anyone else experiencing this? iOS 9 simulator works fine.
I will contact Apple about this today, maybe they changed something.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.