changeset 26:90069a503079

Merge, plus slight GUI updates and fix to standalone mode bug.
author Andrew McPherson <andrewm@eecs.qmul.ac.uk>
date Sat, 22 Feb 2014 21:59:05 +0000
parents af26e47d9a95 (current diff) 5ee6e2f76323 (diff)
children eef567a60146
files Source/GUI/ControlWindowMainComponent.cpp Source/GUI/ControlWindowMainComponent.h Source/TouchKeys/MidiKeyboardSegment.cpp TouchKeys.jucer
diffstat 7 files changed, 128 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/Source/GUI/ControlWindowMainComponent.cpp	Sat Feb 22 10:42:06 2014 +0000
+++ b/Source/GUI/ControlWindowMainComponent.cpp	Sat Feb 22 21:59:05 2014 +0000
@@ -278,9 +278,9 @@
     midiInputDeviceComboBox->setBounds (72, 168, 224, 24);
     label->setBounds (16, 168, 55, 24);
     groupComponent->setBounds (8, 8, 304, 128);
-    label2->setBounds (16, 32, 55, 24);
+    label2->setBounds (16, 32, 60, 24);
     touchkeyDeviceComboBox->setBounds (72, 32, 224, 24);
-    label3->setBounds (16, 96, 55, 24);
+    label3->setBounds (16, 96, 60, 24);
     touchkeyStartButton->setBounds (216, 96, 79, 24);
     touchkeyStatusLabel->setBounds (72, 96, 136, 24);
     oscGroupComponent->setBounds (8, 288, 304, 96);
@@ -376,7 +376,7 @@
         }
         else if(controller_->touchkeyDeviceIsRunning()) {
 #else
-        if(controller_->touchkeyDeviceIsRunning()) {  
+        if(controller_->touchkeyDeviceIsRunning()) {
 #endif
             // TouchKeys were running. Stop and close.
             controller_->closeTouchkeyDevice();
@@ -665,7 +665,7 @@
 {
     String devName = controller_->touchkeyDevicePrefix().c_str();
     devName += touchkeyDeviceComboBox->getText();
-    
+
     return devName;
 }
 
@@ -793,7 +793,7 @@
   <GROUPCOMPONENT name="new group" id="9106305fd2211185" memberName="groupComponent"
                   virtualName="" explicitFocusOrder="0" pos="8 8 304 128" title="TouchKeys"/>
   <LABEL name="new label" id="944877a84dcfc602" memberName="label2" virtualName=""
-         explicitFocusOrder="0" pos="16 32 55 24" edTextCol="ff000000"
+         explicitFocusOrder="0" pos="16 32 60 24" edTextCol="ff000000"
          edBkgCol="0" labelText="Device:&#10;" editableSingleClick="0"
          editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font"
          fontsize="15" bold="0" italic="0" justification="33"/>
@@ -801,7 +801,7 @@
             virtualName="" explicitFocusOrder="0" pos="72 32 224 24" editable="0"
             layout="33" items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/>
   <LABEL name="new label" id="1cdf89082d95c72c" memberName="label3" virtualName=""
-         explicitFocusOrder="0" pos="16 96 55 24" edTextCol="ff000000"
+         explicitFocusOrder="0" pos="16 96 60 24" edTextCol="ff000000"
          edBkgCol="0" labelText="Status:&#10;" editableSingleClick="0"
          editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font"
          fontsize="15" bold="0" italic="0" justification="33"/>
--- a/Source/GUI/ControlWindowMainComponent.h	Sat Feb 22 10:42:06 2014 +0000
+++ b/Source/GUI/ControlWindowMainComponent.h	Sat Feb 22 21:59:05 2014 +0000
@@ -60,7 +60,7 @@
     void textEditorFocusLost(TextEditor &editor);
 
     void synchronize();
-    
+
     // Return the currently selected TouchKeys string
     String currentTouchkeysSelectedPath();
     //[/UserMethods]
--- a/Source/MainApplicationController.cpp	Sat Feb 22 10:42:06 2014 +0000
+++ b/Source/MainApplicationController.cpp	Sat Feb 22 21:59:05 2014 +0000
@@ -92,7 +92,7 @@
 
 bool MainApplicationController::touchkeyDeviceStartupSequence(const char * path) {
 #ifdef TOUCHKEY_ENTROPY_GENERATOR_ENABLE
-    if(!strcmp(path, "/dev/Entropy Generator")) {
+    if(!strcmp(path, "/dev/Entropy Generator") || !strcmp(path, "\\\\.\\Entropy Generator")) {
         entropyGeneratorSelected_ = true;
         touchkeyEntropyGenerator_.start();
     }
@@ -140,18 +140,54 @@
 }
 
 std::string MainApplicationController::touchkeyDevicePrefix() {
+#ifdef _MSC_VER
+	return "\\\\.\\";
+#else
     if(SystemStats::getOperatingSystemType() == SystemStats::Linux) {
         return "/dev/serial/by-id/";
     }
     else {
         return "/dev/";
     }
+#endif
 }
 
 // Return a list of available TouchKey devices
 std::vector<std::string> MainApplicationController::availableTouchkeyDevices() {
     std::vector<std::string> devices;
-    
+
+#ifdef _MSC_VER
+    for(int i = 1; i <= 128; i++) {
+		String comPortName("COM");
+		comPortName += i;
+
+        DWORD dwSize = 0;
+        LPCOMMCONFIG lpCC = (LPCOMMCONFIG) new BYTE[1];
+        BOOL ret = GetDefaultCommConfig(comPortName.toUTF8(), lpCC, &dwSize);
+        delete [] lpCC;
+
+		if(ret) 
+			devices.push_back(comPortName.toStdString());
+		else {
+			if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+				//Logger::writeToLog(String::formatted("Found " + comPortName));
+				lpCC = (LPCOMMCONFIG) new BYTE[dwSize];
+				ret = GetDefaultCommConfig(comPortName.toUTF8(), lpCC, &dwSize);
+				if(ret)
+					devices.push_back(comPortName.toStdString());
+				else {
+					int error = GetLastError();
+					//Logger::writeToLog(String("2Didn't find " + comPortName + "; error " + String(error)));
+				}
+				delete [] lpCC;
+			}
+			else {
+				int error = GetLastError();
+				//Logger::writeToLog(String("Didn't find " + comPortName + "; error " + String(error)));
+			}
+		}
+    }
+#else
     if(SystemStats::getOperatingSystemType() == SystemStats::Linux) {
         DirectoryIterator devDirectory(File("/dev/serial/by-id"),false,"*");
         
@@ -166,6 +202,7 @@
             devices.push_back(string(devDirectory.getFile().getFileName().toUTF8()));
         }
     }
+#endif
     
 #ifdef TOUCHKEY_ENTROPY_GENERATOR_ENABLE
     devices.push_back("Entropy Generator");
--- a/Source/TouchKeys/MidiKeyboardSegment.cpp	Sat Feb 22 10:42:06 2014 +0000
+++ b/Source/TouchKeys/MidiKeyboardSegment.cpp	Sat Feb 22 21:59:05 2014 +0000
@@ -355,6 +355,8 @@
     if(touchkeyStandaloneMode_) {
         if(!strcmp(path, "/touchkeys/on") && numValues > 0) {
             int noteNumber = values[0]->i;
+            if(!respondsToNote(noteNumber))
+                return true;
             if(noteNumber >= 0 && noteNumber < 128) {
                 // Generate MIDI note on for this message
                 MidiMessage msg(MidiMessage::noteOn(1, noteNumber, (uint8)64));
@@ -364,6 +366,8 @@
         }
         else if(!strcmp(path, "/touchkeys/off") && numValues > 0) {
             int noteNumber = values[0]->i;
+            if(!respondsToNote(noteNumber))
+                return true;
             if(noteNumber >= 0 && noteNumber < 128) {
                 // Generate MIDI note off for this message
                 MidiMessage msg(MidiMessage::noteOff(1, noteNumber));
--- a/Source/TouchKeys/TouchkeyDevice.cpp	Sat Feb 22 10:42:06 2014 +0000
+++ b/Source/TouchKeys/TouchkeyDevice.cpp	Sat Feb 22 21:59:05 2014 +0000
@@ -30,7 +30,12 @@
 // Constructor
 
 TouchkeyDevice::TouchkeyDevice(PianoKeyboard& keyboard) 
-: keyboard_(keyboard), device_(-1),
+: keyboard_(keyboard),
+#ifdef _MSC_VER
+serialHandle_(INVALID_HANDLE_VALUE),
+#else
+device_(-1),
+#endif
 ioThread_(boost::bind(&TouchkeyDevice::runLoop, this, _1), "TouchKeyDevice::ioThread"),
 rawDataThread_(boost::bind(&TouchkeyDevice::rawDataRunLoop, this, _1), "TouchKeyDevice::rawDataThread"),
 autoGathering_(false), shouldStop_(false), sendRawOscMessages_(false),
@@ -119,13 +124,51 @@
 
 bool TouchkeyDevice::openDevice(const char * inputDevicePath) {
 	// If the device is already open, close it
-	if(device_ >= 0)
+	if(isOpen())
 		closeDevice();
 	
 	// Open the device
 #ifdef _MSC_VER
-	// WINDOWS_TODO
-	return false;
+	// Open the serial port
+	serialHandle_ = CreateFile(inputDevicePath, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+	if(serialHandle_ == INVALID_HANDLE_VALUE) {
+		Logger::writeToLog("Unable to open serial port " + String(inputDevicePath));
+		return false;
+	}
+
+	// Set some serial parameters, though they don't actually affect the operation
+	// of the port since it is all native USB
+	DCB serialParams = { 0 };
+	serialParams.DCBlength = sizeof(serialParams);
+
+	if(!BuildCommDCBA("baud=1000000 data=8 parity=N stop=1 dtr=on rts=on", &serialParams)) {
+		Logger::writeToLog("Unable to create port settings\n");
+		CloseHandle(serialHandle_);
+		serialHandle_ = INVALID_HANDLE_VALUE;
+		return false;
+	}
+
+	if(!SetCommState(serialHandle_, &serialParams)) {
+		Logger::writeToLog("Unable to set comm state\n");
+		CloseHandle(serialHandle_);
+		serialHandle_ = INVALID_HANDLE_VALUE;
+		return false;
+	}
+
+	// Set timeouts
+	COMMTIMEOUTS timeout = { 0 };
+	timeout.ReadIntervalTimeout = MAXDWORD;
+	timeout.ReadTotalTimeoutConstant = 0;
+	timeout.ReadTotalTimeoutMultiplier = 0;
+	timeout.WriteTotalTimeoutConstant = 0;
+	timeout.WriteTotalTimeoutMultiplier = 0;
+
+	if(!SetCommTimeouts(serialHandle_, &timeout)) {
+		Logger::writeToLog("Unable to set timeouts\n");
+		CloseHandle(serialHandle_);
+		serialHandle_ = INVALID_HANDLE_VALUE;
+		return false;
+	}
 #else
 	device_ = open(inputDevicePath, O_RDWR | O_NOCTTY | O_NDELAY);
 
@@ -138,20 +181,29 @@
 
 // Close the touchkey serial device
 void TouchkeyDevice::closeDevice() {
-	if(device_ < 0)
+	if(!isOpen())
 		return;
 	
 	stopAutoGathering();
 	keysPresent_.clear();
 
 #ifdef _MSC_VER
-	// WINDOWS_TODO
+	CloseHandle(serialHandle_);
+	serialHandle_ = INVALID_HANDLE_VALUE;
 #else
 	close(device_);
     device_ = -1;
 #endif
 }
 
+bool TouchkeyDevice::isOpen() {
+#ifdef _MSC_VER
+	return serialHandle_ != INVALID_HANDLE_VALUE;
+#else
+	return device_ >= 0; 
+#endif
+}
+
 // Check if the device is present and ready to respond.  If status is not null, store the current
 // controller status information.
 
@@ -161,13 +213,8 @@
 	unsigned char ch;
 	bool controlSeq = false, startingFrame = false;
     
-#ifdef _MSC_VER
-	// WINDOWS_TODO
-	return false;
-#else
-	if(device_ < 0)
+	if(!isOpen())
 		return false;
-#endif
     deviceFlush(false);
     
 	if(deviceWrite((char*)kCommandStatus, 5) < 0) {	// Write status command
@@ -2193,8 +2240,11 @@
 // Read from the TouchKeys device
 long TouchkeyDevice::deviceRead(char *buffer, unsigned int count) {
 #ifdef _MSC_VER
-    // WINDOWS_TODO
-    return -1;
+	int n;
+
+	if(!ReadFile(serialHandle_, buffer, count, (LPDWORD)((void *)&n), NULL))
+		return -1;
+	return n;
 #else
     return read(device_, buffer, count);
 #endif
@@ -2202,11 +2252,11 @@
 
 // Write to the TouchKeys device
 int TouchkeyDevice::deviceWrite(char *buffer, unsigned int count) {
-    long result;
+    int result;
     
 #ifdef _MSC_VER
-    // WINDOWS_TODO
-    return -1;
+    if(!WriteFile(serialHandle_, buffer, count, (LPDWORD)((void *)&result), NULL))
+		return -1;
 #else
     result = write(device_, buffer, count);
 #endif
@@ -2214,10 +2264,10 @@
     return result;
 }
 
-// Flush the TouchKeys device input
+// Flush (discard) the TouchKeys device input
 void TouchkeyDevice::deviceFlush(bool bothDirections) {
 #ifdef _MSC_VER
-    // WINDOWS_TODO
+	// WINDOWS_TODO (?)
 #else
     if(bothDirections)
         tcflush(device_, TCIOFLUSH);
@@ -2226,10 +2276,10 @@
 #endif
 }
 
-// Flush the TouchKeys device input
+// Flush the TouchKeys device output
 void TouchkeyDevice::deviceDrainOutput() {
 #ifdef _MSC_VER
-    // WINDOWS_TODO
+    FlushFileBuffers(serialHandle_);
 #else
     tcdrain(device_);
 #endif
--- a/Source/TouchKeys/TouchkeyDevice.h	Sat Feb 22 10:42:06 2014 +0000
+++ b/Source/TouchKeys/TouchkeyDevice.h	Sat Feb 22 21:59:05 2014 +0000
@@ -235,7 +235,7 @@
 	void stopAutoGathering();	
 	
 	// Status query methods
-	bool isOpen() { return device_ >= 0; }
+	bool isOpen();
 	bool isAutoGathering() { return autoGathering_; }
 	int numberOfOctaves() { return numOctaves_; }
     
@@ -362,7 +362,11 @@
 private:
 	PianoKeyboard& keyboard_;	// Main keyboard controller
 
+#ifdef _MSC_VER
+	HANDLE serialHandle_;		// Serial port handle
+#else
 	int device_;				// File descriptor
+#endif
 	DeviceThread ioThread_;		// Thread that handles the communication from the device
     DeviceThread rawDataThread_;// Thread that handles raw data collection
 	//CriticalSection ioMutex_;	// Mutex synchronizing access between internal and external threads
--- a/TouchKeys.jucer	Sat Feb 22 10:42:06 2014 +0000
+++ b/TouchKeys.jucer	Sat Feb 22 21:59:05 2014 +0000
@@ -319,7 +319,8 @@
         <MODULEPATH id="juce_audio_basics" path="../juce/modules"/>
       </MODULEPATHS>
     </LINUX_MAKE>
-    <VS2012 targetFolder="Builds/VisualStudio2012" externalLibraries="liblo.lib&#10;pthreadVC2.lib">
+    <VS2012 targetFolder="Builds/VisualStudio2012" externalLibraries="liblo.lib&#10;pthreadVC2.lib"
+            smallIcon="mbX6Jp" bigIcon="b3DhPc">
       <CONFIGURATIONS>
         <CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="32-bit"
                        isDebug="1" optimisation="1" targetName="TouchKeys" headerPath="H:\Documents\boost_1_55_0;H:\Documents\liblo-0.26;H:\Documents\pthreads\Pre-built.2\include"/>