Mercurial > hg > soniczoomios
changeset 39:df7c08faf541
MIDI, small improvements.
author | Robert Tubb <rt300@eecs.qmul.ac.uk> |
---|---|
date | Thu, 11 Apr 2013 16:56:21 +0100 |
parents | 0dfe9e0c01aa |
children | af06bb942d58 |
files | AppCore.mm HelpViewController.xib TimedSessionController.h TopButtonViewController.mm TopButtonViewController.xib eventLogger.h eventLogger.mm grid.h grid.mm main.mm presetManager.mm testApp.h testApp.mm |
diffstat | 13 files changed, 514 insertions(+), 159 deletions(-) [+] |
line wrap: on
line diff
--- a/AppCore.mm Wed Apr 10 18:57:05 2013 +0100 +++ b/AppCore.mm Thu Apr 11 16:56:21 2013 +0100 @@ -39,9 +39,9 @@ //pd.receive(*this, "toOF"); // receive only from "toOF" // add midi receiver - pd.addMidiReceiver(*this); // automatically receives from all channels + //pd.addMidiReceiver(*this); // automatically receives from all channels //pd.ignoreMidi(*this, 1); // ignore midi channel 1 - //pd.ignoreMidi(*this); // ignore all channels + pd.ignoreMidi(*this); // ignore all channels //pd.receiveMidi(*this, 1); // receive only from channel 1 // add the data/pd folder to the search path
--- a/HelpViewController.xib Wed Apr 10 18:57:05 2013 +0100 +++ b/HelpViewController.xib Thu Apr 11 16:56:21 2013 +0100 @@ -57,50 +57,70 @@ <string type="base64-UTF8" key="NSString">SU5TVFJVQ1RJT05TDQ1QcmVzcyB0aGUgcGxheSBidXR0b24gYXQgdGhlIHRvcCB0byBzdGFydCB0aGUg c2VxdWVuY2VyLiBQcmVzcyBwYXVzZSB0byBzdG9wLg1Zb3Ugd2lsbCBiZSB1c2luZyBhbGwgdGhyZWUg bW9kZXM6IHRoZSBTTElERVJTLCB0aGUgWk9PTUVSIGFuZCBCT1RIIGZvciBhYm91dCA1IG1pbnV0ZXMg -ZWFjaCwgaW4gYSByYW5kb20gb3JkZXIuIEFmdGVyIHlvdSBjb21wbGV0ZSB0aGUgdGltZWQgc2Vzc2lv -bnMgYW5kIHRoZSBxdWVzdGlvbm5haXJlLCB5b3UgY2FuIGFjY2VzcyB0aGVzZSB1c2luZyB0aGUgdGFi -cyBhdCB0aGUgYm90dG9tIG9mIHRoZSBzY3JlZW4uIA0NT1BFUkFUSU5HIFRIRSBaT09NRVLigKgNVGhl -IHJlZCBjcm9zc2hhaXJzIGluIHRoZSBjZW50cmUgb2YgdGhlIHNjcmVlbiByZXByZXNlbnQgdGhlIHBv -aW50IG9uIHRoZSBzdXJmYWNlIHRoYXQgeW91IGFyZSBsaXN0ZW5pbmcgdG8uIFNjcm9sbCB0aGUgc3Vy -ZmFjZSB1bmRlciB0aGlzIHBvaW50IHRvIG1vdmUgdG8gYSBkaWZmZXJlbnQgc291bmQuIEluIEJPVEgg -bW9kZSB5b3Ugd2lsbCBiZSBhYmxlIHRvIHNlZSB0aGUgZWZmZWN0IG9mIHRoaXMgb24gdGhlIHNsaWRl -cnMuIExpa2V3aXNlIGlmIHlvdSBtb3ZlIGEgc2xpZGVyIHlvdSB3aWxsIGhvcCB0byBhIGRpZmZlcmVu -dCBwb2ludCBvbiB0aGUgc3VyZmFjZS7igKgNU2F2ZSBhbnkgc291bmRzL3NlcXVlbmNlcyB0aGF0IHlv -dSBsaWtlIHVzaW5nIHRoZSDigJxzYXZlIHByZXNldOKAnSBidXR0b24uIEEgbWFya2VyIHdpbGwgYXBw -ZWFyIG9uIHRoZSB6b29tIHN1cmZhY2UuIElmIHlvdSBtb3ZlIHRvIHRoZSB2aWNpbml0eSBvZiBhIHBy -ZXNldCBtYXJrZXIsIHRoZSBjcm9zc2hhaXJzIHdpbGwgc25hcCB0byB0aGUgcHJlc2V0LCBpdHMgZGV0 -YWlscyB3aWxsIGFwcGVhciBhbmQgdGhhdCBzb3VuZCB3aWxsIHBsYXkuDeKAqFVzaW5nIHR3byBmaW5n -ZXIgcGluY2ggbW92ZW1lbnQgem9vbXMgdGhlIHN1cmZhY2UganVzdCBhcyBpbiBhIG1hcHMgYXBwLiBU -aGUgZnVydGhlciB5b3Ugem9vbSBpbiwgdGhlIGxlc3MgdGhlIHNvdW5kIHdpbGwgY2hhbmdlIGFzIHlv -dSBzY3JvbGwgYXJvdW5kLiBGb3IgZXhhbXBsZSB0aGUgeWVsbG93IGxpbmVzIHRoYXQgYXBwZWFyIGF0 -IHRoZSBsYXJnZXN0IHNjYWxlIGNvcnJlc3BvbmQgdG8gdGhlIHNsaWRlcnMganVtcGluZyA2NCB1bml0 -cy4gVGhlIHdoaXRlIGxpbmVzIGF0IHRoZSBzbWFsbGVzdCBzY2FsZSBjb3JyZXNwb25kIHRvIGp1bXBz -IG9mIG9uZSB1bml0LiBUaGVyZSBhcmUgNyBsZXZlbHM64oCo4oCoWWVsbG93ID0gNjTigKhUZWFsID0g -MzLigKhQdXJwbGUgPSAxNuKAqEdyZWVuID0gOOKAqERhcmsgQmx1ZSA9IDTigKhSZWQgPSAy4oCoV2hp -dGUgPSAx4oCo4oCoTE9DS+KAqOKAqElmIHlvdSBmaW5kIGEgc2VxdWVuY2UgeW91IGxpa2UgYnV0IHdh -bnQgdG8gY2hhbmdlIHRoZSBzeW50aCBzb3VuZCB1c2UgdGhlICJMb2NrIFNlcXVlbmNlIChYKSIgYnV0 -dG9uLiBUaGlzIHdpbGwgcHJldmVudCB5b3UgYWNjaWRlbnRhbGx5IG1vdmluZyBpbiBmcm9tIGxlZnQg -dG8gcmlnaHQgYW5kIG1lc3NpbmcgdXAgeW91ciBub3RlIHBhdHRlcm4uIFNpbWlsYXJseSBpZiB5b3Ug -ZmluZCBhIHN5bnRoIHNvdW5kIHRoYXQgeW91IGxpa2UsIGJ1dCB3YW50IHRvIGNoYW5nZSB0aGUgbm90 -ZSBzZXF1ZW5jZSwgdXNlIHRoZSAiTG9jayBTeW50aCAoWSkiIGJ1dHRvbi4g4oCo4oCoUkFORE9NSVNF -4oCo4oCoVXNlIHRoZSByYW5kb21pc2UgdG8ganVtcCB0byBhIHJhbmRvbSBwb2ludCBvbiB0aGUgZ3Jp -ZC4g4oCo4oCoVEhFIFFVRVNUSU9OTkFJUkXigKjigKhUaGVyZSBhcmUgYXJvdW5kIDE1IHNpbXBsZSBt -dWx0aXBsZSBjaG9pY2UgcXVlc3Rpb25zIHRvIGFuc3dlciwgYW5kIGEgdGV4dCBmZWVkYmFjayBib3gu -IFlvdXIgZmVlZGJhY2sgaXMgYXBwcmVjaWF0ZWQhDQ0</string> - <dictionary key="NSAttributes"> - <object class="NSColor" key="NSColor"> - <int key="NSColorSpace">1</int> - <bytes key="NSRGB">MC4zMzgyNjY5OTg0IDAuOTA1MzMyMjM5OSAxAA</bytes> - </object> - <object class="NSFont" key="NSFont"> - <string key="NSName">Helvetica</string> - <double key="NSSize">15</double> - <int key="NSfFlags">16</int> - </object> - <object class="NSMutableParagraphStyle" key="NSParagraphStyle"> - <nil key="NSTabStops"/> - </object> - </dictionary> +ZWFjaCwgaW4gYSByYW5kb20gb3JkZXIuIA0NT1BFUkFUSU5HIFRIRSBaT09NRVLigKgNVGhlIHJlZCBj +cm9zc2hhaXJzIGluIHRoZSBjZW50cmUgb2YgdGhlIHNjcmVlbiByZXByZXNlbnQgdGhlIHBvaW50IG9u +IHRoZSBzdXJmYWNlIHRoYXQgeW91IGFyZSBsaXN0ZW5pbmcgdG8uIFNjcm9sbCB0aGUgc3VyZmFjZSB1 +bmRlciB0aGlzIHBvaW50IHRvIG1vdmUgdG8gYSBkaWZmZXJlbnQgc291bmQuIEluIEJPVEggbW9kZSB5 +b3Ugd2lsbCBiZSBhYmxlIHRvIHNlZSB0aGUgZWZmZWN0IG9mIHRoaXMgb24gdGhlIHNsaWRlcnMuIExp +a2V3aXNlIGlmIHlvdSBtb3ZlIGEgc2xpZGVyIHlvdSB3aWxsIGhvcCB0byBhIGRpZmZlcmVudCBwb2lu +dCBvbiB0aGUgc3VyZmFjZS4gWW91ciBwYXRoIHRocm91Z2ggdGhlIHNwYWNlIHdpbGwgc2hvdyBhcyBh +IHdoaXRlIGxpbmUsIGFueSBwb2ludHMgeW91IGhhdmUgaG92ZXJlZCBvdmVyIHdpbGwgc2hvdyBhcyBi +bHVlIGNpcmNsZXMu4oCoDVNhdmUgYW55IHNvdW5kcy9zZXF1ZW5jZXMgdGhhdCB5b3UgbGlrZSB1c2lu +ZyB0aGUg4oCcc2F2ZSBwcmVzZXTigJ0gYnV0dG9uLiBBIG1hcmtlciB3aWxsIGFwcGVhciBvbiB0aGUg +em9vbSBzdXJmYWNlLiBJZiB5b3UgbW92ZSB0byB0aGUgdmljaW5pdHkgb2YgYSBwcmVzZXQgbWFya2Vy +LCB0aGUgY3Jvc3NoYWlycyB3aWxsIHNuYXAgdG8gdGhlIHByZXNldCwgaXRzIGRldGFpbHMgd2lsbCBh +cHBlYXIgYW5kIHRoYXQgc291bmQgd2lsbCBwbGF5Lg3igKhVc2luZyB0d28gZmluZ2VyIHBpbmNoIG1v +dmVtZW50IHpvb21zIHRoZSBzdXJmYWNlIGp1c3QgYXMgaW4gYSBtYXBzIGFwcC4gVGhlIGZ1cnRoZXIg +eW91IHpvb20gaW4sIHRoZSBsZXNzIHRoZSBzb3VuZCB3aWxsIGNoYW5nZSBhcyB5b3Ugc2Nyb2xsIGFy +b3VuZC4gRm9yIGV4YW1wbGUgdGhlIHllbGxvdyBsaW5lcyB0aGF0IGFwcGVhciBhdCB0aGUgbGFyZ2Vz +dCBzY2FsZSBjb3JyZXNwb25kIHRvIHRoZSBzbGlkZXJzIGp1bXBpbmcgNjQgdW5pdHMuIFRoZSB3aGl0 +ZSBsaW5lcyBhdCB0aGUgc21hbGxlc3Qgc2NhbGUgY29ycmVzcG9uZCB0byBqdW1wcyBvZiBvbmUgdW5p +dC4gVGhlcmUgYXJlIDcgbGV2ZWxzOuKAqOKAqFllbGxvdyA9IDY0LCBUZWFsID0gMzIsIFB1cnBsZSA9 +IDE2LCBHcmVlbiA9IDgsIERhcmsgQmx1ZSA9IDQsIFJlZCA9IDIsIFdoaXRlID0gMeKAqOKAqExPQ0vi +gKjigKhJZiB5b3UgZmluZCBhIHNlcXVlbmNlIHlvdSBsaWtlIGJ1dCB3YW50IHRvIGNoYW5nZSB0aGUg +c3ludGggc291bmQgdXNlIHRoZSAiTG9jayBYIiBidXR0b24uIFRoaXMgd2lsbCBwcmV2ZW50IHlvdSBh +Y2NpZGVudGFsbHkgbW92aW5nIGluIGZyb20gbGVmdCB0byByaWdodCBhbmQgbWVzc2luZyB1cCB5b3Vy +IG5vdGUgcGF0dGVybi4gU2ltaWxhcmx5IGlmIHlvdSBmaW5kIGEgc3ludGggc291bmQgdGhhdCB5b3Ug +bGlrZSwgYnV0IHdhbnQgdG8gY2hhbmdlIHRoZSBub3RlIHNlcXVlbmNlLCB1c2UgdGhlICJMb2NrIFki +IGJ1dHRvbi4g4oCo4oCoUkFORE9NSVNF4oCo4oCoVXNlIHRoZSByYW5kb21pc2UgYnV0dG9uIHRvIGp1 +bXAgdG8gYSByYW5kb20gcG9pbnQgb24gdGhlIGdyaWQuIOKAqOKAqEVYVFJBIEZFQVRVUkVT4oCo4oCo +QWZ0ZXIgeW91IGNvbXBsZXRlIHRoZSB0aW1lZCBzZXNzaW9ucyBhbmQgdGhlIHF1ZXN0aW9ubmFpcmUs +IHlvdSBjYW4gdHVybiB0aGUgc2xpZGVycyBhbmQgdGhlIHpvb21lciBvbi9vZmYgdXNpbmcgdGhlIHRh +YnMgYXQgdGhlIGJvdHRvbSBvZiB0aGUgc2NyZWVuLiBUaGVzZSBmdXJ0aGVyIGZlYXR1cmVzIHdpbGwg +YmUgZW5hYmxlZDrigKjigKhTTU9PVEhJTkfigKjigKhXaGVuIHlvdSBoYXZlIGZpbmlzaGVkIHRoZSBl +eHBlcmltZW50LCBhICJzbW9vdGgiIHN3aXRjaCB3aWxsIGFwcGVhci4gVGhpcyB3aWxsIGludGVycG9s +YXRlIHRoZSBncmlkIHNvIHRoYXQgdGhlIHNsaWRlcnMgY2hhbmdlIG1vcmUgc21vb3RobHkuIE5vdGUg +dGhpcyB3aWxsIGJyZWFrIHRoZSBvbmUgdG8gb25lIG1hcHBpbmcgYmV0d2VlbiBzbGlkZXJzIGFuZCBz +dXJmYWNlOiBwcmV2aW91c2x5IHNhdmVkIHByZXNldHMgd2lsbCBub3QgYXBwZWFyLCBhbmQgYW55IHNh +dmVkIGluIHRoaXMgbW9kZSB3aWxsIHRlbmQgdG8gYXBwZWFyIGluIGEgc2xpZ2h0bHkgZGlmZmVyZW50 +IHBvc2l0aW9uIHdoZW4gc21vb3RoIGlzIHR1cm5lZCBvZmYu4oCo4oCoTUlESQ0NA</string> + <array class="NSMutableArray" key="NSAttributes"> + <dictionary> + <object class="NSColor" key="NSColor"> + <int key="NSColorSpace">1</int> + <bytes key="NSRGB">MC4zMzgyNjY5OTg0IDAuOTA1MzMyMjM5OSAxAA</bytes> + </object> + <object class="NSFont" key="NSFont" id="897351317"> + <string key="NSName">Helvetica</string> + <double key="NSSize">15</double> + <int key="NSfFlags">16</int> + </object> + <object class="NSMutableParagraphStyle" key="NSParagraphStyle" id="310792247"> + <nil key="NSTabStops"/> + </object> + </dictionary> + <dictionary> + <object class="NSColor" key="NSColor"> + <int key="NSColorSpace">1</int> + <bytes key="NSRGB">MC4zMzcyNTQ5MDIgMC45MDU4ODIzNTI5IDEAA</bytes> + </object> + <reference key="NSFont" ref="897351317"/> + <reference key="NSParagraphStyle" ref="310792247"/> + </dictionary> + </array> + <object class="NSMutableData" key="NSAttributeInfo"> + <bytes key="NS.bytes">4Q0AwAEBgQMAA</bytes> + </object> </object> <bool key="IBUIEditable">NO</bool> <object class="IBUITextInputTraits" key="IBUITextInputTraits"> @@ -114,6 +134,7 @@ <string key="NSFrame">{{319, 941}, {130, 44}}</string> <reference key="NSSuperview" ref="766721923"/> <reference key="NSWindow"/> + <reference key="NSNextKeyView"/> <string key="NSReuseIdentifierKey">_NS:9</string> <bool key="IBUIOpaque">NO</bool> <string key="targetRuntimeIdentifier">IBIPadFramework</string>
--- a/TimedSessionController.h Wed Apr 10 18:57:05 2013 +0100 +++ b/TimedSessionController.h Thu Apr 11 16:56:21 2013 +0100 @@ -5,7 +5,7 @@ // Created by Robert Tubb on 18/02/2013. // // -#define SECONDS_PER_INTERFACE 300 +#define SECONDS_PER_INTERFACE 400 #import <Foundation/Foundation.h>
--- a/TopButtonViewController.mm Wed Apr 10 18:57:05 2013 +0100 +++ b/TopButtonViewController.mm Thu Apr 11 16:56:21 2013 +0100 @@ -138,13 +138,7 @@ UISwitch * smoothswitch = (UISwitch *)sender; NSLog(@"SMOOTH SWITCH %d", smoothswitch.on); ((testApp *)self.theOFAppRef)->setInterp(smoothswitch.on); - - if(smoothswitch.on){ - self.savePresetButton.enabled = NO; - - }else{ - self.savePresetButton.enabled = YES; - } + } - (IBAction)show:(id)sender
--- a/TopButtonViewController.xib Wed Apr 10 18:57:05 2013 +0100 +++ b/TopButtonViewController.xib Thu Apr 11 16:56:21 2013 +0100 @@ -45,7 +45,7 @@ <object class="IBUISwitch" id="150228020"> <reference key="NSNextResponder" ref="358683122"/> <int key="NSvFlags">-2147483356</int> - <string key="NSFrame">{{106, 9}, {94, 27}}</string> + <string key="NSFrame">{{92, 9}, {94, 27}}</string> <reference key="NSSuperview" ref="358683122"/> <reference key="NSWindow"/> <reference key="NSNextKeyView" ref="459236656"/> @@ -81,25 +81,7 @@ <reference key="IBUICustomView" ref="150228020"/> <reference key="IBUIToolbar" ref="358683122"/> </object> - <object class="IBUIBarButtonItem" id="180077124"> - <string key="IBUITitle">Random</string> - <string key="targetRuntimeIdentifier">IBIPadFramework</string> - <int key="IBUIStyle">1</int> - <reference key="IBUIToolbar" ref="358683122"/> - </object> - <object class="IBUIBarButtonItem" id="189059998"> - <string key="IBUITitle">Lock X</string> - <string key="targetRuntimeIdentifier">IBIPadFramework</string> - <int key="IBUIStyle">1</int> - <reference key="IBUIToolbar" ref="358683122"/> - </object> - <object class="IBUIBarButtonItem" id="597523981"> - <string key="IBUITitle">Lock Y</string> - <string key="targetRuntimeIdentifier">IBIPadFramework</string> - <int key="IBUIStyle">1</int> - <reference key="IBUIToolbar" ref="358683122"/> - </object> - <object class="IBUIBarButtonItem" id="528026433"> + <object class="IBUIBarButtonItem" id="174215053"> <string key="targetRuntimeIdentifier">IBIPadFramework</string> <reference key="IBUIToolbar" ref="358683122"/> <int key="IBUISystemItemIdentifier">5</int> @@ -122,6 +104,29 @@ <reference key="IBUIToolbar" ref="358683122"/> <int key="IBUISystemItemIdentifier">20</int> </object> + <object class="IBUIBarButtonItem" id="528026433"> + <string key="targetRuntimeIdentifier">IBIPadFramework</string> + <reference key="IBUIToolbar" ref="358683122"/> + <int key="IBUISystemItemIdentifier">5</int> + </object> + <object class="IBUIBarButtonItem" id="180077124"> + <string key="IBUITitle">Random</string> + <string key="targetRuntimeIdentifier">IBIPadFramework</string> + <int key="IBUIStyle">1</int> + <reference key="IBUIToolbar" ref="358683122"/> + </object> + <object class="IBUIBarButtonItem" id="189059998"> + <string key="IBUITitle">Lock X</string> + <string key="targetRuntimeIdentifier">IBIPadFramework</string> + <int key="IBUIStyle">1</int> + <reference key="IBUIToolbar" ref="358683122"/> + </object> + <object class="IBUIBarButtonItem" id="597523981"> + <string key="IBUITitle">Lock Y</string> + <string key="targetRuntimeIdentifier">IBIPadFramework</string> + <int key="IBUIStyle">1</int> + <reference key="IBUIToolbar" ref="358683122"/> + </object> <object class="IBUIBarButtonItem" id="680653375"> <string key="targetRuntimeIdentifier">IBIPadFramework</string> <reference key="IBUIToolbar" ref="358683122"/> @@ -392,16 +397,17 @@ <array class="NSMutableArray" key="children"> <reference ref="680653375"/> <reference ref="528026433"/> + <reference ref="924591997"/> + <reference ref="1052071507"/> + <reference ref="379344923"/> <reference ref="898331149"/> - <reference ref="924591997"/> - <reference ref="379344923"/> <reference ref="180077124"/> <reference ref="189059998"/> <reference ref="597523981"/> - <reference ref="1052071507"/> + <reference ref="552018169"/> <reference ref="996249183"/> - <reference ref="552018169"/> <reference ref="1056681435"/> + <reference ref="174215053"/> </array> <reference key="parent" ref="766721923"/> </object> @@ -488,6 +494,11 @@ <reference key="object" ref="459236656"/> <reference key="parent" ref="766721923"/> </object> + <object class="IBObjectRecord"> + <int key="objectID">52</int> + <reference key="object" ref="174215053"/> + <reference key="parent" ref="358683122"/> + </object> </array> </object> <dictionary class="NSMutableDictionary" key="flattenedProperties"> @@ -512,13 +523,14 @@ <string key="45.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string> <string key="46.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string> <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string> + <string key="52.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string> <string key="9.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string> </dictionary> <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/> <nil key="activeLocalization"/> <dictionary class="NSMutableDictionary" key="localizations"/> <nil key="sourceID"/> - <int key="maxID">51</int> + <int key="maxID">52</int> </object> <object class="IBClassDescriber" key="IBDocument.Classes"> <array class="NSMutableArray" key="referencedPartialClassDescriptions">
--- a/eventLogger.h Wed Apr 10 18:57:05 2013 +0100 +++ b/eventLogger.h Thu Apr 11 16:56:21 2013 +0100 @@ -30,7 +30,7 @@ #define EVENT_THIN_FACTOR 12 #define EVENT_LOG_FILENAME "log.json" -#define UPLOAD_CHUNK_SIZE 100 +#define UPLOAD_CHUNK_SIZE 1000 #define APP_CREATION_TIME 381429000000 // milliseconds to the time i wrote this wee blighter. saves digits #define SCROLL_TRAIL_LENGTH 200 #define PROGRAM_VERSION 0.5 // NOW USES NEW HILBERT CURVE. ALL OLD PRESETS WILL BE INVALID :( @@ -61,7 +61,9 @@ HELP_PRESSED, // 19 QUESTIONNAIRE_COMPLETED, // 20 EVALUATION_POINT, // 21 - EMPTY_EVENT}; // 22 + EMPTY_EVENT, // 22 + SMOOTHING_ON, // 23 + SMOOTHING_OFF}; // 24 //--------------------------------------------------------------------------- @@ -181,7 +183,9 @@ vector<lEvent> theEvents; // all logged but not uploaded events deque<lEvent> eventsToDraw; // 200 or so drawable events, maybe uploaded maybe not - void thinnedLogEvent(lEvent nextEvent); + void thinnedSliderEvent(lEvent nextEvent); + void thinnedZoomEvent(lEvent nextEvent); + void thinnedSnapEvent(lEvent nextEvent); void thinnedScrollEvent(lEvent nextEvent); unsigned int nextUploadQty;
--- a/eventLogger.mm Wed Apr 10 18:57:05 2013 +0100 +++ b/eventLogger.mm Thu Apr 11 16:56:21 2013 +0100 @@ -76,6 +76,8 @@ //--------------------------------------------------------------------------- // this reads the persistent log file , checks if we've used the app before and // if we've answered questionnaire or not + +// this function is horrible void EventLogger::checkExistingLogFile(const string &jsonFile){ Json::Value root; Json::Reader reader; @@ -165,6 +167,9 @@ //timer.setInteractionTime(savedInteractionTime); //timer.setOrderFromPrevious(interfaceOrder); + // otherwise just start + ((testApp *)ofGetAppPtr())->justStart(); + } //--------------------------------------------------------------------------- @@ -177,9 +182,9 @@ questionnaireCompleted = false; questionnaireUploaded = false; - //((testApp *)ofGetAppPtr())->showIntro(); + ((testApp *)ofGetAppPtr())->showIntro(); //consentGiven = false; - ((testApp *)ofGetAppPtr())->justStart(); + //((testApp *)ofGetAppPtr())->justStart(); } @@ -398,7 +403,7 @@ // if previous event is more than 300ms ago, or event type has changed, log both of them (lots of events on move+zoom combinations!!) int gap = newEvent.eventTime - previousEvent.eventTime; if(gap > 300){ - // log previous event as a evaluation point MAYBE TODO if previous event was logged as scroll chuck it out? + // log previous event as a evaluation point lEvent evalEvt(EVALUATION_POINT, previousEvent.val1, previousEvent.val2, gap); theEvents.push_back(evalEvt); eventsToDraw.push_back(evalEvt); @@ -425,9 +430,8 @@ eventCounter++; previousEvent = newEvent; -} -//--------------------------------------------------------------------------- -void EventLogger::thinnedLogEvent(lEvent newEvent){ +}//--------------------------------------------------------------------------- +void EventLogger::thinnedSliderEvent(lEvent newEvent){ static lEvent previousEvent(EMPTY_EVENT); // initialised as whatever. hopefully won't log static int eventCounter = 0; @@ -438,19 +442,56 @@ return; } - // if previous event is more than 300ms ago, or event type has changed, log both of them (lots of events on move+zoom combinations!!) + // if previous event is more than 300ms ago log both of them int gap = newEvent.eventTime - previousEvent.eventTime; - if(gap > 300 || newEvent.eventType != previousEvent.eventType){ + if(gap > 300){ + // we need the PREV grid coord though, which is lost!! + TwoVector c = theGridView.getCoord(); + lEvent evalEvt(EVALUATION_POINT, c.x, c.y, gap); + theEvents.push_back(evalEvt); + eventsToDraw.push_back(evalEvt); + if(eventsToDraw.size() > SCROLL_TRAIL_LENGTH){ + eventsToDraw.pop_front(); + } + // if prev slider event not logged, log it + if(theEvents.back().eventTime != previousEvent.eventTime){ + theEvents.push_back(previousEvent); + } + + // also log new slider evt + theEvents.push_back(newEvent); + eventCounter = 0; + + }else if(eventCounter >= EVENT_THIN_FACTOR){ // otherwise only record every Nth event + theEvents.push_back(newEvent); + eventCounter = 0; + + } + eventCounter++; + previousEvent = newEvent; +} +//--------------------------------------------------------------------------- +void EventLogger::thinnedZoomEvent(lEvent newEvent){ + static lEvent previousEvent(EMPTY_EVENT); // initialised as whatever. hopefully won't log + static int eventCounter = 0; + + // if first event then log it. it won't be, but still. + if(theEvents.size() == 0){ + theEvents.push_back(newEvent); + previousEvent = newEvent; + return; + } + + int gap = newEvent.eventTime - previousEvent.eventTime; + if(gap > 400){ // if prev event not logged, log it if(theEvents.back().eventTime != previousEvent.eventTime){ theEvents.push_back(previousEvent); } theEvents.push_back(newEvent); + eventCounter = 0; - } - - // otherwise only record every Nth event - if(eventCounter >= EVENT_THIN_FACTOR){ + }else if(eventCounter >= EVENT_THIN_FACTOR){ theEvents.push_back(newEvent); eventCounter = 0; @@ -458,6 +499,15 @@ eventCounter++; previousEvent = newEvent; } +//----------------------------------------------------------------------------- +void EventLogger::thinnedSnapEvent(lEvent nextEvent){ + static lEvent previousEvent(EMPTY_EVENT); + if(nextEvent.val1 != previousEvent.val1 || nextEvent.val2 != previousEvent.val2){ + theEvents.push_back(nextEvent); + cout << "Snapped EVENT\n"; + } + previousEvent = nextEvent; +} //--------------------------------------------------------------------------- void EventLogger::logEvent(const leventType& evtType,const TwoVector& centre, const double& scale, const int& sliderID, const double& sliderVal){ @@ -479,10 +529,14 @@ //theEvents.push_back(lEvent(evtType,centre.x,centre.y)); break; case ZOOM: - thinnedLogEvent(lEvent(evtType,scale)); + thinnedZoomEvent(lEvent(evtType,scale)); break; case CHANGE_SLIDER: - thinnedLogEvent(lEvent(evtType,sliderVal , 0.0 , sliderID)); + thinnedSliderEvent(lEvent(evtType,sliderVal , 0.0 , sliderID)); + break; + case SNAPPED_TO_PRESET: + thinnedSnapEvent(lEvent(evtType,centre.x,centre.y,sliderID)); + break; // non thinned data case SAVE_PRESET: @@ -495,12 +549,8 @@ case SCROLL_STOPPED: theEvents.push_back(lEvent(evtType,centre.x,centre.y)); - cout << "SCROLL STOPPED EVENT\n"; break; - case SNAPPED_TO_PRESET: - theEvents.push_back(lEvent(evtType,centre.x,centre.y,sliderID)); - cout << "Snapped EVENT\n"; - break; + case SWAP_VIEW: theEvents.push_back(lEvent(evtType,0.0 , 0.0 , sliderID)); // slider ID is which view break;
--- a/grid.h Wed Apr 10 18:57:05 2013 +0100 +++ b/grid.h Thu Apr 11 16:56:21 2013 +0100 @@ -44,6 +44,7 @@ int smallestGridSpacing; // number of pixels when small grid dissappears from view vector<int> getParams(); TwoVector getCoord(); + double getScale(){return scale;}; void setMinZoom(); void setMaxZoom(); void setInterpolation(interpolateModeType mode); @@ -52,10 +53,10 @@ TwoVector calculateCoordFromParams(vector<int> params); vector<int> calculateInterpolatedParamsFromCoord(TwoVector coord); TwoVector coordToPixel(TwoVector coord); - + void setScale(double scaleLevel); // the inverse stuff void setParams(vector<int>); - + TwoVector getCoordForPresetSave(); private: double scale; // surface units per pixel GUI
--- a/grid.mm Wed Apr 10 18:57:05 2013 +0100 +++ b/grid.mm Thu Apr 11 16:56:21 2013 +0100 @@ -33,8 +33,9 @@ pixSize.setCoord(ofGetWidth(), ofGetHeight()); - //set scale and position to random - scale = 15500.0; + //set scale to random + double scaleLevel = (ofRandomf() + 1.00001)*0.5*paramBitDepth; + scale = pow(2.0, scaleLevel*paramBitDepth); smallestGridSpacing = 3; //pixels @@ -60,11 +61,16 @@ viewWasChanged(); calculateInterpolateLevel(); + + // log the starting zoom level + eventLogger.logEvent(ZOOM,centre, scale); + } - +//-------------------------------------------------------------- template <typename T> int sgn(T val) { return (T(0) < val) - (val < T(0)); } + //-------------------------------------------------------------- double Grid::calculateInterpolateLevel(){ if(interpolateMode == INTERPOLATE_GRID){ @@ -80,6 +86,39 @@ } } //-------------------------------------------------------------- +TwoVector Grid::getCoordForPresetSave(){ // bad functions get bad names + + // + TwoVector coord = calculateCoordFromParams(getParams()); + return coord; + +} +//-------------------------------------------------------------- +void Grid::setScale(double scaleLevel){ + + // random + //double p = scaleLevel*paramBitDepth*paramsPerDim*0.5; + + + if(scaleLevel > paramBitDepth || scaleLevel < 0){ + cout << "Error: Bad scale level: " << scaleLevel << "\n"; + scaleLevel = 5; + } + + scale = pow(2.0, scaleLevel*paramsPerDim); + + // update view size using centre + // and scale... + size.x = ofGetWidth()*scale; // zooming in, size gets SMALLER (view less) + size.y = ofGetHeight()*scale; + + + + viewWasChanged(); + calculateInterpolateLevel(); + eventLogger.logEvent(ZOOM, centre, scale); +} +//-------------------------------------------------------------- void Grid::setInterpolation(interpolateModeType mode){ interpolateMode = mode; viewWasChanged(); @@ -493,26 +532,26 @@ if(size.x > maxValue*2.0){ - cout << "maxZoom\n"; + maxZoom = true; size.x = maxValue*2.0; // need to also set y size back to } if(size.y > maxValue*2.0){ - cout << "maxZoom\n"; + maxZoom = true; size.y = maxValue*2.0; } if(size.x < minValue){ - cout << "min Zoom\n"; + minZoom = true; size.x = minValue; // need to also set y size back to } if(size.y < minValue){ minZoom = true; - cout << "min Zoom\n"; + size.y = minValue; }
--- a/main.mm Wed Apr 10 18:57:05 2013 +0100 +++ b/main.mm Thu Apr 11 16:56:21 2013 +0100 @@ -4,6 +4,10 @@ Grid theGridView; // global because it saves PAIN int main(){ + //ofAppiPhoneWindow * iOSWindow = new ofAppiPhoneWindow(); + //iOSWindow->enableAntiAliasing(2); + //iOSWindow->enableRetinaSupport(); + ofSetupOpenGL(1024,768, OF_FULLSCREEN); // <-------- setup the GL context ofRunApp(new testApp); }
--- a/presetManager.mm Wed Apr 10 18:57:05 2013 +0100 +++ b/presetManager.mm Thu Apr 11 16:56:21 2013 +0100 @@ -200,7 +200,7 @@ // hmm shouldn't have to know about eventlogger and grid view... // get the preset coord from the grid - TwoVector coord = theGridView.getCoord(); + TwoVector coord = theGridView.getCoordForPresetSave(); thePresets.push_back(new Preset(coord, name,nextID, eventLogger.userName, eventLogger.deviceID));
--- a/testApp.h Wed Apr 10 18:57:05 2013 +0100 +++ b/testApp.h Thu Apr 11 16:56:21 2013 +0100 @@ -5,6 +5,8 @@ #include "ofxiPhoneExtras.h" #include "ofxiPhoneExternalDisplay.h" #include "ofxOsc.h" +#include "ofxMidi.h" + #include "grid.h" #include "2dvector.h" #include "ofxUI.h" @@ -29,16 +31,19 @@ #define OSC_HOST "169.254.1.1" #define OSC_PORT 12345 -#define SLIDER_GUI_WIDTH 720 +#define SLIDER_GUI_WIDTH 256 #define SLIDER_HEIGHT 256 #define NUM_PARAMS 10 typedef enum {SLIDERS,ZOOMER,BOTH,INTRO,QUESTIONNAIRE, HELP}interfaceType; -class testApp : public ofxiPhoneApp , public ofxiPhoneExternalDisplay{ +class testApp : public ofxiPhoneApp , public ofxiPhoneExternalDisplay, public ofxMidiListener, public ofxMidiConnectionListener { public: + bool sendMIDIAndOSC; + int midiChannel; + int midiOffset; interfaceType whichInterfaceShowing; BottomTabViewController *bottomTabViewController; @@ -119,6 +124,8 @@ void showIntro(); void introHidden(bool OK); void interfaceSelected(int which); + void freeUseMode(); + void seqStartStop(bool go); void showHelp(); void helpHidden(); @@ -153,7 +160,8 @@ void sendFiltFreq(int ctrlin); void sendEnvShape(int ctrlin); void sendModFreq(int ctrlin); - + void sendMidiParams(); + void sendMidiParam(int which); ofxUICanvas *zoomGUI; // audio callbacks @@ -162,6 +170,28 @@ AppCore core; + // message + void addMessage(string msg); + + // midi message callback + void newMidiMessage(ofxMidiMessage& msg); + + // midi device (dis)connection event callbacks + void midiInputAdded(string name, bool isNetwork); + void midiInputRemoved(string name, bool isNetwork); + + void midiOutputAdded(string nam, bool isNetwork); + void midiOutputRemoved(string name, bool isNetwork); + + vector<ofxMidiIn*> inputs; + vector<ofxMidiOut*> outputs; + + deque<string> messages; + int maxMessages; + + int note, ctl; + vector<unsigned char> bytes; + }; // should be off split into
--- a/testApp.mm Wed Apr 10 18:57:05 2013 +0100 +++ b/testApp.mm Thu Apr 11 16:56:21 2013 +0100 @@ -1,7 +1,6 @@ #include "testApp.h" -#define SLIDER_GUI_WIDTH 256 -#define NUM_PARAMS 10 + extern Grid theGridView; extern PresetManager presetManager; extern EventLogger eventLogger; @@ -19,12 +18,12 @@ //-------------------------------------------------------------- void testApp::setup(){ paused = true; - + sendMIDIAndOSC = false; ofBackground( 0, 0, 0 ); ofEnableAlphaBlending(); currentSequence = 0; - //ofEnableSmoothing(); + ofEnableSmoothing(); // open an outgoing connection to HOST:PORT for OSC @@ -137,6 +136,53 @@ //[sliderViewController show:(id)this]; + ///////////////////////// + // MIDI + + midiChannel = 7; + midiOffset = 0; + + // enables the network midi session between iOS and Mac OSX on a + // local wifi network + // + // in ofxMidi: open the input/outport network ports named "Session 1" + // + // on OSX: use the Audio MIDI Setup Utility to connect to the iOS device + // + ofxMidi::enableNetworking(); + + // list the number of available input & output ports + ofxMidiIn::listPorts(); + ofxMidiOut::listPorts(); + + // create and open input ports + for(int i = 0; i < ofxMidiIn::getNumPorts(); ++i) { + + // new object + inputs.push_back(new ofxMidiIn); + + // set this class to receive incoming midi events + inputs[i]->addListener(this); + + // open input port via port number + inputs[i]->openPort(i); + } + + // create and open output ports + for(int i = 0; i < ofxMidiOut::getNumPorts(); ++i) { + + // new object + outputs.push_back(new ofxMidiOut); + + // open input port via port number + outputs[i]->openPort(i); + } + + // set this class to receieve midi device (dis)connection events + ofxMidi::setConnectionListener(this); + + // END MIDI + } @@ -153,6 +199,18 @@ //[topButtonViewController release]; //[bottomTabViewController release]; + // clean up MIDI + for(int i = 0; i < inputs.size(); ++i) { + inputs[i]->closePort(); + inputs[i]->removeListener(this); + delete inputs[i]; + } + + for(int i = 0; i < outputs.size(); ++i) { + outputs[i]->closePort(); + delete outputs[i]; + } + delete sliderGUI; cout << "exit done \n"; @@ -178,7 +236,7 @@ void testApp::lockSequencerPressed(bool locked){ theGridView.shiftCentreToSnapped(); xLocked = locked; - eventLogger.logEvent(SEQ_LOCKED); + eventLogger.logEvent(SEQ_LOCKED); // TODO whatabout unlock? } @@ -229,31 +287,36 @@ void testApp::questionnaireHidden(vector<int> answers, const char* userComments){ // send answers to server as json eventLogger.questionnaireAnswersObtained(answers, userComments); + + freeUseMode(); - // tell bottomtabviewcontroller to show and select both interface +} +//-------------------------------------------------------------- +// shortcut function for testing +void testApp::justStart(){ + freeUseMode(); +} +//-------------------------------------------------------------- +void testApp::freeUseMode(){ interfaceSelected(1); [bottomTabViewController show:(id)this withSelection:1]; [topButtonViewController enableSmoothSwitch:(id)this]; -} -//-------------------------------------------------------------- -// shortcut function for testing -void testApp::justStart(){ - interfaceSelected(1); - [bottomTabViewController show:(id)this withSelection:1]; - [topButtonViewController enableSmoothSwitch:(id)this]; + sendMIDIAndOSC = true; } //-------------------------------------------------------------- void testApp::setInterp(int state){ if(state == 0){ theGridView.setInterpolation(Grid::NO_INTERPOLATION); + eventLogger.logEvent(SMOOTHING_OFF); }else if(state == 1){ theGridView.setInterpolation(Grid::INTERPOLATE_GRID); + eventLogger.logEvent(SMOOTHING_ON); } // tell sliders and PD setAllGUISliders(theGridView.getParams()); - sendParametersToPD(); + } //-------------------------------------------------------------- void testApp::showIntro(){ @@ -288,10 +351,10 @@ // no unOK } //-------------------------------------------------------------- -// called from BottomTabViewController iOS segmented thing +// called from BottomTabViewController iOS segmented thing, also timed session controller void testApp::interfaceSelected(int which){ switch (which){ - case 0: + case 0: // slider whichInterfaceShowing = SLIDERS; sliderGUI->setVisible(true); @@ -300,26 +363,27 @@ setAllGUISliders(sliderVals); break; - case 1: + case 1: // both whichInterfaceShowing = BOTH; sliderGUI->setVisible(true); // set the slider values to stuff got from zoomer sliderVals = theGridView.getParams(); setAllGUISliders(sliderVals); + break; - case 2: + case 2: // zoomer sliderGUI->setVisible(false); whichInterfaceShowing = ZOOMER; break; } - eventLogger.logEvent(SWAP_VIEW,TwoVector(),0.0, which); + eventLogger.logEvent(SWAP_VIEW,theGridView.getCoord(),theGridView.getScale(), which); } //-------------------------------------------------------------- //-------------------------------------------------------------- void testApp::setupSliderGui(){ - float xInit = OFX_UI_GLOBAL_WIDGET_SPACING; + float length = SLIDER_GUI_WIDTH - (OFX_UI_GLOBAL_WIDGET_SPACING*2); @@ -327,7 +391,7 @@ // make this iphone size...? int height = 480; - int width = 320; + float dim = (height-10.0*OFX_UI_GLOBAL_WIDGET_SPACING)/10.0; // LEFT GUI sliderGUI = new ofxUICanvas(0,160,SLIDER_GUI_WIDTH,getHeight()); @@ -381,6 +445,11 @@ theGridView.setParams(sliderVals); sendParametersToPD(); + if(sendMIDIAndOSC){ + + sendMidiParam(which); + sendOSCParams(); + } eventLogger.logEvent(CHANGE_SLIDER, TwoVector(),0.0,which , value); @@ -393,10 +462,19 @@ sliderVals[i] = vals[i]; } + sendParametersToPD(); + if(sendMIDIAndOSC){ + + sendMidiParams(); + sendOSCParams(); + } + } //-------------------------------------------------------------- void testApp::randomise(){ // pick random settings for all params + + // random zoom? no. for(int i=0; i < NUM_PARAMS ; i++){ sliderVals[i] = ofRandom(0, 127); @@ -405,12 +483,12 @@ // send to grid, sliders and PD theGridView.setParams(sliderVals); setAllGUISliders(sliderVals); - sendParametersToPD(); - + + eventLogger.logEvent(RANDOMISE, theGridView.getCoord() ,0.0); } -//- +//-------------------------------------------------------------- void testApp::showHelp(){ whichInterfaceShowing = HELP; seqStartStop(false); @@ -432,6 +510,8 @@ sendParametersToPD(); } //-------------------------------------------------------------- +//-------------------------------------------------------------- +#pragma mark sending to pd and midi void testApp::sendParametersToPD(){ static int previousSequence; // frequencer stuff to get 16 steps @@ -479,8 +559,45 @@ sendFiltFreq(sliderVals[7]); sendEnvShape(sliderVals[8]); sendModFreq(sliderVals[9]); + } +//-------------------------------------------------------------- +void testApp::sendMidiParam(int which){ + int midiChannel = 7; + int offset = 0; + + for(int i = 0; i < outputs.size(); ++i) { + outputs[i]->sendControlChange(midiChannel, offset+which, sliderVals[which]); + } + + +} +//-------------------------------------------------------------- +void testApp::sendMidiParams(){ + + for(int i = 0; i< sliderVals.size(); i++){ + for(int j = 0; j < outputs.size(); ++j) { + outputs[j]->sendControlChange(midiChannel, midiOffset+i, sliderVals[i]); + } + } + +} +//-------------------------------------------------------------- +void testApp::sendOSCParams(){ + + ofxOscMessage m; + m.setAddress( "sonicZoom" ); + + for(int i = 0; i< sliderVals.size(); i++){ + + m.addFloatArg(sliderVals[i]); + + } + sender.sendMessage( m ); +} +//-------------------------------------------------------------- + void testApp::setupNewUser(){ // this function is for supervised trials with my ipad eventLogger.newUser(); @@ -510,7 +627,7 @@ moveVel.setCoord(0.0,0.0);; // don't move if zooming! Too many events! setAllGUISliders(theGridView.getParams()); - sendParametersToPD(); + } if(moveVel.norm() > 0.3){ @@ -523,12 +640,12 @@ } // and get new parameter values setAllGUISliders(theGridView.getParams()); - sendParametersToPD(); + }else if(moveVel.norm() > 0.01){ // and less than 0.3 // stop it moveVel.setCoord(0.0,0.0); setAllGUISliders(theGridView.getParams()); - sendParametersToPD(); + eventLogger.logEvent(SCROLL_STOPPED, theGridView.getCoord() ); }else{ @@ -538,23 +655,9 @@ } } + //-------------------------------------------------------------- -void testApp::sendOSCParams(){ - - vector<int> params = theGridView.getParams(); // FILTER HERE? NEED FLOATS... - vector<int>::iterator iter = params.begin(); - - ofxOscMessage m; - m.setAddress( "p" ); - - for(;iter < params.end();iter++){ - - m.addFloatArg( *iter ); - - } - sender.sendMessage( m ); -} -//-------------------------------------------------------------- + void testApp::draw(){ switch (whichInterfaceShowing){ @@ -683,7 +786,7 @@ // and get new parameter values setAllGUISliders(theGridView.getParams()); - sendParametersToPD(); + } //-------------------------------------------------------------- // handle pinch movememnt @@ -708,7 +811,7 @@ setAllGUISliders(theGridView.getParams()); - sendParametersToPD(); + } @@ -1104,3 +1207,100 @@ currentSequence = ofRandom(0,N-1); } +//------------------------------------------------------------------------- +//-------------------------------------------------------------- + +#pragma mark MIDI +void testApp::addMessage(string msg) { + cout << msg << endl; + messages.push_back(msg); + while(messages.size() > maxMessages) + messages.pop_front(); +} + +//-------------------------------------------------------------- +void testApp::newMidiMessage(ofxMidiMessage& msg) { + //addMessage(msg.toString()); + + // look at what it is + + if(msg.channel == midiChannel && msg.status == MIDI_CONTROL_CHANGE){ + int ctl_num = msg.control; + int ctl_val = msg.value; + if(ctl_num - midiOffset >= 0 && ctl_num - midiOffset < sliderVals.size()){ + sliderVals[ctl_num] = (int)ctl_val; + sliders[ctl_num]->setValue(ctl_val); + theGridView.setParams(sliderVals); + } + } + +} + +//-------------------------------------------------------------- +void testApp::midiInputAdded(string name, bool isNetwork) { + stringstream msg; + msg << "ofxMidi: input added: " << name << " network: " << isNetwork; + cout << msg.str(); + addMessage(msg.str()); + + // create and open a new input port + ofxMidiIn * newInput = new ofxMidiIn; + newInput->openPort(name); + newInput->addListener(this); + inputs.push_back(newInput); +} + +//-------------------------------------------------------------- +void testApp::midiInputRemoved(string name, bool isNetwork) { + stringstream msg; + msg << "ofxMidi: input removed: " << name << " network: " << isNetwork << endl; + cout << msg.str(); + addMessage(msg.str()); + + // close and remove input port + vector<ofxMidiIn*>::iterator iter; + for(iter = inputs.begin(); iter != inputs.end(); ++iter) { + ofxMidiIn * input = (*iter); + if(input->getName() == name) { + input->closePort(); + input->removeListener(this); + delete input; + inputs.erase(iter); + break; + } + } +} + +//-------------------------------------------------------------- +void testApp::midiOutputAdded(string name, bool isNetwork) { + stringstream msg; + msg << "ofxMidi: output added: " << name << " network: " << isNetwork << endl; + cout << msg.str(); + addMessage(msg.str()); + + // create and open new output port + ofxMidiOut * newOutput = new ofxMidiOut; + newOutput->openPort(name); + outputs.push_back(newOutput); +} + +//-------------------------------------------------------------- +void testApp::midiOutputRemoved(string name, bool isNetwork) { + stringstream msg; + msg << "ofxMidi: output removed: " << name << " network: " << isNetwork << endl; + cout << msg.str(); + addMessage(msg.str()); + + // close and remove output port + vector<ofxMidiOut*>::iterator iter; + for(iter = outputs.begin(); iter != outputs.end(); ++iter) { + ofxMidiOut * output = (*iter); + if(output->getName() == name) { + output->closePort(); + delete output; + outputs.erase(iter); + break; + } + } +} +//-------------------------------------------------------------- \ No newline at end of file