Added Firmware Code and Mac App to make the Rotary Gecko a juke box. This is for my presentation at Security B-Sides Huntsville.
This commit is contained in:
parent
a08f3f3def
commit
1f2230c2cb
@ -11,6 +11,7 @@ SoftwareSerial btSerial(2,3); // RX,TX
|
||||
int eventPin = 4;
|
||||
int eventValue = 1;
|
||||
int commandPin = 5;
|
||||
int commandToggle = 0;
|
||||
|
||||
int hookPin = 6;
|
||||
int hookValue = 1;
|
||||
@ -114,6 +115,7 @@ void setup() {
|
||||
pinMode(eventPin, INPUT);
|
||||
pinMode(commandPin, OUTPUT);
|
||||
digitalWrite(commandPin, LOW);
|
||||
commandToggle = 1;
|
||||
|
||||
pinMode(hookPin, INPUT_PULLUP);
|
||||
pinMode(startPosPin, INPUT_PULLUP);
|
||||
@ -129,8 +131,9 @@ void setup() {
|
||||
void loop() {
|
||||
if (btSerial.available())
|
||||
Serial.write(btSerial.read());
|
||||
if (Serial.available())
|
||||
if (Serial.available()) {
|
||||
btSerial.write(Serial.read());
|
||||
}
|
||||
|
||||
// Gather information from the pins to work with.
|
||||
int event = digitalRead(eventPin);
|
||||
@ -212,6 +215,16 @@ void loop() {
|
||||
} else if (hook==0) {
|
||||
if (dialedNumber==3) {
|
||||
serialSendVerify("AP\r", "AOK");
|
||||
} else if (dialedNumber==9) {
|
||||
if (commandToggle==1) {
|
||||
Serial.print("Command Mode Off\n");
|
||||
digitalWrite(commandPin, HIGH);
|
||||
commandToggle = 0;
|
||||
} else {
|
||||
Serial.print("Command Mode On\n");
|
||||
digitalWrite(commandPin, LOW);
|
||||
commandToggle = 1;
|
||||
}
|
||||
}
|
||||
} else if (hook==1 && state!=outgoingCall && state!=incomingCall && state!=activeCallInProgress && state!=threeWayWaiting && state!=threeWayHold && state!=threeWay && state!=incomingCallHold && state!=activeCall) {
|
||||
phoneNumber[numberCount] = dialedNumber;
|
||||
|
326
Code/Rotary_Player/Rotary Player.xcodeproj/project.pbxproj
Normal file
326
Code/Rotary_Player/Rotary Player.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,326 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
2A7C81F2189815CF00094EF7 /* MGMSound.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A7C81F1189815CF00094EF7 /* MGMSound.m */; };
|
||||
2AAEF920189365CB00E05D4F /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AAEF91F189365CB00E05D4F /* Cocoa.framework */; };
|
||||
2AAEF92A189365CB00E05D4F /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2AAEF928189365CB00E05D4F /* InfoPlist.strings */; };
|
||||
2AAEF92C189365CB00E05D4F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AAEF92B189365CB00E05D4F /* main.m */; };
|
||||
2AAEF930189365CB00E05D4F /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2AAEF92E189365CB00E05D4F /* Credits.rtf */; };
|
||||
2AAEF933189365CB00E05D4F /* MGMAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AAEF932189365CB00E05D4F /* MGMAppDelegate.m */; };
|
||||
2AAEF936189365CB00E05D4F /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2AAEF934189365CB00E05D4F /* MainMenu.xib */; };
|
||||
2AAEF93E1893660B00E05D4F /* MGMSerial.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AAEF93D1893660B00E05D4F /* MGMSerial.m */; };
|
||||
2AAEF940189367CD00E05D4F /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AAEF93F189367CD00E05D4F /* IOKit.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
2A7C81F0189815CF00094EF7 /* MGMSound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMSound.h; sourceTree = "<group>"; };
|
||||
2A7C81F1189815CF00094EF7 /* MGMSound.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMSound.m; sourceTree = "<group>"; };
|
||||
2AAEF91C189365CB00E05D4F /* Rotary Player.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Rotary Player.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2AAEF91F189365CB00E05D4F /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
2AAEF922189365CB00E05D4F /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
2AAEF923189365CB00E05D4F /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
2AAEF924189365CB00E05D4F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
2AAEF927189365CB00E05D4F /* Rotary Player-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Rotary Player-Info.plist"; sourceTree = "<group>"; };
|
||||
2AAEF929189365CB00E05D4F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
2AAEF92B189365CB00E05D4F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
2AAEF92D189365CB00E05D4F /* Rotary Player-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Rotary Player-Prefix.pch"; sourceTree = "<group>"; };
|
||||
2AAEF92F189365CB00E05D4F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
|
||||
2AAEF931189365CB00E05D4F /* MGMAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGMAppDelegate.h; sourceTree = "<group>"; };
|
||||
2AAEF932189365CB00E05D4F /* MGMAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGMAppDelegate.m; sourceTree = "<group>"; };
|
||||
2AAEF935189365CB00E05D4F /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
2AAEF93C1893660B00E05D4F /* MGMSerial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMSerial.h; sourceTree = "<group>"; };
|
||||
2AAEF93D1893660B00E05D4F /* MGMSerial.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMSerial.m; sourceTree = "<group>"; };
|
||||
2AAEF93F189367CD00E05D4F /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
2AAEF919189365CB00E05D4F /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2AAEF940189367CD00E05D4F /* IOKit.framework in Frameworks */,
|
||||
2AAEF920189365CB00E05D4F /* Cocoa.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
2AAEF913189365CB00E05D4F = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2AAEF925189365CB00E05D4F /* Rotary Player */,
|
||||
2AAEF91E189365CB00E05D4F /* Frameworks */,
|
||||
2AAEF91D189365CB00E05D4F /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2AAEF91D189365CB00E05D4F /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2AAEF91C189365CB00E05D4F /* Rotary Player.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2AAEF91E189365CB00E05D4F /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2AAEF93F189367CD00E05D4F /* IOKit.framework */,
|
||||
2AAEF91F189365CB00E05D4F /* Cocoa.framework */,
|
||||
2AAEF921189365CB00E05D4F /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2AAEF921189365CB00E05D4F /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2AAEF922189365CB00E05D4F /* AppKit.framework */,
|
||||
2AAEF923189365CB00E05D4F /* CoreData.framework */,
|
||||
2AAEF924189365CB00E05D4F /* Foundation.framework */,
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2AAEF925189365CB00E05D4F /* Rotary Player */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2AAEF931189365CB00E05D4F /* MGMAppDelegate.h */,
|
||||
2AAEF932189365CB00E05D4F /* MGMAppDelegate.m */,
|
||||
2AAEF934189365CB00E05D4F /* MainMenu.xib */,
|
||||
2AAEF926189365CB00E05D4F /* Supporting Files */,
|
||||
2AAEF93C1893660B00E05D4F /* MGMSerial.h */,
|
||||
2AAEF93D1893660B00E05D4F /* MGMSerial.m */,
|
||||
2A7C81F0189815CF00094EF7 /* MGMSound.h */,
|
||||
2A7C81F1189815CF00094EF7 /* MGMSound.m */,
|
||||
);
|
||||
path = "Rotary Player";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2AAEF926189365CB00E05D4F /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2AAEF927189365CB00E05D4F /* Rotary Player-Info.plist */,
|
||||
2AAEF928189365CB00E05D4F /* InfoPlist.strings */,
|
||||
2AAEF92B189365CB00E05D4F /* main.m */,
|
||||
2AAEF92D189365CB00E05D4F /* Rotary Player-Prefix.pch */,
|
||||
2AAEF92E189365CB00E05D4F /* Credits.rtf */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
2AAEF91B189365CB00E05D4F /* Rotary Player */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 2AAEF939189365CB00E05D4F /* Build configuration list for PBXNativeTarget "Rotary Player" */;
|
||||
buildPhases = (
|
||||
2AAEF918189365CB00E05D4F /* Sources */,
|
||||
2AAEF919189365CB00E05D4F /* Frameworks */,
|
||||
2AAEF91A189365CB00E05D4F /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "Rotary Player";
|
||||
productName = "Rotary Player";
|
||||
productReference = 2AAEF91C189365CB00E05D4F /* Rotary Player.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
2AAEF914189365CB00E05D4F /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
CLASSPREFIX = MGM;
|
||||
LastUpgradeCheck = 0460;
|
||||
ORGANIZATIONNAME = "Mr. Gecko's Media";
|
||||
};
|
||||
buildConfigurationList = 2AAEF917189365CB00E05D4F /* Build configuration list for PBXProject "Rotary Player" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 2AAEF913189365CB00E05D4F;
|
||||
productRefGroup = 2AAEF91D189365CB00E05D4F /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
2AAEF91B189365CB00E05D4F /* Rotary Player */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
2AAEF91A189365CB00E05D4F /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2AAEF92A189365CB00E05D4F /* InfoPlist.strings in Resources */,
|
||||
2AAEF930189365CB00E05D4F /* Credits.rtf in Resources */,
|
||||
2AAEF936189365CB00E05D4F /* MainMenu.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
2AAEF918189365CB00E05D4F /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2AAEF92C189365CB00E05D4F /* main.m in Sources */,
|
||||
2AAEF933189365CB00E05D4F /* MGMAppDelegate.m in Sources */,
|
||||
2AAEF93E1893660B00E05D4F /* MGMSerial.m in Sources */,
|
||||
2A7C81F2189815CF00094EF7 /* MGMSound.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
2AAEF928189365CB00E05D4F /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
2AAEF929189365CB00E05D4F /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2AAEF92E189365CB00E05D4F /* Credits.rtf */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
2AAEF92F189365CB00E05D4F /* en */,
|
||||
);
|
||||
name = Credits.rtf;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2AAEF934189365CB00E05D4F /* MainMenu.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
2AAEF935189365CB00E05D4F /* en */,
|
||||
);
|
||||
name = MainMenu.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
2AAEF937189365CB00E05D4F /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
2AAEF938189365CB00E05D4F /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
2AAEF93A189365CB00E05D4F /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Rotary Player/Rotary Player-Prefix.pch";
|
||||
INFOPLIST_FILE = "Rotary Player/Rotary Player-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
2AAEF93B189365CB00E05D4F /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Rotary Player/Rotary Player-Prefix.pch";
|
||||
INFOPLIST_FILE = "Rotary Player/Rotary Player-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
2AAEF917189365CB00E05D4F /* Build configuration list for PBXProject "Rotary Player" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
2AAEF937189365CB00E05D4F /* Debug */,
|
||||
2AAEF938189365CB00E05D4F /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
2AAEF939189365CB00E05D4F /* Build configuration list for PBXNativeTarget "Rotary Player" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
2AAEF93A189365CB00E05D4F /* Debug */,
|
||||
2AAEF93B189365CB00E05D4F /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 2AAEF914189365CB00E05D4F /* Project object */;
|
||||
}
|
7
Code/Rotary_Player/Rotary Player.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
Code/Rotary_Player/Rotary Player.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:Rotary Player.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
|
||||
<false/>
|
||||
<key>IDESourceControlProjectIdentifier</key>
|
||||
<string>0E4BB332-BC42-417B-807A-34777077B658</string>
|
||||
<key>IDESourceControlProjectName</key>
|
||||
<string>Rotary Player</string>
|
||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||
<dict>
|
||||
<key>9A28687E-3864-4112-AB75-1624B265E471</key>
|
||||
<string>ssh://github.com/GRMrGecko/Rotary-Gecko.git</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectPath</key>
|
||||
<string>Rotary Player/Rotary Player.xcodeproj/project.xcworkspace</string>
|
||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||
<dict>
|
||||
<key>9A28687E-3864-4112-AB75-1624B265E471</key>
|
||||
<string>../../..</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectURL</key>
|
||||
<string>ssh://github.com/GRMrGecko/Rotary-Gecko.git</string>
|
||||
<key>IDESourceControlProjectVersion</key>
|
||||
<integer>110</integer>
|
||||
<key>IDESourceControlProjectWCCIdentifier</key>
|
||||
<string>9A28687E-3864-4112-AB75-1624B265E471</string>
|
||||
<key>IDESourceControlProjectWCConfigurations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.git</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>9A28687E-3864-4112-AB75-1624B265E471</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>Rotary-Gecko</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0460"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "2AAEF91B189365CB00E05D4F"
|
||||
BuildableName = "Rotary Player.app"
|
||||
BlueprintName = "Rotary Player"
|
||||
ReferencedContainer = "container:Rotary Player.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "2AAEF91B189365CB00E05D4F"
|
||||
BuildableName = "Rotary Player.app"
|
||||
BlueprintName = "Rotary Player"
|
||||
ReferencedContainer = "container:Rotary Player.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "2AAEF91B189365CB00E05D4F"
|
||||
BuildableName = "Rotary Player.app"
|
||||
BlueprintName = "Rotary Player"
|
||||
ReferencedContainer = "container:Rotary Player.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "2AAEF91B189365CB00E05D4F"
|
||||
BuildableName = "Rotary Player.app"
|
||||
BlueprintName = "Rotary Player"
|
||||
ReferencedContainer = "container:Rotary Player.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>Rotary Player.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>2AAEF91B189365CB00E05D4F</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
34
Code/Rotary_Player/Rotary Player/MGMAppDelegate.h
Normal file
34
Code/Rotary_Player/Rotary Player/MGMAppDelegate.h
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// MGMAppDelegate.h
|
||||
// Rotary Player
|
||||
//
|
||||
// Created by Mr. Gecko's Media (James Coleman) on 1/28/14.
|
||||
// No Copyright Claimed. Public Domain.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@class MGMSound;
|
||||
|
||||
@interface MGMAppDelegate : NSObject <NSApplicationDelegate> {
|
||||
IBOutlet NSWindow *window;
|
||||
IBOutlet NSTextField *statusField;
|
||||
IBOutlet NSTextField *lastInfoField;
|
||||
|
||||
IBOutlet NSTextField *song1Field;
|
||||
IBOutlet NSTextField *song2Field;
|
||||
IBOutlet NSTextField *song3Field;
|
||||
IBOutlet NSTextField *song4Field;
|
||||
IBOutlet NSTextField *song5Field;
|
||||
IBOutlet NSTextField *song6Field;
|
||||
IBOutlet NSTextField *song7Field;
|
||||
IBOutlet NSTextField *song8Field;
|
||||
IBOutlet NSTextField *song9Field;
|
||||
|
||||
MGMSound *songPlaying;
|
||||
}
|
||||
- (IBAction)connect:(id)sender;
|
||||
- (IBAction)disconnect:(id)sender;
|
||||
|
||||
- (IBAction)chooseSong:(id)sender;
|
||||
@end
|
144
Code/Rotary_Player/Rotary Player/MGMAppDelegate.m
Normal file
144
Code/Rotary_Player/Rotary Player/MGMAppDelegate.m
Normal file
@ -0,0 +1,144 @@
|
||||
//
|
||||
// MGMAppDelegate.m
|
||||
// Rotary Player
|
||||
//
|
||||
// Created by Mr. Gecko's Media (James Coleman) on 1/28/14.
|
||||
// No Copyright Claimed. Public Domain.
|
||||
//
|
||||
|
||||
#import "MGMAppDelegate.h"
|
||||
|
||||
#import "MGMSerial.h"
|
||||
#import "MGMSound.h"
|
||||
|
||||
NSString * const serialPort = @"/dev/cu.RotaryGecko-SPPDev";
|
||||
NSString * const MGMSong1 = @"song1";
|
||||
NSString * const MGMSong2 = @"song2";
|
||||
NSString * const MGMSong3 = @"song3";
|
||||
NSString * const MGMSong4 = @"song4";
|
||||
NSString * const MGMSong5 = @"song5";
|
||||
NSString * const MGMSong6 = @"song6";
|
||||
NSString * const MGMSong7 = @"song7";
|
||||
NSString * const MGMSong8 = @"song8";
|
||||
NSString * const MGMSong9 = @"song9";
|
||||
|
||||
@implementation MGMAppDelegate
|
||||
- (void)awakeFromNib {
|
||||
MGMSerialPorts *ports = [MGMSerialPorts sharedSerialPorts];
|
||||
NSLog(@"%@", [ports serialPorts]);
|
||||
|
||||
NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
|
||||
if ([settings objectForKey:MGMSong1]!=nil)
|
||||
[song1Field setStringValue:[[[settings objectForKey:MGMSong1] lastPathComponent] stringByDeletingPathExtension]];
|
||||
if ([settings objectForKey:MGMSong2]!=nil)
|
||||
[song2Field setStringValue:[[[settings objectForKey:MGMSong2] lastPathComponent] stringByDeletingPathExtension]];
|
||||
if ([settings objectForKey:MGMSong3]!=nil)
|
||||
[song3Field setStringValue:[[[settings objectForKey:MGMSong3] lastPathComponent] stringByDeletingPathExtension]];
|
||||
if ([settings objectForKey:MGMSong4]!=nil)
|
||||
[song4Field setStringValue:[[[settings objectForKey:MGMSong4] lastPathComponent] stringByDeletingPathExtension]];
|
||||
if ([settings objectForKey:MGMSong5]!=nil)
|
||||
[song5Field setStringValue:[[[settings objectForKey:MGMSong5] lastPathComponent] stringByDeletingPathExtension]];
|
||||
if ([settings objectForKey:MGMSong6]!=nil)
|
||||
[song6Field setStringValue:[[[settings objectForKey:MGMSong6] lastPathComponent] stringByDeletingPathExtension]];
|
||||
if ([settings objectForKey:MGMSong7]!=nil)
|
||||
[song7Field setStringValue:[[[settings objectForKey:MGMSong7] lastPathComponent] stringByDeletingPathExtension]];
|
||||
if ([settings objectForKey:MGMSong8]!=nil)
|
||||
[song8Field setStringValue:[[[settings objectForKey:MGMSong8] lastPathComponent] stringByDeletingPathExtension]];
|
||||
if ([settings objectForKey:MGMSong9]!=nil)
|
||||
[song9Field setStringValue:[[[settings objectForKey:MGMSong9] lastPathComponent] stringByDeletingPathExtension]];
|
||||
}
|
||||
- (void)dealloc {
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (IBAction)connect:(id)sender {
|
||||
MGMSerialPort *port = [[MGMSerialPorts sharedSerialPorts] portForPath:serialPort];
|
||||
[port setSpeed:9600];
|
||||
if ([port open]) {
|
||||
[statusField setStringValue:@"Connected"];
|
||||
} else {
|
||||
[statusField setStringValue:@"Unable to Connect"];
|
||||
}
|
||||
[port setDelegate:self];
|
||||
NSLog(@"%@", port);
|
||||
|
||||
[port readDataInBackgroundNewLine];
|
||||
}
|
||||
- (IBAction)disconnect:(id)sender {
|
||||
[[[MGMSerialPorts sharedSerialPorts] portForPath:serialPort] close];
|
||||
[statusField setStringValue:@"Disconnected"];
|
||||
}
|
||||
|
||||
|
||||
- (void)serial:(MGMSerialPort *)thePort read:(NSData *)theBytes; {
|
||||
NSString *info = [[[NSString alloc] initWithData:theBytes encoding:NSUTF8StringEncoding] autorelease];
|
||||
[lastInfoField setStringValue:info];
|
||||
NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
|
||||
if ([info hasPrefix:@"Dialed: "]) {
|
||||
NSString *number = [info substringFromIndex:8];
|
||||
NSString *song = [NSString stringWithFormat:@"song%@", number];
|
||||
if ([settings objectForKey:song]!=nil) {
|
||||
if (songPlaying!=nil) {
|
||||
[songPlaying stop];
|
||||
[songPlaying release];
|
||||
}
|
||||
songPlaying = [[MGMSound alloc] initWithContentsOfFile:[settings objectForKey:song]];
|
||||
[songPlaying setDelegate:self];
|
||||
[songPlaying play];
|
||||
}
|
||||
NSLog(@"%@", info);
|
||||
} else if ([info hasPrefix:@"Hook: "]) {
|
||||
NSString *status = [info substringFromIndex:6];
|
||||
if ([status isEqual:@"0"] && songPlaying!=nil) {
|
||||
[songPlaying stop];
|
||||
[songPlaying release];
|
||||
songPlaying = nil;
|
||||
}
|
||||
NSLog(@"%@", info);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)soundDidFinishPlaying:(MGMSound *)theSound {
|
||||
[songPlaying release];
|
||||
songPlaying = nil;
|
||||
}
|
||||
|
||||
- (IBAction)chooseSong:(id)sender {
|
||||
NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setCanChooseDirectories:NO];
|
||||
[panel setCanChooseFiles:YES];
|
||||
long returnCode = [panel runModal];
|
||||
if (returnCode==NSOKButton) {
|
||||
NSString *path = [[panel URL] path];
|
||||
if ([[sender identifier] isEqual:@"1"]) {
|
||||
[song1Field setStringValue:[[path lastPathComponent] stringByDeletingPathExtension]];
|
||||
[settings setObject:path forKey:MGMSong1];
|
||||
} else if ([[sender identifier] isEqual:@"2"]) {
|
||||
[song2Field setStringValue:[[path lastPathComponent] stringByDeletingPathExtension]];
|
||||
[settings setObject:path forKey:MGMSong2];
|
||||
} else if ([[sender identifier] isEqual:@"3"]) {
|
||||
[song3Field setStringValue:[[path lastPathComponent] stringByDeletingPathExtension]];
|
||||
[settings setObject:path forKey:MGMSong3];
|
||||
} else if ([[sender identifier] isEqual:@"4"]) {
|
||||
[song4Field setStringValue:[[path lastPathComponent] stringByDeletingPathExtension]];
|
||||
[settings setObject:path forKey:MGMSong4];
|
||||
} else if ([[sender identifier] isEqual:@"5"]) {
|
||||
[song5Field setStringValue:[[path lastPathComponent] stringByDeletingPathExtension]];
|
||||
[settings setObject:path forKey:MGMSong5];
|
||||
} else if ([[sender identifier] isEqual:@"6"]) {
|
||||
[song6Field setStringValue:[[path lastPathComponent] stringByDeletingPathExtension]];
|
||||
[settings setObject:path forKey:MGMSong6];
|
||||
} else if ([[sender identifier] isEqual:@"7"]) {
|
||||
[song7Field setStringValue:[[path lastPathComponent] stringByDeletingPathExtension]];
|
||||
[settings setObject:path forKey:MGMSong7];
|
||||
} else if ([[sender identifier] isEqual:@"8"]) {
|
||||
[song8Field setStringValue:[[path lastPathComponent] stringByDeletingPathExtension]];
|
||||
[settings setObject:path forKey:MGMSong8];
|
||||
} else if ([[sender identifier] isEqual:@"9"]) {
|
||||
[song9Field setStringValue:[[path lastPathComponent] stringByDeletingPathExtension]];
|
||||
[settings setObject:path forKey:MGMSong9];
|
||||
}
|
||||
}
|
||||
}
|
||||
@end
|
70
Code/Rotary_Player/Rotary Player/MGMSerial.h
Normal file
70
Code/Rotary_Player/Rotary Player/MGMSerial.h
Normal file
@ -0,0 +1,70 @@
|
||||
//
|
||||
// MGMSerial.h
|
||||
// Rotary Player
|
||||
//
|
||||
// Created by Mr. Gecko's Media (James Coleman) on 1/28/14.
|
||||
// No Copyright Claimed. Public Domain.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
extern NSString * const MGMSerialPortsFoundNotification;
|
||||
extern NSString * const MGMSerialPortsRemovedNotification;
|
||||
|
||||
@class MGMSerialPort;
|
||||
|
||||
@interface MGMSerialPorts : NSObject {
|
||||
NSMutableArray *serialPorts;
|
||||
|
||||
IONotificationPortRef notificationPort;
|
||||
CFRunLoopSourceRef runLoop;
|
||||
}
|
||||
+ (id)sharedSerialPorts;
|
||||
|
||||
- (NSArray *)serialPorts;
|
||||
- (MGMSerialPort *)portForName:(NSString *)theName;
|
||||
- (MGMSerialPort *)portForPath:(NSString *)thePath;
|
||||
- (NSArray *)portsOfType:(NSString *)theType;
|
||||
@end
|
||||
|
||||
@protocol MGMSerialPortDelegate <NSObject>
|
||||
- (void)serial:(MGMSerialPort *)thePort read:(NSData *)theBytes;
|
||||
@end
|
||||
|
||||
@interface MGMSerialPort : NSObject {
|
||||
NSString *portPath;
|
||||
NSString *portName;
|
||||
NSString *portType;
|
||||
long portSpeed;
|
||||
int fileDescriptor;
|
||||
|
||||
id<MGMSerialPortDelegate> delegate;
|
||||
|
||||
NSLock *readLock;
|
||||
BOOL stopBackgroundRead;
|
||||
NSLock *closeLock;
|
||||
}
|
||||
+ (id)portWithPath:(NSString *)thePath name:(NSString *)theName type:(NSString *)theType speed:(int)theSpeed delegate:(id)theDelegate;
|
||||
- (id)initWithPath:(NSString *)thePath name:(NSString *)theName type:(NSString *)theType speed:(int)theSpeed delegate:(id)theDelegate;
|
||||
|
||||
- (NSString *)path;
|
||||
- (NSString *)name;
|
||||
- (NSString *)type;
|
||||
|
||||
- (BOOL)isOpen;
|
||||
- (BOOL)open;
|
||||
- (void)close;
|
||||
|
||||
- (long)speed;
|
||||
- (BOOL)setSpeed:(long)theSpeed;
|
||||
|
||||
- (id<MGMSerialPortDelegate>)delegate;
|
||||
- (void)setDelegate:(id)theDelegate;
|
||||
|
||||
- (BOOL)writeData:(NSData *)data;
|
||||
- (BOOL)writeString:(NSString *)string usingEncoding:(NSStringEncoding)encoding;
|
||||
|
||||
- (NSData *)readData:(int)theByteCount;
|
||||
- (BOOL)readDataInBackgroundNewLine;
|
||||
- (void)stopBackgroundRead;
|
||||
@end
|
348
Code/Rotary_Player/Rotary Player/MGMSerial.m
Normal file
348
Code/Rotary_Player/Rotary Player/MGMSerial.m
Normal file
@ -0,0 +1,348 @@
|
||||
//
|
||||
// MGMSerial.m
|
||||
// Rotary Player
|
||||
//
|
||||
// Created by Mr. Gecko's Media (James Coleman) on 1/28/14.
|
||||
// No Copyright Claimed. Public Domain.
|
||||
//
|
||||
|
||||
#import "MGMSerial.h"
|
||||
#import <IOKit/serial/IOSerialKeys.h>
|
||||
#import <IOKit/serial/ioss.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
NSString * const MGMSerialPortsFoundNotification = @"MGMSerialPortsFoundNotification";
|
||||
NSString * const MGMSerialPortsRemovedNotification = @"MGMSerialPortsRemovedNotification";
|
||||
|
||||
int const MGMSerialPortMaxLine = 4096;
|
||||
|
||||
@interface MGMSerialPorts (MGMPrivate)
|
||||
- (MGMSerialPort *)nextPort:(io_iterator_t)iterator;
|
||||
@end
|
||||
|
||||
@interface MGMSerialPort (MGMPrivate)
|
||||
|
||||
@end
|
||||
|
||||
|
||||
void MGMSerialPortFound(void *refcon, io_iterator_t iterator) {
|
||||
|
||||
}
|
||||
void MGMSerialPortDidRemove(void *refcon, io_iterator_t iterator) {
|
||||
|
||||
}
|
||||
|
||||
static MGMSerialPorts *MGMSharedSerialPorts = nil;
|
||||
|
||||
@implementation MGMSerialPorts
|
||||
+ (id)sharedSerialPorts {
|
||||
@synchronized(self) {
|
||||
if (MGMSharedSerialPorts==nil) {
|
||||
MGMSharedSerialPorts = [self new];
|
||||
}
|
||||
}
|
||||
return MGMSharedSerialPorts;
|
||||
}
|
||||
- (id)init {
|
||||
if ((self = [super init])) {
|
||||
serialPorts = [NSMutableArray new];
|
||||
|
||||
CFMutableDictionaryRef servicesMatch = IOServiceMatching(kIOSerialBSDServiceValue);
|
||||
if (servicesMatch!=NULL) {
|
||||
CFDictionarySetValue(servicesMatch, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes));
|
||||
CFMutableDictionaryRef servicesMatchRemoved = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, servicesMatch);
|
||||
|
||||
notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
|
||||
runLoop = IONotificationPortGetRunLoopSource(notificationPort);
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoop, kCFRunLoopDefaultMode);
|
||||
|
||||
|
||||
io_iterator_t found;
|
||||
kern_return_t result = IOServiceAddMatchingNotification(notificationPort, kIOPublishNotification, servicesMatch, MGMSerialPortFound, self, &found);
|
||||
if (result!=kIOReturnSuccess)
|
||||
NSLog(@"Unable to register for serial add %d", result);
|
||||
MGMSerialPort *port;
|
||||
while ((port = [self nextPort:found])) {
|
||||
[serialPorts addObject:port];
|
||||
}
|
||||
IOObjectRelease(found);
|
||||
|
||||
|
||||
result = IOServiceAddMatchingNotification(notificationPort, kIOTerminatedNotification, servicesMatchRemoved, MGMSerialPortDidRemove, self, &found);
|
||||
if (result!=kIOReturnSuccess) {
|
||||
NSLog(@"Unable to register for serial remove %d", result);
|
||||
} else {
|
||||
MGMSerialPort *port;
|
||||
while ((port = [self nextPort:found])) {
|
||||
[serialPorts removeObject:port];
|
||||
}
|
||||
IOObjectRelease(found);
|
||||
}
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (MGMSerialPort *)nextPort:(io_iterator_t)iterator {
|
||||
io_object_t serialPort = IOIteratorNext(iterator);
|
||||
if (serialPort != 0) {
|
||||
NSString *portName = [(NSString *)IORegistryEntryCreateCFProperty(serialPort, CFSTR(kIOTTYDeviceKey), kCFAllocatorDefault, 0) autorelease];
|
||||
NSString *portPath = [(NSString *)IORegistryEntryCreateCFProperty(serialPort, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0) autorelease];
|
||||
NSString *portType = [(NSString *)IORegistryEntryCreateCFProperty(serialPort, CFSTR(kIOSerialBSDTypeKey), kCFAllocatorDefault, 0) autorelease];
|
||||
IOObjectRelease(serialPort);
|
||||
if (portName!=nil && portPath!=nil) {
|
||||
MGMSerialPort *port = [self portForPath:portPath];
|
||||
if (port!=nil) {
|
||||
return port;
|
||||
}
|
||||
return [MGMSerialPort portWithPath:portPath name:portName type:portType speed:0 delegate:nil];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)portsFound:(io_iterator_t)found {
|
||||
NSMutableArray *addedPorts = [NSMutableArray array];
|
||||
MGMSerialPort *port;
|
||||
while ((port = [self nextPort:found])) {
|
||||
[serialPorts addObject:port];
|
||||
[addedPorts addObject:port];
|
||||
}
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MGMSerialPortsFoundNotification object:self userInfo:[NSDictionary dictionaryWithObject:addedPorts forKey:@"ports"]];
|
||||
}
|
||||
|
||||
- (void)postsRemoved:(io_iterator_t)removed {
|
||||
NSMutableArray *removedPorts = [NSMutableArray array];
|
||||
MGMSerialPort *port;
|
||||
while ((port = [self nextPort:removed])) {
|
||||
[port close];
|
||||
[removedPorts addObject:port];
|
||||
[serialPorts removeObject:port];
|
||||
}
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MGMSerialPortsRemovedNotification object:self userInfo:[NSDictionary dictionaryWithObject:removedPorts forKey:@"ports"]];
|
||||
}
|
||||
|
||||
- (NSArray *)serialPorts {
|
||||
return serialPorts;
|
||||
}
|
||||
- (MGMSerialPort *)portForName:(NSString *)portName {
|
||||
for (int i=0; i<[serialPorts count]; i++) {
|
||||
if ([[(MGMSerialPort *)[serialPorts objectAtIndex:i] name] isEqualToString:portName])
|
||||
return [serialPorts objectAtIndex:i];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
- (MGMSerialPort *)portForPath:(NSString *)portPath {
|
||||
for (int i=0; i<[serialPorts count]; i++) {
|
||||
if ([[(MGMSerialPort *)[serialPorts objectAtIndex:i] path] isEqualToString:portPath])
|
||||
return [serialPorts objectAtIndex:i];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
- (NSArray *)portsOfType:(NSString *)portType {
|
||||
NSMutableArray *ports = [NSMutableArray array];
|
||||
for (int i=0; i<[serialPorts count]; i++) {
|
||||
if ([[(MGMSerialPort *)[serialPorts objectAtIndex:i] type] isEqualToString:portType])
|
||||
[ports addObject:[serialPorts objectAtIndex:i]];
|
||||
}
|
||||
return ports;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MGMSerialPort
|
||||
+ (id)portWithPath:(NSString *)thePath name:(NSString *)theName type:(NSString *)theType speed:(int)theSpeed delegate:(id)theDelegate {
|
||||
return [[[self alloc] initWithPath:thePath name:theName type:theType speed:theSpeed delegate:theDelegate] autorelease];
|
||||
}
|
||||
- (id)initWithPath:(NSString *)thePath name:(NSString *)theName type:(NSString *)theType speed:(int)theSpeed delegate:(id)theDelegate {
|
||||
if ((self = [super init])) {
|
||||
portPath = [thePath copy];
|
||||
portName = [theName copy];
|
||||
portType = [theType copy];
|
||||
portSpeed = theSpeed;
|
||||
|
||||
fileDescriptor = -1;
|
||||
|
||||
readLock = [NSLock new];
|
||||
closeLock = [NSLock new];
|
||||
|
||||
delegate = [theDelegate retain];
|
||||
|
||||
stopBackgroundRead = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p %@ %@>", NSStringFromClass([self class]), self, portPath, portName];
|
||||
}
|
||||
- (NSString *)path {
|
||||
return portPath;
|
||||
}
|
||||
- (NSString *)name {
|
||||
return portName;
|
||||
}
|
||||
- (NSString *)type {
|
||||
return portType;
|
||||
}
|
||||
|
||||
- (BOOL)isOpen {
|
||||
return (fileDescriptor>=0);
|
||||
}
|
||||
- (BOOL)open {
|
||||
if (fileDescriptor>=0)
|
||||
return YES;
|
||||
fileDescriptor = open([portPath fileSystemRepresentation], O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
|
||||
if (fileDescriptor<0) {
|
||||
fileDescriptor = -1;
|
||||
NSLog(@"Unable to open.");
|
||||
return NO;
|
||||
} else if (portSpeed!=0) {
|
||||
speed_t newSpeed = portSpeed;
|
||||
int errorCode = ioctl(fileDescriptor, IOSSIOSPEED, &newSpeed, 1);
|
||||
if (errorCode==-1) {
|
||||
if (fileDescriptor>=0)
|
||||
close(fileDescriptor);
|
||||
fileDescriptor = -1;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
- (void)close {
|
||||
if (fileDescriptor>=0) {
|
||||
stopBackgroundRead = YES;
|
||||
[closeLock lock];
|
||||
|
||||
close(fileDescriptor);
|
||||
fileDescriptor = -1;
|
||||
|
||||
[closeLock unlock];
|
||||
}
|
||||
}
|
||||
|
||||
- (long)speed {
|
||||
return portSpeed;
|
||||
}
|
||||
- (BOOL)setSpeed:(long)theSpeed {
|
||||
if (fileDescriptor >= 0) {
|
||||
speed_t newSpeed = theSpeed;
|
||||
int errorCode = ioctl(fileDescriptor, IOSSIOSPEED, &newSpeed, 1);
|
||||
if (errorCode == -1) {
|
||||
return NO;
|
||||
} else {
|
||||
portSpeed = theSpeed;
|
||||
}
|
||||
} else {
|
||||
portSpeed = theSpeed;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id<MGMSerialPortDelegate>)delegate {
|
||||
return delegate;
|
||||
}
|
||||
- (void)setDelegate:(id)theDelegate {
|
||||
[delegate autorelease];
|
||||
delegate = [theDelegate retain];
|
||||
}
|
||||
|
||||
- (BOOL)writeData:(NSData *)data {
|
||||
const char *dataBytes = (const char *)[data bytes];
|
||||
NSUInteger dataLenth = [data length];
|
||||
ssize_t bytesWritten = 0;
|
||||
if (dataBytes!=NULL && dataLenth>0) {
|
||||
bytesWritten = write(fileDescriptor, dataBytes, dataLenth);
|
||||
if ((NSUInteger)bytesWritten==dataLenth) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
- (BOOL)writeString:(NSString *)string usingEncoding:(NSStringEncoding)encoding {
|
||||
return [self writeData:[string dataUsingEncoding:encoding]];
|
||||
}
|
||||
|
||||
- (NSData *)readData:(int)theByteCount {
|
||||
[readLock lock];
|
||||
[closeLock lock];
|
||||
|
||||
NSData *data = nil;
|
||||
void *buffer = malloc(theByteCount);
|
||||
ssize_t bytesRead = 0;
|
||||
fd_set *readFDs = NULL;
|
||||
|
||||
if (fileDescriptor>=0) {
|
||||
readFDs = (fd_set *)malloc(sizeof(fd_set));
|
||||
FD_ZERO(readFDs);
|
||||
FD_SET(fileDescriptor, readFDs);
|
||||
int result = select(fileDescriptor+1, readFDs, nil, nil, nil);
|
||||
if (result>=1 && fileDescriptor>=0)
|
||||
bytesRead = read(fileDescriptor, buffer, theByteCount);
|
||||
free(readFDs);
|
||||
readFDs = NULL;
|
||||
if (bytesRead==0) {
|
||||
[closeLock unlock];
|
||||
[readLock unlock];
|
||||
free(buffer);
|
||||
return nil;
|
||||
}
|
||||
data = [NSData dataWithBytes:buffer length:bytesRead];
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
|
||||
[closeLock unlock];
|
||||
[readLock unlock];
|
||||
return data;
|
||||
}
|
||||
- (BOOL)readDataInBackgroundNewLine {
|
||||
if ([delegate respondsToSelector:@selector(serial:read:)] && stopBackgroundRead && fileDescriptor>=0) {
|
||||
stopBackgroundRead = NO;
|
||||
[NSThread detachNewThreadSelector:@selector(readDataBackgroundThread) toTarget:self withObject:nil];
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
- (void)stopBackgroundRead {
|
||||
stopBackgroundRead = YES;
|
||||
}
|
||||
- (void)readDataBackgroundThread {
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
|
||||
while (!stopBackgroundRead) {
|
||||
NSMutableData *data = [NSMutableData new];
|
||||
|
||||
while (!stopBackgroundRead) {
|
||||
NSData *readData = [self readData:1];
|
||||
if (readData!=nil) {
|
||||
if (strcmp([readData bytes], "\n")==0 || strcmp([readData bytes], "\r")==0) {
|
||||
if ([data length]<=0)
|
||||
continue;
|
||||
break;
|
||||
} else {
|
||||
if ([data length]>=MGMSerialPortMaxLine)
|
||||
break;
|
||||
[data appendData:readData];
|
||||
}
|
||||
}
|
||||
[pool drain];
|
||||
pool = [NSAutoreleasePool new];
|
||||
}
|
||||
|
||||
if ([data length]>0 && !stopBackgroundRead) {
|
||||
SEL readSelector = @selector(serial:read:);
|
||||
NSMethodSignature *signature = [(NSObject *)delegate methodSignatureForSelector:readSelector];
|
||||
if (signature!=nil) {
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||
[invocation setSelector:readSelector];
|
||||
[invocation setArgument:&self atIndex:2];
|
||||
[invocation setArgument:&data atIndex:3];
|
||||
[invocation performSelectorOnMainThread:@selector(invokeWithTarget:) withObject:delegate waitUntilDone:YES];
|
||||
}
|
||||
}
|
||||
|
||||
[data release];
|
||||
}
|
||||
|
||||
[pool drain];
|
||||
}
|
||||
@end
|
65
Code/Rotary_Player/Rotary Player/MGMSound.h
Normal file
65
Code/Rotary_Player/Rotary Player/MGMSound.h
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// MGMSound.h
|
||||
// SoundNote
|
||||
//
|
||||
// Created by Mr. Gecko on 9/23/10.
|
||||
// Copyright (c) 2014 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||
// with or without fee is hereby granted, provided that the above copyright notice
|
||||
// and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
//
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#else
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
|
||||
@class MGMSound;
|
||||
|
||||
@protocol MGMSoundDelegate <NSObject>
|
||||
- (void)soundDidFinishPlaying:(MGMSound *)theSound;
|
||||
@end
|
||||
|
||||
@protocol NSSoundDelegate;
|
||||
|
||||
@interface MGMSound : NSObject
|
||||
#if TARGET_OS_IPHONE
|
||||
<AVAudioPlayerDelegate>
|
||||
#else
|
||||
<NSSoundDelegate>
|
||||
#endif
|
||||
{
|
||||
#if TARGET_OS_IPHONE
|
||||
AVAudioPlayer *sound;
|
||||
#else
|
||||
NSSound *sound;
|
||||
#endif
|
||||
id<MGMSoundDelegate> delegate;
|
||||
|
||||
BOOL loops;
|
||||
}
|
||||
- (id)initWithContentsOfFile:(NSString *)theFile;
|
||||
- (id)initWithContentsOfURL:(NSURL *)theURL;
|
||||
- (id)initWithData:(NSData *)theData;
|
||||
|
||||
- (void)setDelegate:(id)theDelegate;
|
||||
- (id<MGMSoundDelegate>)delegate;
|
||||
|
||||
- (void)setLoops:(BOOL)shouldLoop;
|
||||
- (BOOL)loops;
|
||||
|
||||
- (void)play;
|
||||
- (void)pause;
|
||||
- (void)stop;
|
||||
- (BOOL)isPlaying;
|
||||
@end
|
109
Code/Rotary_Player/Rotary Player/MGMSound.m
Normal file
109
Code/Rotary_Player/Rotary Player/MGMSound.m
Normal file
@ -0,0 +1,109 @@
|
||||
//
|
||||
// MGMSound.m
|
||||
// SoundNote
|
||||
//
|
||||
// Created by Mr. Gecko on 9/23/10.
|
||||
// Copyright (c) 2014 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||
// with or without fee is hereby granted, provided that the above copyright notice
|
||||
// and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
//
|
||||
|
||||
#import "MGMSound.h"
|
||||
|
||||
@implementation MGMSound
|
||||
- (id)init {
|
||||
if ((self = [super init])) {
|
||||
loops = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (id)initWithContentsOfFile:(NSString *)theFile {
|
||||
return [self initWithContentsOfURL:[NSURL fileURLWithPath:theFile]];
|
||||
}
|
||||
- (id)initWithContentsOfURL:(NSURL *)theURL {
|
||||
if ((self = [self init])) {
|
||||
#if TARGET_OS_IPHONE
|
||||
sound = [[AVAudioPlayer alloc] initWithContentsOfURL:theURL error:nil];
|
||||
#else
|
||||
sound = [[NSSound alloc] initWithContentsOfURL:theURL byReference:YES];
|
||||
#endif
|
||||
[sound setDelegate:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (id)initWithData:(NSData *)theData {
|
||||
if ((self = [self init])) {
|
||||
#if TARGET_OS_IPHONE
|
||||
sound = [[AVAudioPlayer alloc] initWithData:theData error:nil];
|
||||
#else
|
||||
sound = [[NSSound alloc] initWithData:theData];
|
||||
#endif
|
||||
[sound setDelegate:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (void)dealloc {
|
||||
[sound setDelegate:nil];
|
||||
[sound stop];
|
||||
[sound release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)setDelegate:(id)theDelegate {
|
||||
delegate = theDelegate;
|
||||
}
|
||||
- (id<MGMSoundDelegate>)delegate {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
|
||||
if (loops) {
|
||||
[sound stop];
|
||||
[sound play];
|
||||
} else {
|
||||
if (delegate!=nil && [delegate respondsToSelector:@selector(soundDidFinishPlaying:)]) [delegate soundDidFinishPlaying:self];
|
||||
}
|
||||
}
|
||||
#else
|
||||
- (void)sound:(NSSound *)theSound didFinishPlaying:(BOOL)finishedPlaying {
|
||||
if (finishedPlaying) {
|
||||
if (loops) {
|
||||
[sound stop];
|
||||
[sound play];
|
||||
} else {
|
||||
if (delegate!=nil && [delegate respondsToSelector:@selector(soundDidFinishPlaying:)]) [delegate soundDidFinishPlaying:self];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)setLoops:(BOOL)shouldLoop {
|
||||
loops = shouldLoop;
|
||||
}
|
||||
- (BOOL)loops {
|
||||
return loops;
|
||||
}
|
||||
|
||||
- (void)play {
|
||||
[sound performSelectorOnMainThread:@selector(play) withObject:nil waitUntilDone:YES];
|
||||
}
|
||||
- (void)pause {
|
||||
[sound pause];
|
||||
}
|
||||
- (void)stop {
|
||||
[sound stop];
|
||||
}
|
||||
- (BOOL)isPlaying {
|
||||
return [sound isPlaying];
|
||||
}
|
||||
@end
|
34
Code/Rotary_Player/Rotary Player/Rotary Player-Info.plist
Normal file
34
Code/Rotary_Player/Rotary Player/Rotary Player-Info.plist
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.mrgeckosmedia.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014 Mr. Gecko's Media. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,7 @@
|
||||
//
|
||||
// Prefix header for all source files of the 'Rotary Player' target in the 'Rotary Player' project
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
29
Code/Rotary_Player/Rotary Player/en.lproj/Credits.rtf
Normal file
29
Code/Rotary_Player/Rotary Player/en.lproj/Credits.rtf
Normal file
@ -0,0 +1,29 @@
|
||||
{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\paperw9840\paperh8400
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
|
||||
|
||||
\f0\b\fs24 \cf0 Engineering:
|
||||
\b0 \
|
||||
Some people\
|
||||
\
|
||||
|
||||
\b Human Interface Design:
|
||||
\b0 \
|
||||
Some other people\
|
||||
\
|
||||
|
||||
\b Testing:
|
||||
\b0 \
|
||||
Hopefully not nobody\
|
||||
\
|
||||
|
||||
\b Documentation:
|
||||
\b0 \
|
||||
Whoever\
|
||||
\
|
||||
|
||||
\b With special thanks to:
|
||||
\b0 \
|
||||
Mom\
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
6531
Code/Rotary_Player/Rotary Player/en.lproj/MainMenu.xib
Normal file
6531
Code/Rotary_Player/Rotary Player/en.lproj/MainMenu.xib
Normal file
File diff suppressed because it is too large
Load Diff
14
Code/Rotary_Player/Rotary Player/main.m
Normal file
14
Code/Rotary_Player/Rotary Player/main.m
Normal file
@ -0,0 +1,14 @@
|
||||
//
|
||||
// main.m
|
||||
// Rotary Player
|
||||
//
|
||||
// Created by James Coleman on 1/24/14.
|
||||
// Copyright (c) 2014 Mr. Gecko's Media. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
return NSApplicationMain(argc, (const char **)argv);
|
||||
}
|
116
Code/Rotary_Player_Firmware/Rotary_Player_Firmware.ino
Normal file
116
Code/Rotary_Player_Firmware/Rotary_Player_Firmware.ino
Normal file
@ -0,0 +1,116 @@
|
||||
//
|
||||
// Rotary_Player_Firmware.ino
|
||||
//
|
||||
// Created by Mr. Gecko's Media (James Coleman) on 1/28/14.
|
||||
// No Copyright Claimed. Public Domain.
|
||||
//
|
||||
|
||||
#include <SoftwareSerial.h>
|
||||
|
||||
SoftwareSerial btSerial(2,3); // RX,TX
|
||||
int eventPin = 4;
|
||||
int eventValue = 1;
|
||||
int commandPin = 5;
|
||||
|
||||
int hookPin = 6;
|
||||
int hookValue = 1;
|
||||
int startPosPin = 7;
|
||||
int startPosValue = 1;
|
||||
int rotaryPin = 8;
|
||||
int rotaryValue = 1;
|
||||
int dialedNumber = 0;
|
||||
|
||||
int speakerShutOffPin = 9;
|
||||
int speakerShutOffToggle = 0;
|
||||
|
||||
void setup() {
|
||||
// Setup Serial Interfaces.
|
||||
Serial.begin(9600);
|
||||
btSerial.begin(9600);
|
||||
|
||||
// Setup Pins.
|
||||
pinMode(eventPin, INPUT);
|
||||
pinMode(commandPin, OUTPUT);
|
||||
digitalWrite(commandPin, HIGH);
|
||||
|
||||
pinMode(hookPin, INPUT_PULLUP);
|
||||
pinMode(startPosPin, INPUT_PULLUP);
|
||||
pinMode(rotaryPin, INPUT_PULLUP);
|
||||
pinMode(speakerShutOffPin, OUTPUT);
|
||||
|
||||
// Allow for RN-52 to play startup tone.
|
||||
digitalWrite(speakerShutOffPin, HIGH);
|
||||
delay(1000);
|
||||
digitalWrite(speakerShutOffPin, LOW);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (btSerial.available())
|
||||
Serial.write(btSerial.read());
|
||||
if (Serial.available()) {
|
||||
btSerial.write(Serial.read());
|
||||
}
|
||||
|
||||
// Gather information from the pins to work with.
|
||||
int hook = digitalRead(hookPin);
|
||||
int hookChanged = (hookValue!=hook);
|
||||
hookValue = hook;
|
||||
|
||||
int startPos = digitalRead(startPosPin);
|
||||
int startPosChanged = (startPosValue!=startPos);
|
||||
startPosValue = startPos;
|
||||
|
||||
int rotary = digitalRead(rotaryPin);
|
||||
int rotaryChanged = (rotaryValue!=rotary);
|
||||
rotaryValue = rotary;
|
||||
|
||||
// Debug Code.
|
||||
if (hookChanged) {
|
||||
Serial.print("Hook: ");
|
||||
Serial.print(hook);
|
||||
Serial.print("\n");
|
||||
btSerial.print("Hook: ");
|
||||
btSerial.print(hook);
|
||||
btSerial.print("\n");
|
||||
}
|
||||
if (startPosChanged) {
|
||||
Serial.print("Start Position: ");
|
||||
Serial.print(startPos);
|
||||
Serial.print("\n");
|
||||
}
|
||||
if (rotaryChanged) {
|
||||
Serial.print("Rotary: ");
|
||||
Serial.print(rotary);
|
||||
Serial.print("\n");
|
||||
}
|
||||
|
||||
if (startPosChanged) {
|
||||
if (startPos==0) {
|
||||
dialedNumber = 0;
|
||||
} else {
|
||||
if (dialedNumber!=0) {
|
||||
if (dialedNumber>=10)
|
||||
dialedNumber = 0;
|
||||
Serial.print("Dialed: ");
|
||||
Serial.print(dialedNumber);
|
||||
Serial.print("\n");
|
||||
btSerial.print("Dialed: ");
|
||||
btSerial.print(dialedNumber);
|
||||
btSerial.print("\n");
|
||||
if (dialedNumber==0) {
|
||||
if (speakerShutOffToggle==0) {
|
||||
speakerShutOffToggle = 1;
|
||||
digitalWrite(speakerShutOffPin, HIGH);
|
||||
} else {
|
||||
speakerShutOffToggle = 0;
|
||||
digitalWrite(speakerShutOffPin, LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (startPos==0 && rotaryChanged && rotary==0) {
|
||||
dialedNumber++;
|
||||
delay(50);
|
||||
}
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
|
||||
Rtoary Gecko is my work to convert a Rotary Phone into a Bluetooth Phone. You can dial numbers, and answer phone calls with your cell phone as the man in the middle that provides cell service.
|
||||
|
||||
The documents stored here are the major documents needed to make a Rotary Phone Bluetooth. To read my quest to build this Phone, visit my blog at http://mrgecko.org. To get videos/photos and documentation to the hardware which I collected, you can visit my bitcasa share at http://l.bitcasa.com/P8xOdiBa.
|
||||
The documents stored here are the major documents needed to make a Rotary Phone Bluetooth. To read my quest to build this Phone, visit my blog at http://mrgecko.org. To get videos/photos and documentation to the hardware which I collected, you can visit my bitcasa share at http://l.bitcasa.com/P3r9r6d1.
|
||||
|
||||
As I do with every code I write, I make it fairly easy to understand with my naming conventions, so there are no comments to explain things, you should be able to just read it and know what it does.
|
||||
As I do with every code I write, I make it fairly easy to understand with my naming conventions, so there are not many comments to explain things, you should be able to just read it and know what it does.
|
||||
|
||||
I would like to give a big thank you to crashcartpro in ##gen (freenode) and myself/others in #sparkfun (freenode). They all helped me out considerbly with understanding this stuff and completing this phone.
|
||||
I would like to give a big thank you to crashcartpro in ##gen (freenode) and myself/others in #sparkfun (freenode). They all helped me out considerably with understanding this stuff and completing this phone.
|
Loading…
Reference in New Issue
Block a user