├── .travis.yml ├── Arduino-SoftModem ├── Receiver.ino ├── SoftModem.cpp ├── SoftModem.h ├── Transmitter.ino └── keywords.txt ├── FSK-Arduino-iOS.podspec ├── FSK-Demo ├── FSK-Demo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── FSK-Demo.xccheckout │ │ └── xcuserdata │ │ │ └── ezefranca.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── FSK-Demo.xcscheme │ └── xcuserdata │ │ └── ezefranca.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── FSK-Demo.xcscheme ├── FSK-Demo.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── FSK-Demo.xccheckout │ └── xcuserdata │ │ └── ezefranca.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── FSK-Demo │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── AudioDemo.h │ ├── AudioDemo.m │ ├── Base.lproj │ │ ├── Main_iPad.storyboard │ │ └── Main_iPhone.storyboard │ ├── Class │ │ ├── FK │ │ │ ├── NSString+HexColor.h │ │ │ ├── NSString+HexColor.m │ │ │ └── UIView+Layout.h │ │ └── SoftModem │ │ │ ├── AudioQueueObject.h │ │ │ ├── AudioQueueObject.m │ │ │ ├── AudioSignalAnalyzer.h │ │ │ ├── AudioSignalAnalyzer.m │ │ │ ├── AudioSignalGenerator.h │ │ │ ├── AudioSignalGenerator.m │ │ │ ├── CharReceiver.h │ │ │ ├── FSKByteQueue.h │ │ │ ├── FSKModemConfig.h │ │ │ ├── FSKRecognizer.h │ │ │ ├── FSKRecognizer.mm │ │ │ ├── FSKSerialGenerator.h │ │ │ ├── FSKSerialGenerator.mm │ │ │ ├── MultiDelegate.h │ │ │ ├── MultiDelegate.m │ │ │ ├── PatternRecognizer.h │ │ │ └── lockfree.h │ ├── FSK-Demo-Info.plist │ ├── FSK-Demo-Prefix.pch │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── ViewController.h │ ├── ViewController.m │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── framework.png │ └── main.m ├── FSK-DemoTests │ ├── FSK-DemoTests-Info.plist │ ├── FSK_DemoTests.m │ └── en.lproj │ │ └── InfoPlist.strings └── image.png ├── FSK ├── AudioQueueObject.h ├── AudioQueueObject.m ├── AudioSignalAnalyzer.h ├── AudioSignalAnalyzer.m ├── AudioSignalGenerator.h ├── AudioSignalGenerator.m ├── CharReceiver.h ├── FSKByteQueue.h ├── FSKModemConfig.h ├── FSKRecognizer.h ├── FSKRecognizer.mm ├── FSKSerialGenerator.h ├── FSKSerialGenerator.mm ├── MultiDelegate.h ├── MultiDelegate.m ├── NSString+HexColor.h ├── NSString+HexColor.m ├── PatternRecognizer.h ├── UIView+Layout.h └── lockfree.h ├── LICENSE ├── README.md ├── appveyor.yml └── wercker.yml /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | before_install: 3 | - cd FSK-Demo 4 | script: xcodebuild -workspace FSK-Demo.xcworkspace -scheme FSK-Demo -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO 5 | -------------------------------------------------------------------------------- /Arduino-SoftModem/Receiver.ino: -------------------------------------------------------------------------------- 1 | #include 2 | SoftModem modem; 3 | int dat; 4 | 5 | void setup() 6 | { 7 | modem.begin(); 8 | Serial.begin(115200); 9 | pinMode(13,OUTPUT); 10 | } 11 | void loop() 12 | { 13 | if(modem.available()) 14 | { 15 | dat = modem.read(); 16 | if(dat == 'C') 17 | { 18 | Serial.write('Y'); 19 | digitalWrite(13,HIGH); 20 | } 21 | else 22 | { 23 | Serial.write('N'); 24 | digitalWrite(13,LOW); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Arduino-SoftModem/SoftModem.cpp: -------------------------------------------------------------------------------- 1 | #include "SoftModem.h" 2 | 3 | #define TX_PIN (3) 4 | #define RX_PIN1 (6) // AIN0 5 | #define RX_PIN2 (7) // AIN1 6 | 7 | SoftModem *SoftModem::activeObject = 0; 8 | 9 | SoftModem::SoftModem() { 10 | } 11 | 12 | SoftModem::~SoftModem() { 13 | end(); 14 | } 15 | 16 | #if F_CPU == 16000000 17 | #if SOFT_MODEM_BAUD_RATE <= 126 18 | #define TIMER_CLOCK_SELECT (7) 19 | #define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(1024)) 20 | #elif SOFT_MODEM_BAUD_RATE <= 315 21 | #define TIMER_CLOCK_SELECT (6) 22 | #define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(256)) 23 | #elif SOFT_MODEM_BAUD_RATE <= 630 24 | #define TIMER_CLOCK_SELECT (5) 25 | #define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(128)) 26 | #elif SOFT_MODEM_BAUD_RATE <= 1225 27 | #define TIMER_CLOCK_SELECT (4) 28 | #define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(64)) 29 | #else 30 | #define TIMER_CLOCK_SELECT (3) 31 | #define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(32)) 32 | #endif 33 | #else 34 | #if SOFT_MODEM_BAUD_RATE <= 126 35 | #define TIMER_CLOCK_SELECT (6) 36 | #define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(256)) 37 | #elif SOFT_MODEM_BAUD_RATE <= 315 38 | #define TIMER_CLOCK_SELECT (5) 39 | #define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(128)) 40 | #elif SOFT_MODEM_BAUD_RATE <= 630 41 | #define TIMER_CLOCK_SELECT (4) 42 | #define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(64)) 43 | #else 44 | #define TIMER_CLOCK_SELECT (3) 45 | #define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(32)) 46 | #endif 47 | #endif 48 | 49 | #define BIT_PERIOD (1000000/SOFT_MODEM_BAUD_RATE) 50 | #define HIGH_FREQ_MICROS (1000000/SOFT_MODEM_HIGH_FREQ) 51 | #define LOW_FREQ_MICROS (1000000/SOFT_MODEM_LOW_FREQ) 52 | 53 | #define HIGH_FREQ_CNT (BIT_PERIOD/HIGH_FREQ_MICROS) 54 | #define LOW_FREQ_CNT (BIT_PERIOD/LOW_FREQ_MICROS) 55 | 56 | #define MAX_CARRIR_BITS (40000/BIT_PERIOD) // 40ms 57 | 58 | #define TCNT_BIT_PERIOD (BIT_PERIOD/MICROS_PER_TIMER_COUNT) 59 | #define TCNT_HIGH_FREQ (HIGH_FREQ_MICROS/MICROS_PER_TIMER_COUNT) 60 | #define TCNT_LOW_FREQ (LOW_FREQ_MICROS/MICROS_PER_TIMER_COUNT) 61 | 62 | #define TCNT_HIGH_TH_L (TCNT_HIGH_FREQ * 0.80) 63 | #define TCNT_HIGH_TH_H (TCNT_HIGH_FREQ * 1.15) 64 | #define TCNT_LOW_TH_L (TCNT_LOW_FREQ * 0.85) 65 | #define TCNT_LOW_TH_H (TCNT_LOW_FREQ * 1.20) 66 | 67 | #if SOFT_MODEM_DEBUG_ENABLE 68 | static volatile uint8_t *_portLEDReg; 69 | static uint8_t _portLEDMask; 70 | #endif 71 | 72 | enum { START_BIT = 0, DATA_BIT = 8, STOP_BIT = 9, INACTIVE = 0xff }; 73 | 74 | void SoftModem::begin(void) 75 | { 76 | pinMode(RX_PIN1, INPUT); 77 | digitalWrite(RX_PIN1, LOW); 78 | 79 | pinMode(RX_PIN2, INPUT); 80 | digitalWrite(RX_PIN2, LOW); 81 | 82 | pinMode(TX_PIN, OUTPUT); 83 | digitalWrite(TX_PIN, LOW); 84 | 85 | _txPortReg = portOutputRegister(digitalPinToPort(TX_PIN)); 86 | _txPortMask = digitalPinToBitMask(TX_PIN); 87 | 88 | #if SOFT_MODEM_DEBUG_ENABLE 89 | _portLEDReg = portOutputRegister(digitalPinToPort(13)); 90 | _portLEDMask = digitalPinToBitMask(13); 91 | pinMode(13, OUTPUT); 92 | #endif 93 | 94 | _recvStat = INACTIVE; 95 | _recvBufferHead = _recvBufferTail = 0; 96 | 97 | SoftModem::activeObject = this; 98 | 99 | _lastTCNT = TCNT2; 100 | _lastDiff = _lowCount = _highCount = 0; 101 | 102 | TCCR2A = 0; 103 | TCCR2B = TIMER_CLOCK_SELECT; 104 | ACSR = _BV(ACIE) | _BV(ACIS1); 105 | DIDR1 = _BV(AIN1D) | _BV(AIN0D); // digital port off 106 | } 107 | 108 | void SoftModem::end(void) 109 | { 110 | ACSR &= ~(_BV(ACIE)); 111 | TIMSK2 &= ~(_BV(OCIE2A)); 112 | DIDR1 &= ~(_BV(AIN1D) | _BV(AIN0D)); 113 | SoftModem::activeObject = 0; 114 | } 115 | 116 | void SoftModem::demodulate(void) 117 | { 118 | uint8_t t = TCNT2; 119 | uint8_t diff; 120 | 121 | if(TIFR2 & _BV(TOV2)){ 122 | TIFR2 |= _BV(TOV2); 123 | diff = (255 - _lastTCNT) + t + 1; 124 | } 125 | else{ 126 | diff = t - _lastTCNT; 127 | } 128 | 129 | if(diff < (uint8_t)(TCNT_HIGH_TH_L)) // Noise? 130 | return; 131 | 132 | _lastTCNT = t; 133 | 134 | if(diff > (uint8_t)(TCNT_LOW_TH_H)) 135 | return; 136 | 137 | // _lastDiff = (diff >> 1) + (diff >> 2) + (_lastDiff >> 2); 138 | _lastDiff = diff; 139 | 140 | if(_lastDiff >= (uint8_t)(TCNT_LOW_TH_L)){ 141 | _lowCount += _lastDiff; 142 | if((_recvStat == INACTIVE) && (_lowCount >= (uint8_t)(TCNT_BIT_PERIOD * 0.5))){ // maybe Start-Bit 143 | _recvStat = START_BIT; 144 | _highCount = 0; 145 | _recvBits = 0; 146 | OCR2A = t + (uint8_t)(TCNT_BIT_PERIOD) - _lowCount; // 1 bit period after detected 147 | TIFR2 |= _BV(OCF2A); 148 | TIMSK2 |= _BV(OCIE2A); 149 | } 150 | } 151 | else if(_lastDiff <= (uint8_t)(TCNT_HIGH_TH_H)){ 152 | _highCount += _lastDiff; 153 | if((_recvStat == INACTIVE) && (_highCount >= (uint8_t)(TCNT_BIT_PERIOD))){ 154 | _lowCount = _highCount = 0; 155 | } 156 | } 157 | } 158 | 159 | ISR(ANALOG_COMP_vect) 160 | { 161 | SoftModem::activeObject->demodulate(); 162 | } 163 | 164 | void SoftModem::recv(void) 165 | { 166 | uint8_t high; 167 | if(_highCount > _lowCount){ 168 | if(_highCount >= (uint8_t)TCNT_BIT_PERIOD) 169 | _highCount -= (uint8_t)TCNT_BIT_PERIOD; 170 | else 171 | _highCount = 0; 172 | high = 0x80; 173 | } 174 | else{ 175 | if(_lowCount >= (uint8_t)TCNT_BIT_PERIOD) 176 | _lowCount -= (uint8_t)TCNT_BIT_PERIOD; 177 | else 178 | _lowCount = 0; 179 | high = 0x00; 180 | } 181 | 182 | if(_recvStat == START_BIT){ // Start bit 183 | if(!high){ 184 | _recvStat++; 185 | }else{ 186 | goto end_recv; 187 | } 188 | } 189 | else if(_recvStat <= DATA_BIT) { // Data bits 190 | _recvBits >>= 1; 191 | _recvBits |= high; 192 | _recvStat++; 193 | } 194 | else if(_recvStat == STOP_BIT){ // Stop bit 195 | uint8_t new_tail = (_recvBufferTail + 1) & (SOFT_MODEM_RX_BUF_SIZE - 1); 196 | if(new_tail != _recvBufferHead){ 197 | _recvBuffer[_recvBufferTail] = _recvBits; 198 | _recvBufferTail = new_tail; 199 | } 200 | goto end_recv; 201 | } 202 | else{ 203 | end_recv: 204 | _recvStat = INACTIVE; 205 | TIMSK2 &= ~_BV(OCIE2A); 206 | } 207 | } 208 | 209 | ISR(TIMER2_COMPA_vect) 210 | { 211 | OCR2A += (uint8_t)TCNT_BIT_PERIOD; 212 | SoftModem::activeObject->recv(); 213 | #if SOFT_MODEM_DEBUG_ENABLE 214 | *_portLEDReg ^= _portLEDMask; 215 | #endif 216 | } 217 | 218 | int SoftModem::available() 219 | { 220 | return (_recvBufferTail + SOFT_MODEM_RX_BUF_SIZE - _recvBufferHead) & (SOFT_MODEM_RX_BUF_SIZE - 1); 221 | } 222 | 223 | int SoftModem::read() 224 | { 225 | if(_recvBufferHead == _recvBufferTail) 226 | return -1; 227 | int d = _recvBuffer[_recvBufferHead]; 228 | _recvBufferHead = (_recvBufferHead + 1) & (SOFT_MODEM_RX_BUF_SIZE - 1); 229 | return d; 230 | } 231 | 232 | int SoftModem::peek() 233 | { 234 | if(_recvBufferHead == _recvBufferTail) 235 | return -1; 236 | return _recvBuffer[_recvBufferHead]; 237 | } 238 | 239 | void SoftModem::flush() 240 | { 241 | _recvBufferHead = _recvBufferTail = 0; 242 | } 243 | 244 | void SoftModem::modulate(uint8_t b) 245 | { 246 | uint8_t cnt,tcnt,tcnt2; 247 | if(b){ 248 | cnt = (uint8_t)(HIGH_FREQ_CNT); 249 | tcnt2 = (uint8_t)(TCNT_HIGH_FREQ / 2); 250 | tcnt = (uint8_t)(TCNT_HIGH_FREQ) - tcnt2; 251 | }else{ 252 | cnt = (uint8_t)(LOW_FREQ_CNT); 253 | tcnt2 = (uint8_t)(TCNT_LOW_FREQ / 2); 254 | tcnt = (uint8_t)(TCNT_LOW_FREQ) - tcnt2; 255 | } 256 | do { 257 | cnt--; 258 | { 259 | OCR2B += tcnt; 260 | TIFR2 |= _BV(OCF2B); 261 | while(!(TIFR2 & _BV(OCF2B))); 262 | } 263 | *_txPortReg ^= _txPortMask; 264 | { 265 | OCR2B += tcnt2; 266 | TIFR2 |= _BV(OCF2B); 267 | while(!(TIFR2 & _BV(OCF2B))); 268 | } 269 | *_txPortReg ^= _txPortMask; 270 | } while (cnt); 271 | } 272 | 273 | // Brief carrier tone before each transmission 274 | // 1 start bit (LOW) 275 | // 8 data bits, LSB first 276 | // 1 stop bit (HIGH) 277 | // ... 278 | // 1 push bit (HIGH) 279 | 280 | size_t SoftModem::write(const uint8_t *buffer, size_t size) 281 | { 282 | uint8_t cnt = ((micros() - _lastWriteTime) / BIT_PERIOD) + 1; 283 | if(cnt > MAX_CARRIR_BITS) 284 | cnt = MAX_CARRIR_BITS; 285 | for(uint8_t i = 0; i 5 | 6 | //#define SOFT_MODEM_BAUD_RATE (126) 7 | //#define SOFT_MODEM_LOW_FREQ (882) 8 | //#define SOFT_MODEM_HIGH_FREQ (1764) 9 | //#define SOFT_MODEM_RX_BUF_SIZE (4) 10 | 11 | //#define SOFT_MODEM_BAUD_RATE (315) 12 | //#define SOFT_MODEM_LOW_FREQ (1575) 13 | //#define SOFT_MODEM_HIGH_FREQ (3150) 14 | //#define SOFT_MODEM_RX_BUF_SIZE (8) 15 | 16 | //#define SOFT_MODEM_BAUD_RATE (630) 17 | //#define SOFT_MODEM_LOW_FREQ (3150) 18 | //#define SOFT_MODEM_HIGH_FREQ (6300) 19 | //#define SOFT_MODEM_RX_BUF_SIZE (16) 20 | 21 | #define SOFT_MODEM_BAUD_RATE (1225) 22 | #define SOFT_MODEM_LOW_FREQ (4900) 23 | #define SOFT_MODEM_HIGH_FREQ (7350) 24 | #define SOFT_MODEM_RX_BUF_SIZE (32) 25 | 26 | //#define SOFT_MODEM_BAUD_RATE (2450) 27 | //#define SOFT_MODEM_LOW_FREQ (4900) 28 | //#define SOFT_MODEM_HIGH_FREQ (7350) 29 | //#define SOFT_MODEM_RX_BUF_SIZE (32) 30 | 31 | #define SOFT_MODEM_DEBUG_ENABLE (0) 32 | 33 | class SoftModem : public Stream 34 | { 35 | private: 36 | volatile uint8_t *_txPortReg; 37 | uint8_t _txPortMask; 38 | uint8_t _lastTCNT; 39 | uint8_t _lastDiff; 40 | uint8_t _recvStat; 41 | uint8_t _recvBits; 42 | uint8_t _recvBufferHead; 43 | uint8_t _recvBufferTail; 44 | uint8_t _recvBuffer[SOFT_MODEM_RX_BUF_SIZE]; 45 | uint8_t _lowCount; 46 | uint8_t _highCount; 47 | unsigned long _lastWriteTime; 48 | void modulate(uint8_t b); 49 | public: 50 | SoftModem(); 51 | ~SoftModem(); 52 | void begin(void); 53 | void end(void); 54 | virtual int available(); 55 | virtual int read(); 56 | virtual void flush(); 57 | virtual int peek(); 58 | virtual size_t write(const uint8_t *buffer, size_t size); 59 | virtual size_t write(uint8_t data); 60 | void demodulate(void); 61 | void recv(void); 62 | static SoftModem *activeObject; 63 | }; 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /Arduino-SoftModem/Transmitter.ino: -------------------------------------------------------------------------------- 1 | #include 2 | SoftModem modem; 3 | 4 | void setup() 5 | { 6 | modem.begin(); 7 | Serial.begin(115200); 8 | } 9 | void loop() 10 | { 11 | modem.write('C'); 12 | Serial.write('C'); 13 | delay(100); 14 | } -------------------------------------------------------------------------------- /Arduino-SoftModem/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For SoftModem 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | SoftModem KEYWORD1 9 | 10 | ####################################### 11 | # Methods and Functions (KEYWORD2) 12 | ####################################### 13 | 14 | begin KEYWORD2 15 | end KEYWORD2 16 | available KEYWORD2 17 | read KEYWORD2 18 | write KEYWORD2 19 | 20 | ####################################### 21 | # Instances (KEYWORD2) 22 | ####################################### 23 | 24 | ####################################### 25 | # Constants (LITERAL1) 26 | ####################################### 27 | -------------------------------------------------------------------------------- /FSK-Arduino-iOS.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "FSK-Arduino-iOS" 3 | s.version = "0.0.1" 4 | s.summary = "FSK Library for iOS interface with Arduino Development." 5 | s.homepage = "http://github.com/ezefranca/FSK-Arduino-iOS" 6 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 7 | s.license = { :type => "MIT"} 8 | s.author = { "ezefranca" => "ezequiel.ifsp@gmail.com" } 9 | s.social_media_url = "http://twitter.com/ezefranca" 10 | s.platform = :ios 11 | s.source = { :git => "https://github.com/ezefranca/FSK-Arduino-iOS.git", :tag => "0.0.1" } 12 | s.source_files = 'FSK/**/*.{h,m}' 13 | #s.source_files = "FK*, SoftModem*" 14 | s.exclude_files = "Arduino-SoftModem, LICENSE, README.md, FSK-Arduino-iOS.podspec, wercker.yml" 15 | s.requires_arc = false 16 | end 17 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | F7C3C39D1903952700B9FFA3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7C3C39C1903952700B9FFA3 /* Foundation.framework */; }; 11 | F7C3C39F1903952700B9FFA3 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7C3C39E1903952700B9FFA3 /* CoreGraphics.framework */; }; 12 | F7C3C3A11903952700B9FFA3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7C3C3A01903952700B9FFA3 /* UIKit.framework */; }; 13 | F7C3C3A71903952700B9FFA3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F7C3C3A51903952700B9FFA3 /* InfoPlist.strings */; }; 14 | F7C3C3A91903952700B9FFA3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C3C3A81903952700B9FFA3 /* main.m */; }; 15 | F7C3C3AD1903952700B9FFA3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C3C3AC1903952700B9FFA3 /* AppDelegate.m */; }; 16 | F7C3C3B01903952700B9FFA3 /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7C3C3AE1903952700B9FFA3 /* Main_iPhone.storyboard */; }; 17 | F7C3C3B31903952700B9FFA3 /* Main_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7C3C3B11903952700B9FFA3 /* Main_iPad.storyboard */; }; 18 | F7C3C3B61903952700B9FFA3 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C3C3B51903952700B9FFA3 /* ViewController.m */; }; 19 | F7C3C3B81903952700B9FFA3 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F7C3C3B71903952700B9FFA3 /* Images.xcassets */; }; 20 | F7C3C3BF1903952700B9FFA3 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7C3C3BE1903952700B9FFA3 /* XCTest.framework */; }; 21 | F7C3C3C01903952700B9FFA3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7C3C39C1903952700B9FFA3 /* Foundation.framework */; }; 22 | F7C3C3C11903952700B9FFA3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7C3C3A01903952700B9FFA3 /* UIKit.framework */; }; 23 | F7C3C3C91903952700B9FFA3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F7C3C3C71903952700B9FFA3 /* InfoPlist.strings */; }; 24 | F7C3C3CB1903952700B9FFA3 /* FSK_DemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C3C3CA1903952700B9FFA3 /* FSK_DemoTests.m */; }; 25 | F7C3C3EB1903956300B9FFA3 /* NSString+HexColor.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C3C3D71903956300B9FFA3 /* NSString+HexColor.m */; }; 26 | F7C3C3EC1903956300B9FFA3 /* AudioQueueObject.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C3C3DB1903956300B9FFA3 /* AudioQueueObject.m */; }; 27 | F7C3C3ED1903956300B9FFA3 /* AudioSignalAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C3C3DD1903956300B9FFA3 /* AudioSignalAnalyzer.m */; }; 28 | F7C3C3EE1903956300B9FFA3 /* AudioSignalGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C3C3DF1903956300B9FFA3 /* AudioSignalGenerator.m */; }; 29 | F7C3C3EF1903956300B9FFA3 /* FSKRecognizer.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7C3C3E41903956300B9FFA3 /* FSKRecognizer.mm */; }; 30 | F7C3C3F01903956300B9FFA3 /* FSKSerialGenerator.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7C3C3E61903956300B9FFA3 /* FSKSerialGenerator.mm */; }; 31 | F7C3C3F11903956300B9FFA3 /* MultiDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C3C3E91903956300B9FFA3 /* MultiDelegate.m */; }; 32 | F7C3C3F4190395C800B9FFA3 /* AudioDemo.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C3C3F3190395C800B9FFA3 /* AudioDemo.m */; }; 33 | F7C3C3F819039C6F00B9FFA3 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7C3C3F519039C6F00B9FFA3 /* AudioToolbox.framework */; }; 34 | F7C3C3FA19039C6F00B9FFA3 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7C3C3F719039C6F00B9FFA3 /* CoreAudio.framework */; }; 35 | F7C3C40D1904306300B9FFA3 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7C3C40C1904306300B9FFA3 /* AVFoundation.framework */; }; 36 | /* End PBXBuildFile section */ 37 | 38 | /* Begin PBXContainerItemProxy section */ 39 | F7C3C3C21903952700B9FFA3 /* PBXContainerItemProxy */ = { 40 | isa = PBXContainerItemProxy; 41 | containerPortal = F7C3C3911903952600B9FFA3 /* Project object */; 42 | proxyType = 1; 43 | remoteGlobalIDString = F7C3C3981903952700B9FFA3; 44 | remoteInfo = "FSK-Demo"; 45 | }; 46 | /* End PBXContainerItemProxy section */ 47 | 48 | /* Begin PBXFileReference section */ 49 | F7C3C3991903952700B9FFA3 /* FSK-Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "FSK-Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | F7C3C39C1903952700B9FFA3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 51 | F7C3C39E1903952700B9FFA3 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 52 | F7C3C3A01903952700B9FFA3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 53 | F7C3C3A41903952700B9FFA3 /* FSK-Demo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "FSK-Demo-Info.plist"; sourceTree = ""; }; 54 | F7C3C3A61903952700B9FFA3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 55 | F7C3C3A81903952700B9FFA3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 56 | F7C3C3AA1903952700B9FFA3 /* FSK-Demo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FSK-Demo-Prefix.pch"; sourceTree = ""; }; 57 | F7C3C3AB1903952700B9FFA3 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 58 | F7C3C3AC1903952700B9FFA3 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 59 | F7C3C3AF1903952700B9FFA3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPhone.storyboard; sourceTree = ""; }; 60 | F7C3C3B21903952700B9FFA3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPad.storyboard; sourceTree = ""; }; 61 | F7C3C3B41903952700B9FFA3 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 62 | F7C3C3B51903952700B9FFA3 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 63 | F7C3C3B71903952700B9FFA3 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 64 | F7C3C3BD1903952700B9FFA3 /* FSK-DemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "FSK-DemoTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | F7C3C3BE1903952700B9FFA3 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 66 | F7C3C3C61903952700B9FFA3 /* FSK-DemoTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "FSK-DemoTests-Info.plist"; sourceTree = ""; }; 67 | F7C3C3C81903952700B9FFA3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 68 | F7C3C3CA1903952700B9FFA3 /* FSK_DemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FSK_DemoTests.m; sourceTree = ""; }; 69 | F7C3C3D61903956300B9FFA3 /* NSString+HexColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+HexColor.h"; sourceTree = ""; }; 70 | F7C3C3D71903956300B9FFA3 /* NSString+HexColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+HexColor.m"; sourceTree = ""; }; 71 | F7C3C3D81903956300B9FFA3 /* UIView+Layout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Layout.h"; sourceTree = ""; }; 72 | F7C3C3DA1903956300B9FFA3 /* AudioQueueObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioQueueObject.h; sourceTree = ""; }; 73 | F7C3C3DB1903956300B9FFA3 /* AudioQueueObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioQueueObject.m; sourceTree = ""; }; 74 | F7C3C3DC1903956300B9FFA3 /* AudioSignalAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioSignalAnalyzer.h; sourceTree = ""; }; 75 | F7C3C3DD1903956300B9FFA3 /* AudioSignalAnalyzer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioSignalAnalyzer.m; sourceTree = ""; }; 76 | F7C3C3DE1903956300B9FFA3 /* AudioSignalGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioSignalGenerator.h; sourceTree = ""; }; 77 | F7C3C3DF1903956300B9FFA3 /* AudioSignalGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioSignalGenerator.m; sourceTree = ""; }; 78 | F7C3C3E01903956300B9FFA3 /* CharReceiver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CharReceiver.h; sourceTree = ""; }; 79 | F7C3C3E11903956300B9FFA3 /* FSKByteQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSKByteQueue.h; sourceTree = ""; }; 80 | F7C3C3E21903956300B9FFA3 /* FSKModemConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSKModemConfig.h; sourceTree = ""; }; 81 | F7C3C3E31903956300B9FFA3 /* FSKRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSKRecognizer.h; sourceTree = ""; }; 82 | F7C3C3E41903956300B9FFA3 /* FSKRecognizer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FSKRecognizer.mm; sourceTree = ""; }; 83 | F7C3C3E51903956300B9FFA3 /* FSKSerialGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSKSerialGenerator.h; sourceTree = ""; }; 84 | F7C3C3E61903956300B9FFA3 /* FSKSerialGenerator.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FSKSerialGenerator.mm; sourceTree = ""; }; 85 | F7C3C3E71903956300B9FFA3 /* lockfree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lockfree.h; sourceTree = ""; }; 86 | F7C3C3E81903956300B9FFA3 /* MultiDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MultiDelegate.h; sourceTree = ""; }; 87 | F7C3C3E91903956300B9FFA3 /* MultiDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MultiDelegate.m; sourceTree = ""; }; 88 | F7C3C3EA1903956300B9FFA3 /* PatternRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PatternRecognizer.h; sourceTree = ""; }; 89 | F7C3C3F2190395C800B9FFA3 /* AudioDemo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDemo.h; sourceTree = ""; }; 90 | F7C3C3F3190395C800B9FFA3 /* AudioDemo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioDemo.m; sourceTree = ""; }; 91 | F7C3C3F519039C6F00B9FFA3 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 92 | F7C3C3F619039C6F00B9FFA3 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; 93 | F7C3C3F719039C6F00B9FFA3 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; 94 | F7C3C40C1904306300B9FFA3 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; 95 | /* End PBXFileReference section */ 96 | 97 | /* Begin PBXFrameworksBuildPhase section */ 98 | F7C3C3961903952700B9FFA3 /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | F7C3C40D1904306300B9FFA3 /* AVFoundation.framework in Frameworks */, 103 | F7C3C3F819039C6F00B9FFA3 /* AudioToolbox.framework in Frameworks */, 104 | F7C3C3FA19039C6F00B9FFA3 /* CoreAudio.framework in Frameworks */, 105 | F7C3C39F1903952700B9FFA3 /* CoreGraphics.framework in Frameworks */, 106 | F7C3C3A11903952700B9FFA3 /* UIKit.framework in Frameworks */, 107 | F7C3C39D1903952700B9FFA3 /* Foundation.framework in Frameworks */, 108 | ); 109 | runOnlyForDeploymentPostprocessing = 0; 110 | }; 111 | F7C3C3BA1903952700B9FFA3 /* Frameworks */ = { 112 | isa = PBXFrameworksBuildPhase; 113 | buildActionMask = 2147483647; 114 | files = ( 115 | F7C3C3BF1903952700B9FFA3 /* XCTest.framework in Frameworks */, 116 | F7C3C3C11903952700B9FFA3 /* UIKit.framework in Frameworks */, 117 | F7C3C3C01903952700B9FFA3 /* Foundation.framework in Frameworks */, 118 | ); 119 | runOnlyForDeploymentPostprocessing = 0; 120 | }; 121 | /* End PBXFrameworksBuildPhase section */ 122 | 123 | /* Begin PBXGroup section */ 124 | F7C3C3901903952600B9FFA3 = { 125 | isa = PBXGroup; 126 | children = ( 127 | F7C3C3D41903956300B9FFA3 /* Class */, 128 | F7C3C3A21903952700B9FFA3 /* FSK-Demo */, 129 | F7C3C3C41903952700B9FFA3 /* FSK-DemoTests */, 130 | F7C3C39B1903952700B9FFA3 /* Frameworks */, 131 | F7C3C39A1903952700B9FFA3 /* Products */, 132 | ); 133 | sourceTree = ""; 134 | }; 135 | F7C3C39A1903952700B9FFA3 /* Products */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | F7C3C3991903952700B9FFA3 /* FSK-Demo.app */, 139 | F7C3C3BD1903952700B9FFA3 /* FSK-DemoTests.xctest */, 140 | ); 141 | name = Products; 142 | sourceTree = ""; 143 | }; 144 | F7C3C39B1903952700B9FFA3 /* Frameworks */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | F7C3C40C1904306300B9FFA3 /* AVFoundation.framework */, 148 | F7C3C3F519039C6F00B9FFA3 /* AudioToolbox.framework */, 149 | F7C3C3F619039C6F00B9FFA3 /* AudioUnit.framework */, 150 | F7C3C3F719039C6F00B9FFA3 /* CoreAudio.framework */, 151 | F7C3C39C1903952700B9FFA3 /* Foundation.framework */, 152 | F7C3C39E1903952700B9FFA3 /* CoreGraphics.framework */, 153 | F7C3C3A01903952700B9FFA3 /* UIKit.framework */, 154 | F7C3C3BE1903952700B9FFA3 /* XCTest.framework */, 155 | ); 156 | name = Frameworks; 157 | sourceTree = ""; 158 | }; 159 | F7C3C3A21903952700B9FFA3 /* FSK-Demo */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | F7C3C3AB1903952700B9FFA3 /* AppDelegate.h */, 163 | F7C3C3AC1903952700B9FFA3 /* AppDelegate.m */, 164 | F7C3C3AE1903952700B9FFA3 /* Main_iPhone.storyboard */, 165 | F7C3C3B11903952700B9FFA3 /* Main_iPad.storyboard */, 166 | F7C3C3B41903952700B9FFA3 /* ViewController.h */, 167 | F7C3C3B51903952700B9FFA3 /* ViewController.m */, 168 | F7C3C3F2190395C800B9FFA3 /* AudioDemo.h */, 169 | F7C3C3F3190395C800B9FFA3 /* AudioDemo.m */, 170 | F7C3C3B71903952700B9FFA3 /* Images.xcassets */, 171 | F7C3C3A31903952700B9FFA3 /* Supporting Files */, 172 | ); 173 | path = "FSK-Demo"; 174 | sourceTree = ""; 175 | }; 176 | F7C3C3A31903952700B9FFA3 /* Supporting Files */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | F7C3C3A41903952700B9FFA3 /* FSK-Demo-Info.plist */, 180 | F7C3C3A51903952700B9FFA3 /* InfoPlist.strings */, 181 | F7C3C3A81903952700B9FFA3 /* main.m */, 182 | F7C3C3AA1903952700B9FFA3 /* FSK-Demo-Prefix.pch */, 183 | ); 184 | name = "Supporting Files"; 185 | sourceTree = ""; 186 | }; 187 | F7C3C3C41903952700B9FFA3 /* FSK-DemoTests */ = { 188 | isa = PBXGroup; 189 | children = ( 190 | F7C3C3CA1903952700B9FFA3 /* FSK_DemoTests.m */, 191 | F7C3C3C51903952700B9FFA3 /* Supporting Files */, 192 | ); 193 | path = "FSK-DemoTests"; 194 | sourceTree = ""; 195 | }; 196 | F7C3C3C51903952700B9FFA3 /* Supporting Files */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | F7C3C3C61903952700B9FFA3 /* FSK-DemoTests-Info.plist */, 200 | F7C3C3C71903952700B9FFA3 /* InfoPlist.strings */, 201 | ); 202 | name = "Supporting Files"; 203 | sourceTree = ""; 204 | }; 205 | F7C3C3D41903956300B9FFA3 /* Class */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | F7C3C3D51903956300B9FFA3 /* FK */, 209 | F7C3C3D91903956300B9FFA3 /* SoftModem */, 210 | ); 211 | name = Class; 212 | path = "FSK-Demo/Class"; 213 | sourceTree = ""; 214 | }; 215 | F7C3C3D51903956300B9FFA3 /* FK */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | F7C3C3D61903956300B9FFA3 /* NSString+HexColor.h */, 219 | F7C3C3D71903956300B9FFA3 /* NSString+HexColor.m */, 220 | F7C3C3D81903956300B9FFA3 /* UIView+Layout.h */, 221 | ); 222 | path = FK; 223 | sourceTree = ""; 224 | }; 225 | F7C3C3D91903956300B9FFA3 /* SoftModem */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | F7C3C3DA1903956300B9FFA3 /* AudioQueueObject.h */, 229 | F7C3C3DB1903956300B9FFA3 /* AudioQueueObject.m */, 230 | F7C3C3DC1903956300B9FFA3 /* AudioSignalAnalyzer.h */, 231 | F7C3C3DD1903956300B9FFA3 /* AudioSignalAnalyzer.m */, 232 | F7C3C3DE1903956300B9FFA3 /* AudioSignalGenerator.h */, 233 | F7C3C3DF1903956300B9FFA3 /* AudioSignalGenerator.m */, 234 | F7C3C3E01903956300B9FFA3 /* CharReceiver.h */, 235 | F7C3C3E11903956300B9FFA3 /* FSKByteQueue.h */, 236 | F7C3C3E21903956300B9FFA3 /* FSKModemConfig.h */, 237 | F7C3C3E31903956300B9FFA3 /* FSKRecognizer.h */, 238 | F7C3C3E41903956300B9FFA3 /* FSKRecognizer.mm */, 239 | F7C3C3E51903956300B9FFA3 /* FSKSerialGenerator.h */, 240 | F7C3C3E61903956300B9FFA3 /* FSKSerialGenerator.mm */, 241 | F7C3C3E71903956300B9FFA3 /* lockfree.h */, 242 | F7C3C3E81903956300B9FFA3 /* MultiDelegate.h */, 243 | F7C3C3E91903956300B9FFA3 /* MultiDelegate.m */, 244 | F7C3C3EA1903956300B9FFA3 /* PatternRecognizer.h */, 245 | ); 246 | path = SoftModem; 247 | sourceTree = ""; 248 | }; 249 | /* End PBXGroup section */ 250 | 251 | /* Begin PBXNativeTarget section */ 252 | F7C3C3981903952700B9FFA3 /* FSK-Demo */ = { 253 | isa = PBXNativeTarget; 254 | buildConfigurationList = F7C3C3CE1903952700B9FFA3 /* Build configuration list for PBXNativeTarget "FSK-Demo" */; 255 | buildPhases = ( 256 | F7C3C3951903952700B9FFA3 /* Sources */, 257 | F7C3C3961903952700B9FFA3 /* Frameworks */, 258 | F7C3C3971903952700B9FFA3 /* Resources */, 259 | ); 260 | buildRules = ( 261 | ); 262 | dependencies = ( 263 | ); 264 | name = "FSK-Demo"; 265 | productName = "FSK-Demo"; 266 | productReference = F7C3C3991903952700B9FFA3 /* FSK-Demo.app */; 267 | productType = "com.apple.product-type.application"; 268 | }; 269 | F7C3C3BC1903952700B9FFA3 /* FSK-DemoTests */ = { 270 | isa = PBXNativeTarget; 271 | buildConfigurationList = F7C3C3D11903952700B9FFA3 /* Build configuration list for PBXNativeTarget "FSK-DemoTests" */; 272 | buildPhases = ( 273 | F7C3C3B91903952700B9FFA3 /* Sources */, 274 | F7C3C3BA1903952700B9FFA3 /* Frameworks */, 275 | F7C3C3BB1903952700B9FFA3 /* Resources */, 276 | ); 277 | buildRules = ( 278 | ); 279 | dependencies = ( 280 | F7C3C3C31903952700B9FFA3 /* PBXTargetDependency */, 281 | ); 282 | name = "FSK-DemoTests"; 283 | productName = "FSK-DemoTests"; 284 | productReference = F7C3C3BD1903952700B9FFA3 /* FSK-DemoTests.xctest */; 285 | productType = "com.apple.product-type.bundle.unit-test"; 286 | }; 287 | /* End PBXNativeTarget section */ 288 | 289 | /* Begin PBXProject section */ 290 | F7C3C3911903952600B9FFA3 /* Project object */ = { 291 | isa = PBXProject; 292 | attributes = { 293 | LastUpgradeCheck = 0510; 294 | ORGANIZATIONNAME = "Ezequiel Franca dos Santos"; 295 | TargetAttributes = { 296 | F7C3C3BC1903952700B9FFA3 = { 297 | TestTargetID = F7C3C3981903952700B9FFA3; 298 | }; 299 | }; 300 | }; 301 | buildConfigurationList = F7C3C3941903952600B9FFA3 /* Build configuration list for PBXProject "FSK-Demo" */; 302 | compatibilityVersion = "Xcode 3.2"; 303 | developmentRegion = English; 304 | hasScannedForEncodings = 0; 305 | knownRegions = ( 306 | en, 307 | Base, 308 | ); 309 | mainGroup = F7C3C3901903952600B9FFA3; 310 | productRefGroup = F7C3C39A1903952700B9FFA3 /* Products */; 311 | projectDirPath = ""; 312 | projectRoot = ""; 313 | targets = ( 314 | F7C3C3981903952700B9FFA3 /* FSK-Demo */, 315 | F7C3C3BC1903952700B9FFA3 /* FSK-DemoTests */, 316 | ); 317 | }; 318 | /* End PBXProject section */ 319 | 320 | /* Begin PBXResourcesBuildPhase section */ 321 | F7C3C3971903952700B9FFA3 /* Resources */ = { 322 | isa = PBXResourcesBuildPhase; 323 | buildActionMask = 2147483647; 324 | files = ( 325 | F7C3C3B31903952700B9FFA3 /* Main_iPad.storyboard in Resources */, 326 | F7C3C3B81903952700B9FFA3 /* Images.xcassets in Resources */, 327 | F7C3C3B01903952700B9FFA3 /* Main_iPhone.storyboard in Resources */, 328 | F7C3C3A71903952700B9FFA3 /* InfoPlist.strings in Resources */, 329 | ); 330 | runOnlyForDeploymentPostprocessing = 0; 331 | }; 332 | F7C3C3BB1903952700B9FFA3 /* Resources */ = { 333 | isa = PBXResourcesBuildPhase; 334 | buildActionMask = 2147483647; 335 | files = ( 336 | F7C3C3C91903952700B9FFA3 /* InfoPlist.strings in Resources */, 337 | ); 338 | runOnlyForDeploymentPostprocessing = 0; 339 | }; 340 | /* End PBXResourcesBuildPhase section */ 341 | 342 | /* Begin PBXSourcesBuildPhase section */ 343 | F7C3C3951903952700B9FFA3 /* Sources */ = { 344 | isa = PBXSourcesBuildPhase; 345 | buildActionMask = 2147483647; 346 | files = ( 347 | F7C3C3F01903956300B9FFA3 /* FSKSerialGenerator.mm in Sources */, 348 | F7C3C3B61903952700B9FFA3 /* ViewController.m in Sources */, 349 | F7C3C3F11903956300B9FFA3 /* MultiDelegate.m in Sources */, 350 | F7C3C3EB1903956300B9FFA3 /* NSString+HexColor.m in Sources */, 351 | F7C3C3F4190395C800B9FFA3 /* AudioDemo.m in Sources */, 352 | F7C3C3AD1903952700B9FFA3 /* AppDelegate.m in Sources */, 353 | F7C3C3A91903952700B9FFA3 /* main.m in Sources */, 354 | F7C3C3EF1903956300B9FFA3 /* FSKRecognizer.mm in Sources */, 355 | F7C3C3EE1903956300B9FFA3 /* AudioSignalGenerator.m in Sources */, 356 | F7C3C3ED1903956300B9FFA3 /* AudioSignalAnalyzer.m in Sources */, 357 | F7C3C3EC1903956300B9FFA3 /* AudioQueueObject.m in Sources */, 358 | ); 359 | runOnlyForDeploymentPostprocessing = 0; 360 | }; 361 | F7C3C3B91903952700B9FFA3 /* Sources */ = { 362 | isa = PBXSourcesBuildPhase; 363 | buildActionMask = 2147483647; 364 | files = ( 365 | F7C3C3CB1903952700B9FFA3 /* FSK_DemoTests.m in Sources */, 366 | ); 367 | runOnlyForDeploymentPostprocessing = 0; 368 | }; 369 | /* End PBXSourcesBuildPhase section */ 370 | 371 | /* Begin PBXTargetDependency section */ 372 | F7C3C3C31903952700B9FFA3 /* PBXTargetDependency */ = { 373 | isa = PBXTargetDependency; 374 | target = F7C3C3981903952700B9FFA3 /* FSK-Demo */; 375 | targetProxy = F7C3C3C21903952700B9FFA3 /* PBXContainerItemProxy */; 376 | }; 377 | /* End PBXTargetDependency section */ 378 | 379 | /* Begin PBXVariantGroup section */ 380 | F7C3C3A51903952700B9FFA3 /* InfoPlist.strings */ = { 381 | isa = PBXVariantGroup; 382 | children = ( 383 | F7C3C3A61903952700B9FFA3 /* en */, 384 | ); 385 | name = InfoPlist.strings; 386 | sourceTree = ""; 387 | }; 388 | F7C3C3AE1903952700B9FFA3 /* Main_iPhone.storyboard */ = { 389 | isa = PBXVariantGroup; 390 | children = ( 391 | F7C3C3AF1903952700B9FFA3 /* Base */, 392 | ); 393 | name = Main_iPhone.storyboard; 394 | sourceTree = ""; 395 | }; 396 | F7C3C3B11903952700B9FFA3 /* Main_iPad.storyboard */ = { 397 | isa = PBXVariantGroup; 398 | children = ( 399 | F7C3C3B21903952700B9FFA3 /* Base */, 400 | ); 401 | name = Main_iPad.storyboard; 402 | sourceTree = ""; 403 | }; 404 | F7C3C3C71903952700B9FFA3 /* InfoPlist.strings */ = { 405 | isa = PBXVariantGroup; 406 | children = ( 407 | F7C3C3C81903952700B9FFA3 /* en */, 408 | ); 409 | name = InfoPlist.strings; 410 | sourceTree = ""; 411 | }; 412 | /* End PBXVariantGroup section */ 413 | 414 | /* Begin XCBuildConfiguration section */ 415 | F7C3C3CC1903952700B9FFA3 /* Debug */ = { 416 | isa = XCBuildConfiguration; 417 | buildSettings = { 418 | ALWAYS_SEARCH_USER_PATHS = NO; 419 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 420 | CLANG_CXX_LIBRARY = "libc++"; 421 | CLANG_ENABLE_MODULES = YES; 422 | CLANG_ENABLE_OBJC_ARC = YES; 423 | CLANG_WARN_BOOL_CONVERSION = YES; 424 | CLANG_WARN_CONSTANT_CONVERSION = YES; 425 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 426 | CLANG_WARN_EMPTY_BODY = YES; 427 | CLANG_WARN_ENUM_CONVERSION = YES; 428 | CLANG_WARN_INT_CONVERSION = YES; 429 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 430 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 431 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 432 | COPY_PHASE_STRIP = NO; 433 | GCC_C_LANGUAGE_STANDARD = gnu99; 434 | GCC_DYNAMIC_NO_PIC = NO; 435 | GCC_OPTIMIZATION_LEVEL = 0; 436 | GCC_PREPROCESSOR_DEFINITIONS = ( 437 | "DEBUG=1", 438 | "$(inherited)", 439 | ); 440 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 441 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 442 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 443 | GCC_WARN_UNDECLARED_SELECTOR = YES; 444 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 445 | GCC_WARN_UNUSED_FUNCTION = YES; 446 | GCC_WARN_UNUSED_VARIABLE = YES; 447 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 448 | ONLY_ACTIVE_ARCH = YES; 449 | SDKROOT = iphoneos; 450 | TARGETED_DEVICE_FAMILY = "1,2"; 451 | }; 452 | name = Debug; 453 | }; 454 | F7C3C3CD1903952700B9FFA3 /* Release */ = { 455 | isa = XCBuildConfiguration; 456 | buildSettings = { 457 | ALWAYS_SEARCH_USER_PATHS = NO; 458 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 459 | CLANG_CXX_LIBRARY = "libc++"; 460 | CLANG_ENABLE_MODULES = YES; 461 | CLANG_ENABLE_OBJC_ARC = YES; 462 | CLANG_WARN_BOOL_CONVERSION = YES; 463 | CLANG_WARN_CONSTANT_CONVERSION = YES; 464 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 465 | CLANG_WARN_EMPTY_BODY = YES; 466 | CLANG_WARN_ENUM_CONVERSION = YES; 467 | CLANG_WARN_INT_CONVERSION = YES; 468 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 469 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 470 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 471 | COPY_PHASE_STRIP = YES; 472 | ENABLE_NS_ASSERTIONS = NO; 473 | GCC_C_LANGUAGE_STANDARD = gnu99; 474 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 475 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 476 | GCC_WARN_UNDECLARED_SELECTOR = YES; 477 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 478 | GCC_WARN_UNUSED_FUNCTION = YES; 479 | GCC_WARN_UNUSED_VARIABLE = YES; 480 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 481 | SDKROOT = iphoneos; 482 | TARGETED_DEVICE_FAMILY = "1,2"; 483 | VALIDATE_PRODUCT = YES; 484 | }; 485 | name = Release; 486 | }; 487 | F7C3C3CF1903952700B9FFA3 /* Debug */ = { 488 | isa = XCBuildConfiguration; 489 | buildSettings = { 490 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 491 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 492 | CODE_SIGN_IDENTITY = ""; 493 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 494 | GCC_PREFIX_HEADER = "FSK-Demo/FSK-Demo-Prefix.pch"; 495 | INFOPLIST_FILE = "FSK-Demo/FSK-Demo-Info.plist"; 496 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 497 | PRODUCT_NAME = "$(TARGET_NAME)"; 498 | PROVISIONING_PROFILE = "0587D4CF-008A-47FB-96DA-2C41ECDD923C"; 499 | WRAPPER_EXTENSION = app; 500 | }; 501 | name = Debug; 502 | }; 503 | F7C3C3D01903952700B9FFA3 /* Release */ = { 504 | isa = XCBuildConfiguration; 505 | buildSettings = { 506 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 507 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 508 | CODE_SIGN_IDENTITY = ""; 509 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 510 | GCC_PREFIX_HEADER = "FSK-Demo/FSK-Demo-Prefix.pch"; 511 | INFOPLIST_FILE = "FSK-Demo/FSK-Demo-Info.plist"; 512 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 513 | PRODUCT_NAME = "$(TARGET_NAME)"; 514 | PROVISIONING_PROFILE = "0587D4CF-008A-47FB-96DA-2C41ECDD923C"; 515 | WRAPPER_EXTENSION = app; 516 | }; 517 | name = Release; 518 | }; 519 | F7C3C3D21903952700B9FFA3 /* Debug */ = { 520 | isa = XCBuildConfiguration; 521 | buildSettings = { 522 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/FSK-Demo.app/FSK-Demo"; 523 | FRAMEWORK_SEARCH_PATHS = ( 524 | "$(SDKROOT)/Developer/Library/Frameworks", 525 | "$(inherited)", 526 | "$(DEVELOPER_FRAMEWORKS_DIR)", 527 | ); 528 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 529 | GCC_PREFIX_HEADER = "FSK-Demo/FSK-Demo-Prefix.pch"; 530 | GCC_PREPROCESSOR_DEFINITIONS = ( 531 | "DEBUG=1", 532 | "$(inherited)", 533 | ); 534 | INFOPLIST_FILE = "FSK-DemoTests/FSK-DemoTests-Info.plist"; 535 | PRODUCT_NAME = "$(TARGET_NAME)"; 536 | TEST_HOST = "$(BUNDLE_LOADER)"; 537 | WRAPPER_EXTENSION = xctest; 538 | }; 539 | name = Debug; 540 | }; 541 | F7C3C3D31903952700B9FFA3 /* Release */ = { 542 | isa = XCBuildConfiguration; 543 | buildSettings = { 544 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/FSK-Demo.app/FSK-Demo"; 545 | FRAMEWORK_SEARCH_PATHS = ( 546 | "$(SDKROOT)/Developer/Library/Frameworks", 547 | "$(inherited)", 548 | "$(DEVELOPER_FRAMEWORKS_DIR)", 549 | ); 550 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 551 | GCC_PREFIX_HEADER = "FSK-Demo/FSK-Demo-Prefix.pch"; 552 | INFOPLIST_FILE = "FSK-DemoTests/FSK-DemoTests-Info.plist"; 553 | PRODUCT_NAME = "$(TARGET_NAME)"; 554 | TEST_HOST = "$(BUNDLE_LOADER)"; 555 | WRAPPER_EXTENSION = xctest; 556 | }; 557 | name = Release; 558 | }; 559 | /* End XCBuildConfiguration section */ 560 | 561 | /* Begin XCConfigurationList section */ 562 | F7C3C3941903952600B9FFA3 /* Build configuration list for PBXProject "FSK-Demo" */ = { 563 | isa = XCConfigurationList; 564 | buildConfigurations = ( 565 | F7C3C3CC1903952700B9FFA3 /* Debug */, 566 | F7C3C3CD1903952700B9FFA3 /* Release */, 567 | ); 568 | defaultConfigurationIsVisible = 0; 569 | defaultConfigurationName = Release; 570 | }; 571 | F7C3C3CE1903952700B9FFA3 /* Build configuration list for PBXNativeTarget "FSK-Demo" */ = { 572 | isa = XCConfigurationList; 573 | buildConfigurations = ( 574 | F7C3C3CF1903952700B9FFA3 /* Debug */, 575 | F7C3C3D01903952700B9FFA3 /* Release */, 576 | ); 577 | defaultConfigurationIsVisible = 0; 578 | defaultConfigurationName = Release; 579 | }; 580 | F7C3C3D11903952700B9FFA3 /* Build configuration list for PBXNativeTarget "FSK-DemoTests" */ = { 581 | isa = XCConfigurationList; 582 | buildConfigurations = ( 583 | F7C3C3D21903952700B9FFA3 /* Debug */, 584 | F7C3C3D31903952700B9FFA3 /* Release */, 585 | ); 586 | defaultConfigurationIsVisible = 0; 587 | defaultConfigurationName = Release; 588 | }; 589 | /* End XCConfigurationList section */ 590 | }; 591 | rootObject = F7C3C3911903952600B9FFA3 /* Project object */; 592 | } 593 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo.xcodeproj/project.xcworkspace/xcshareddata/FSK-Demo.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 4BCE0416-B888-494F-B233-A3E50F76A13F 9 | IDESourceControlProjectName 10 | FSK-Demo 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | FC0F5123-0A0E-408C-891B-4BE1E28D008C 14 | https://github.com/IoT-Repositories/FSK-Arduino-iOS7.git 15 | 16 | IDESourceControlProjectPath 17 | FSK-Demo/FSK-Demo.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | FC0F5123-0A0E-408C-891B-4BE1E28D008C 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/IoT-Repositories/FSK-Arduino-iOS7.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | FC0F5123-0A0E-408C-891B-4BE1E28D008C 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | FC0F5123-0A0E-408C-891B-4BE1E28D008C 36 | IDESourceControlWCCName 37 | FSK-Arduino-iOS7 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo.xcodeproj/project.xcworkspace/xcuserdata/ezefranca.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ezefranca/FSK-Arduino-iOS/0b1b8040853c1c751aee94442f82e453f489b6b7/FSK-Demo/FSK-Demo.xcodeproj/project.xcworkspace/xcuserdata/ezefranca.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo.xcodeproj/xcshareddata/xcschemes/FSK-Demo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo.xcodeproj/xcuserdata/ezefranca.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | FSK-Demo.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | F7C3C3981903952700B9FFA3 16 | 17 | primary 18 | 19 | 20 | F7C3C3BC1903952700B9FFA3 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo.xcworkspace/xcshareddata/FSK-Demo.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 4BCE0416-B888-494F-B233-A3E50F76A13F 9 | IDESourceControlProjectName 10 | FSK-Demo 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | FC0F5123-0A0E-408C-891B-4BE1E28D008C 14 | https://github.com/IoT-Repositories/FSK-Arduino-iOS7.git 15 | 16 | IDESourceControlProjectPath 17 | FSK-Demo/FSK-Demo.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | FC0F5123-0A0E-408C-891B-4BE1E28D008C 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/IoT-Repositories/FSK-Arduino-iOS7.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | FC0F5123-0A0E-408C-891B-4BE1E28D008C 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | FC0F5123-0A0E-408C-891B-4BE1E28D008C 36 | IDESourceControlWCCName 37 | FSK-Arduino-iOS7 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo.xcworkspace/xcuserdata/ezefranca.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ezefranca/FSK-Arduino-iOS/0b1b8040853c1c751aee94442f82e453f489b6b7/FSK-Demo/FSK-Demo.xcworkspace/xcuserdata/ezefranca.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // FSK-Demo 4 | // 5 | // Created by Ezequiel Franca dos Santos on 20/04/14. 6 | // Copyright (c) 2014 Ezequiel Franca dos Santos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // FSK-Demo 4 | // 5 | // Created by Ezequiel Franca dos Santos on 20/04/14. 6 | // Copyright (c) 2014 Ezequiel Franca dos Santos. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/AudioDemo.h: -------------------------------------------------------------------------------- 1 | // 2 | // AudioDemo.h 3 | // FSK-Demo 4 | // 5 | // Created by Ezequiel Franca dos Santos on 20/04/14. 6 | // Copyright (c) 2014 Ezequiel Franca dos Santos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | #import "CharReceiver.h" 14 | 15 | @class AudioSignalAnalyzer, FSKSerialGenerator; 16 | 17 | @interface AudioDemo : NSObject { 18 | char local_input; 19 | } 20 | @property (strong, nonatomic) AudioSignalAnalyzer* analyzer; 21 | @property (strong, nonatomic) FSKSerialGenerator* generator; 22 | 23 | + (id)shared; 24 | 25 | - (void)signalArduino:(BOOL)on; 26 | - (char)returnChar; 27 | @end -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/AudioDemo.m: -------------------------------------------------------------------------------- 1 | // 2 | // AudioDemo.m 3 | // FSK-Demo 4 | // 5 | // Created by Ezequiel Franca dos Santos on 20/04/14. 6 | // Copyright (c) 2014 Ezequiel Franca dos Santos. All rights reserved. 7 | // 8 | 9 | #import "AudioDemo.h" 10 | #import "CharReceiver.h" 11 | #import "AudioSignalAnalyzer.h" 12 | #import "FSKRecognizer.h" 13 | #import "FSKSerialGenerator.h" 14 | 15 | @implementation AudioDemo{ 16 | FSKRecognizer *_recognizer; 17 | } 18 | 19 | + (id)shared { 20 | static id shared; 21 | static dispatch_once_t once; 22 | dispatch_once(&once, ^{ 23 | shared = [[self alloc] init]; 24 | }); 25 | return shared; 26 | } 27 | 28 | - (id)init { 29 | if (self = [super init]) { 30 | AVAudioSession *session = [AVAudioSession sharedInstance]; 31 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interruption:) name:AVAudioSessionInterruptionNotification object:nil]; 32 | if(session.inputAvailable) { 33 | NSLog(@"Input is available, playandrecord\n"); 34 | [session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 35 | } else { 36 | NSLog(@"Input is available, playback\n"); 37 | [session setCategory:AVAudioSessionCategoryPlayback error:nil]; 38 | } 39 | [session setActive:YES error:nil]; 40 | [session setPreferredIOBufferDuration:0.023220 error:nil]; 41 | 42 | _generator = [[FSKSerialGenerator alloc] init]; [_generator play]; 43 | _recognizer = [[FSKRecognizer alloc] init]; [_recognizer addReceiver:self]; 44 | _analyzer = [[AudioSignalAnalyzer alloc] init]; [_analyzer addRecognizer:_recognizer]; 45 | 46 | if(session.inputAvailable){ 47 | NSLog(@"Input is available, analyzer record\n"); 48 | [self.analyzer record]; 49 | } 50 | 51 | } 52 | return self; 53 | } 54 | 55 | - (void)inputIsAvailableChanged:(BOOL)isInputAvailable 56 | { 57 | NSLog(@"inputIsAvailableChanged %d",isInputAvailable); 58 | 59 | AVAudioSession *session = [AVAudioSession sharedInstance]; 60 | 61 | [self.analyzer stop]; 62 | [self.generator stop]; 63 | 64 | if(isInputAvailable){ 65 | [session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 66 | [self.analyzer record]; 67 | }else{ 68 | [session setCategory:AVAudioSessionCategoryPlayback error:nil]; 69 | } 70 | [self.generator play]; 71 | } 72 | 73 | - (void)beginInterruption 74 | { 75 | NSLog(@"beginInterruption"); 76 | [self.analyzer stop]; 77 | [self.generator pause]; 78 | } 79 | 80 | - (void)endInterruption 81 | { 82 | NSLog(@"endInterruption"); 83 | [self.analyzer record]; 84 | [self.generator resume]; 85 | } 86 | 87 | - (void)endInterruptionWithFlags:(NSUInteger)flags 88 | { 89 | NSLog(@"endInterruptionWithFlags: %x",flags); 90 | } 91 | 92 | - (void)signalArduino:(BOOL)on { 93 | [self.generator writeByte:0xFF]; 94 | } 95 | 96 | - (void)receivedChar:(char)input { 97 | self->local_input = input; 98 | [self returnChar]; 99 | NSLog(@"Received: %d", input); 100 | } 101 | 102 | #pragma mark return received char 103 | 104 | - (char)returnChar{ 105 | return local_input; 106 | } 107 | 108 | #pragma mark New way in iOS 7 109 | 110 | - (void) interruption:(NSNotification*)notification 111 | { 112 | NSDictionary *interuptionDict = notification.userInfo; 113 | NSUInteger interuptionType = (NSUInteger)[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey]; 114 | 115 | if (interuptionType == AVAudioSessionInterruptionTypeBegan) 116 | [self beginInterruption]; 117 | #if __CC_PLATFORM_IOS >= 40000 118 | else if (interuptionType == AVAudioSessionInterruptionTypeEnded) 119 | [self endInterruptionWithFlags:(NSUInteger)[interuptionDict valueForKey:AVAudioSessionInterruptionOptionKey]]; 120 | #else 121 | else if (interuptionType == AVAudioSessionInterruptionTypeEnded) 122 | [self endInterruption]; 123 | #endif 124 | } 125 | 126 | @end 127 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Base.lproj/Main_iPad.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 26 | 33 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Base.lproj/Main_iPhone.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 29 | 36 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/FK/NSString+HexColor.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSStringColor.h 3 | // PhoneGap 4 | // 5 | // Created by Michael Nachbaur on 08/05/09. 6 | // Copyright 2009 Decaf Ninja Software. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (HexColor) 12 | 13 | - (UIColor*)colorFromHex; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/FK/NSString+HexColor.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+HexColor.m 3 | // PhoneGap 4 | // 5 | // Created by Michael Nachbaur on 08/05/09. 6 | // Copyright 2009 Decaf Ninja Software. All rights reserved. 7 | // 8 | 9 | #import "NSString+HexColor.h" 10 | 11 | @implementation NSString (HexColor) 12 | 13 | - (UIColor*)colorFromHex 14 | { 15 | NSString *hexColor = [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; 16 | 17 | if ([hexColor length] < 6) 18 | return [UIColor blackColor]; 19 | if ([hexColor hasPrefix:@"#"]) 20 | hexColor = [hexColor substringFromIndex:1]; 21 | if ([hexColor length] != 6 && [hexColor length] != 8) 22 | return [UIColor blackColor]; 23 | 24 | NSRange range; 25 | range.location = 0; 26 | range.length = 2; 27 | 28 | NSString *rString = [hexColor substringWithRange:range]; 29 | 30 | range.location = 2; 31 | NSString *gString = [hexColor substringWithRange:range]; 32 | 33 | range.location = 4; 34 | NSString *bString = [hexColor substringWithRange:range]; 35 | 36 | range.location = 6; 37 | NSString *aString = @"FF"; 38 | if ([hexColor length] == 8) 39 | aString = [hexColor substringWithRange:range]; 40 | 41 | // Scan values 42 | unsigned int r, g, b, a; 43 | [[NSScanner scannerWithString:rString] scanHexInt:&r]; 44 | [[NSScanner scannerWithString:gString] scanHexInt:&g]; 45 | [[NSScanner scannerWithString:bString] scanHexInt:&b]; 46 | [[NSScanner scannerWithString:aString] scanHexInt:&a]; 47 | 48 | return [UIColor colorWithRed:((float) r / 255.0f) 49 | green:((float) g / 255.0f) 50 | blue:((float) b / 255.0f) 51 | alpha:((float) a / 255.0f)]; 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/FK/UIView+Layout.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+UIFont+Layout.h 3 | // Labour 4 | // 5 | // Created by Bret Cheng on 29/12/2010. 6 | // Copyright 2010 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (Layout) 12 | 13 | @property(nonatomic, readonly)CGFloat width; 14 | @property(nonatomic, readonly)CGFloat height; 15 | @property(nonatomic, readonly)CGFloat top; 16 | @property(nonatomic, readonly)CGFloat bottom; 17 | @property(nonatomic, readonly)CGFloat left; 18 | @property(nonatomic, readonly)CGFloat right; 19 | 20 | @end 21 | 22 | @implementation UIView (Layout) 23 | 24 | - (CGFloat)width { 25 | return self.frame.size.width; 26 | } 27 | 28 | - (CGFloat)height { 29 | return self.frame.size.height; 30 | } 31 | 32 | - (CGFloat)top { 33 | return self.frame.origin.y; 34 | } 35 | 36 | - (CGFloat)bottom { 37 | return self.frame.origin.y + self.frame.size.height; 38 | } 39 | 40 | - (CGFloat)left { 41 | return self.frame.origin.x; 42 | } 43 | 44 | - (CGFloat)right { 45 | return self.frame.origin.x + self.frame.size.width; 46 | } 47 | @end 48 | 49 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/AudioQueueObject.h: -------------------------------------------------------------------------------- 1 | // 2 | // AudioQueueObject.h 3 | // iNfrared 4 | // 5 | // Created by George Dean on 11/28/08. 6 | // Culled from SpeakHere sample code. 7 | // Copyright 2008 Perceptive Development. All rights reserved. 8 | // 9 | // Edited by Ezequiel Franca on 20/04/14 10 | 11 | #import 12 | #include 13 | 14 | #define kNumberAudioDataBuffers 3 15 | 16 | @interface AudioQueueObject : NSObject { 17 | AudioQueueRef queueObject; // the audio queue object being used for playback 18 | AudioStreamBasicDescription audioFormat; 19 | } 20 | 21 | @property (readwrite) AudioQueueRef queueObject; 22 | @property (readwrite) AudioStreamBasicDescription audioFormat; 23 | 24 | - (BOOL) isRunning; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/AudioQueueObject.m: -------------------------------------------------------------------------------- 1 | // 2 | // AudioQueueObject.m 3 | // iNfrared 4 | // 5 | // Created by George Dean on 11/28/08. 6 | // Culled from SpeakHere sample code. 7 | // Copyright 2008 Perceptive Development. All rights reserved. 8 | // 9 | // Edited by Ezequiel Franca on 20/04/14 10 | 11 | #import "AudioQueueObject.h" 12 | 13 | 14 | @implementation AudioQueueObject 15 | 16 | @synthesize queueObject; 17 | @synthesize audioFormat; 18 | 19 | - (BOOL) isRunning { 20 | 21 | UInt32 isRunning; 22 | UInt32 propertySize = sizeof (UInt32); 23 | OSStatus result; 24 | 25 | result = AudioQueueGetProperty ( 26 | queueObject, 27 | kAudioQueueProperty_IsRunning, 28 | &isRunning, 29 | &propertySize 30 | ); 31 | 32 | if (result != noErr) { 33 | return false; 34 | } else { 35 | return isRunning; 36 | } 37 | } 38 | 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/AudioSignalAnalyzer.h: -------------------------------------------------------------------------------- 1 | // 2 | // AudioSignalAnalyzer.h 3 | // iNfrared 4 | // 5 | // Created by George Dean on 11/28/08. 6 | // Copyright 2008 Perceptive Development. All rights reserved. 7 | // 8 | // Edited by Ezequiel Franca on 20/04/14 9 | 10 | #import "AudioQueueObject.h" 11 | #import "PatternRecognizer.h" 12 | 13 | //#define DETAILED_ANALYSIS 14 | 15 | typedef struct 16 | { 17 | int lastFrame; 18 | int lastEdgeSign; 19 | unsigned lastEdgeWidth; 20 | int edgeSign; 21 | int edgeDiff; 22 | unsigned edgeWidth; 23 | unsigned plateauWidth; 24 | #ifdef DETAILED_ANALYSIS 25 | SInt64 edgeSum; 26 | int edgeMin; 27 | int edgeMax; 28 | SInt64 plateauSum; 29 | int plateauMin; 30 | int plateauMax; 31 | #endif 32 | } 33 | analyzerData; 34 | 35 | @interface AudioSignalAnalyzer : AudioQueueObject { 36 | BOOL stopping; 37 | analyzerData pulseData; 38 | NSMutableArray* recognizers; 39 | } 40 | 41 | @property (readwrite) BOOL stopping; 42 | @property (readonly) analyzerData* pulseData; 43 | 44 | - (void) addRecognizer: (id)recognizer; 45 | 46 | - (void) setupRecording; 47 | 48 | - (void) record; 49 | - (void) stop; 50 | 51 | - (void) edge: (int)height width:(unsigned)width interval:(unsigned)interval; 52 | - (void) idle: (unsigned)samples; 53 | - (void) reset; 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/AudioSignalAnalyzer.m: -------------------------------------------------------------------------------- 1 | // 2 | // AudioSignalAnalyzer.m 3 | // iNfrared 4 | // 5 | // Created by George Dean on 11/28/08. 6 | // Copyright 2008 Perceptive Development. All rights reserved. 7 | // 8 | // Edited by Ezequiel Franca on 20/04/14 9 | 10 | #import "AudioSignalAnalyzer.h" 11 | 12 | #define SAMPLE_RATE 44100 13 | #define SAMPLE SInt16 14 | #define NUM_CHANNELS 1 15 | #define BYTES_PER_FRAME (NUM_CHANNELS * sizeof(SAMPLE)) 16 | 17 | #define SAMPLES_TO_NS(__samples__) (((UInt64)(__samples__) * 1000000000) / SAMPLE_RATE) 18 | #define NS_TO_SAMPLES(__nanosec__) (unsigned)(((UInt64)(__nanosec__) * SAMPLE_RATE) / 1000000000) 19 | #define US_TO_SAMPLES(__microsec__) (unsigned)(((UInt64)(__microsec__) * SAMPLE_RATE) / 1000000) 20 | #define MS_TO_SAMPLES(__millisec__) (unsigned)(((UInt64)(__millisec__) * SAMPLE_RATE) / 1000) 21 | 22 | #define EDGE_DIFF_THRESHOLD 16384 23 | #define EDGE_SLOPE_THRESHOLD 256 24 | #define EDGE_MAX_WIDTH 8 25 | #define IDLE_CHECK_PERIOD MS_TO_SAMPLES(10) 26 | 27 | static int analyze( SAMPLE *inputBuffer, 28 | unsigned long framesPerBuffer, 29 | AudioSignalAnalyzer* analyzer) 30 | { 31 | analyzerData *data = analyzer.pulseData; 32 | SAMPLE *pSample = inputBuffer; 33 | int lastFrame = data->lastFrame; 34 | 35 | unsigned idleInterval = data->plateauWidth + data->lastEdgeWidth + data->edgeWidth; 36 | 37 | for (long i=0; i < framesPerBuffer; i++, pSample++) 38 | { 39 | int thisFrame = *pSample; 40 | int diff = thisFrame - lastFrame; 41 | 42 | int sign = 0; 43 | if (diff > EDGE_SLOPE_THRESHOLD) 44 | { 45 | // Signal is rising 46 | sign = 1; 47 | } 48 | else if(-diff > EDGE_SLOPE_THRESHOLD) 49 | { 50 | // Signal is falling 51 | sign = -1; 52 | } 53 | 54 | // If the signal has changed direction or the edge detector has gone on for too long, 55 | // then close out the current edge detection phase 56 | if(data->edgeSign != sign || (data->edgeSign && data->edgeWidth + 1 > EDGE_MAX_WIDTH)) 57 | { 58 | if(abs(data->edgeDiff) > EDGE_DIFF_THRESHOLD && data->lastEdgeSign != data->edgeSign) 59 | { 60 | // The edge is significant 61 | [analyzer edge:data->edgeDiff 62 | width:data->edgeWidth 63 | interval:data->plateauWidth + data->edgeWidth]; 64 | 65 | // Save the edge 66 | data->lastEdgeSign = data->edgeSign; 67 | data->lastEdgeWidth = data->edgeWidth; 68 | 69 | // Reset the plateau 70 | data->plateauWidth = 0; 71 | idleInterval = data->edgeWidth; 72 | #ifdef DETAILED_ANALYSIS 73 | data->plateauSum = 0; 74 | data->plateauMin = data->plateauMax = thisFrame; 75 | #endif 76 | } 77 | else 78 | { 79 | // The edge is rejected; add the edge data to the plateau 80 | data->plateauWidth += data->edgeWidth; 81 | #ifdef DETAILED_ANALYSIS 82 | data->plateauSum += data->edgeSum; 83 | if(data->plateauMax < data->edgeMax) 84 | data->plateauMax = data->edgeMax; 85 | if(data->plateauMin > data->edgeMin) 86 | data->plateauMin = data->edgeMin; 87 | #endif 88 | } 89 | 90 | data->edgeSign = sign; 91 | data->edgeWidth = 0; 92 | data->edgeDiff = 0; 93 | #ifdef DETAILED_ANALYSIS 94 | data->edgeSum = 0; 95 | data->edgeMin = data->edgeMax = lastFrame; 96 | #endif 97 | } 98 | 99 | if(data->edgeSign) 100 | { 101 | // Sample may be part of an edge 102 | data->edgeWidth++; 103 | data->edgeDiff += diff; 104 | #ifdef DETAILED_ANALYSIS 105 | data->edgeSum += thisFrame; 106 | if(data->edgeMax < thisFrame) 107 | data->edgeMax = thisFrame; 108 | if(data->edgeMin > thisFrame) 109 | data->edgeMin = thisFrame; 110 | #endif 111 | } 112 | else 113 | { 114 | // Sample is part of a plateau 115 | data->plateauWidth++; 116 | #ifdef DETAILED_ANALYSIS 117 | data->plateauSum += thisFrame; 118 | if(data->plateauMax < thisFrame) 119 | data->plateauMax = thisFrame; 120 | if(data->plateauMin > thisFrame) 121 | data->plateauMin = thisFrame; 122 | #endif 123 | } 124 | idleInterval++; 125 | 126 | data->lastFrame = lastFrame = thisFrame; 127 | 128 | if ( (idleInterval % IDLE_CHECK_PERIOD) == 0 ) 129 | [analyzer idle:idleInterval]; 130 | 131 | } 132 | 133 | return 0; 134 | } 135 | 136 | 137 | static void recordingCallback ( 138 | void *inUserData, 139 | AudioQueueRef inAudioQueue, 140 | AudioQueueBufferRef inBuffer, 141 | const AudioTimeStamp *inStartTime, 142 | UInt32 inNumPackets, 143 | const AudioStreamPacketDescription *inPacketDesc 144 | ) { 145 | // This is not a Cocoa thread, it needs a manually allocated pool 146 | // NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 147 | 148 | // This callback, being outside the implementation block, needs a reference to the AudioRecorder object 149 | AudioSignalAnalyzer *analyzer = (__bridge AudioSignalAnalyzer *) inUserData; 150 | 151 | // if there is audio data, analyze it 152 | if (inNumPackets > 0) { 153 | analyze((SAMPLE*)inBuffer->mAudioData, inBuffer->mAudioDataByteSize / BYTES_PER_FRAME, analyzer); 154 | } 155 | 156 | // if not stopping, re-enqueue the buffer so that it can be filled again 157 | if ([analyzer isRunning]) { 158 | AudioQueueEnqueueBuffer ( 159 | inAudioQueue, 160 | inBuffer, 161 | 0, 162 | NULL 163 | ); 164 | } 165 | 166 | } 167 | 168 | 169 | 170 | @implementation AudioSignalAnalyzer 171 | 172 | @synthesize stopping; 173 | 174 | - (analyzerData*) pulseData 175 | { 176 | return &pulseData; 177 | } 178 | 179 | - (id) init 180 | { 181 | self = [super init]; 182 | 183 | if (self != nil) 184 | { 185 | recognizers = [[NSMutableArray alloc] init]; 186 | // these statements define the audio stream basic description 187 | // for the file to record into. 188 | audioFormat.mSampleRate = SAMPLE_RATE; 189 | audioFormat.mFormatID = kAudioFormatLinearPCM; 190 | audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 191 | audioFormat.mFramesPerPacket = 1; 192 | audioFormat.mChannelsPerFrame = 1; 193 | audioFormat.mBitsPerChannel = 16; 194 | audioFormat.mBytesPerPacket = 2; 195 | audioFormat.mBytesPerFrame = 2; 196 | 197 | 198 | AudioQueueNewInput ( 199 | &audioFormat, 200 | recordingCallback, 201 | (__bridge void *)(self), // userData 202 | NULL, // run loop 203 | NULL, // run loop mode 204 | 0, // flags 205 | &queueObject 206 | ); 207 | 208 | } 209 | return self; 210 | } 211 | 212 | - (void) addRecognizer: (id)recognizer 213 | { 214 | [recognizers addObject:recognizer]; 215 | } 216 | 217 | - (void) record 218 | { 219 | [self setupRecording]; 220 | 221 | [self reset]; 222 | 223 | AudioQueueStart ( 224 | queueObject, 225 | NULL // start time. NULL means ASAP. 226 | ); 227 | } 228 | 229 | 230 | - (void) stop 231 | { 232 | AudioQueueStop ( 233 | queueObject, 234 | TRUE 235 | ); 236 | 237 | [self reset]; 238 | } 239 | 240 | 241 | - (void) setupRecording 242 | { 243 | // allocate and enqueue buffers 244 | int bufferByteSize = 4096; // this is the maximum buffer size used by the player class 245 | int bufferIndex; 246 | 247 | for (bufferIndex = 0; bufferIndex < 20; ++bufferIndex) { 248 | 249 | AudioQueueBufferRef bufferRef; 250 | 251 | AudioQueueAllocateBuffer ( 252 | queueObject, 253 | bufferByteSize, &bufferRef 254 | ); 255 | 256 | AudioQueueEnqueueBuffer ( 257 | queueObject, 258 | bufferRef, 259 | 0, 260 | NULL 261 | ); 262 | } 263 | } 264 | 265 | - (void) idle: (unsigned)samples 266 | { 267 | // Convert to microseconds 268 | UInt64 nsInterval = SAMPLES_TO_NS(samples); 269 | for (id rec in recognizers) 270 | [rec idle:nsInterval]; 271 | } 272 | 273 | - (void) edge: (int)height width:(unsigned)width interval:(unsigned)interval 274 | { 275 | // Convert to microseconds 276 | UInt64 nsInterval = SAMPLES_TO_NS(interval); 277 | UInt64 nsWidth = SAMPLES_TO_NS(width); 278 | for (id rec in recognizers) 279 | [rec edge:height width:nsWidth interval:nsInterval]; 280 | } 281 | 282 | - (void) reset 283 | { 284 | [recognizers makeObjectsPerformSelector:@selector(reset)]; 285 | 286 | memset(&pulseData, 0, sizeof(pulseData)); 287 | } 288 | 289 | @end 290 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/AudioSignalGenerator.h: -------------------------------------------------------------------------------- 1 | // 2 | // AudioSignalGenerator.h 3 | // FSK Terminal 4 | // 5 | // Created by George Dean on 1/6/09. 6 | // Copyright 2009 Perceptive Development. All rights reserved. 7 | // 8 | // Edited by Ezequiel Franca on 20/04/14 9 | 10 | #import "AudioQueueObject.h" 11 | 12 | 13 | @interface AudioSignalGenerator : AudioQueueObject { 14 | 15 | AudioQueueBufferRef buffers[kNumberAudioDataBuffers]; // the audio queue buffers for the audio queue 16 | 17 | UInt32 bufferByteSize; // the number of bytes to use in each audio queue buffer 18 | UInt32 bufferPacketCount; 19 | 20 | AudioStreamPacketDescription *packetDescriptions; 21 | 22 | BOOL stopped; 23 | BOOL audioPlayerShouldStopImmediately; 24 | } 25 | 26 | @property (readwrite) AudioStreamPacketDescription *packetDescriptions; 27 | @property (readwrite) BOOL stopped, audioPlayerShouldStopImmediately; 28 | @property (readwrite) UInt32 bufferByteSize; 29 | @property (readwrite) UInt32 bufferPacketCount; 30 | 31 | - (void) setupAudioFormat; 32 | - (void) setupPlaybackAudioQueueObject; 33 | - (void) setupAudioQueueBuffers; 34 | 35 | - (void) play; 36 | - (void) stop; 37 | - (void) pause; 38 | - (void) resume; 39 | 40 | - (void) fillBuffer:(void*)buffer; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/AudioSignalGenerator.m: -------------------------------------------------------------------------------- 1 | // 2 | // AudioSignalGenerator.m 3 | // FSK Terminal 4 | // 5 | // Created by George Dean on 1/6/09. 6 | // Copyright 2009 Perceptive Development. All rights reserved. 7 | // 8 | // Edited by Ezequiel Franca on 20/04/14 9 | 10 | #include 11 | #import "AudioQueueObject.h" 12 | #import "AudioSignalGenerator.h" 13 | 14 | 15 | static void playbackCallback ( 16 | void *inUserData, 17 | AudioQueueRef inAudioQueue, 18 | AudioQueueBufferRef bufferReference 19 | ) { 20 | // This is not a Cocoa thread, it needs a manually allocated pool 21 | // NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 22 | 23 | // This callback, being outside the implementation block, needs a reference to the AudioSignalGenerator object 24 | AudioSignalGenerator *player = (__bridge AudioSignalGenerator *) inUserData; 25 | if ([player stopped]) return; 26 | 27 | [player fillBuffer:bufferReference->mAudioData]; 28 | 29 | bufferReference->mAudioDataByteSize = player.bufferByteSize; 30 | 31 | AudioQueueEnqueueBuffer ( 32 | inAudioQueue, 33 | bufferReference, 34 | player.bufferPacketCount, 35 | player.packetDescriptions 36 | ); 37 | 38 | // [pool release]; 39 | } 40 | 41 | @implementation AudioSignalGenerator 42 | 43 | @synthesize packetDescriptions; 44 | @synthesize bufferByteSize; 45 | @synthesize bufferPacketCount; 46 | @synthesize stopped; 47 | @synthesize audioPlayerShouldStopImmediately; 48 | 49 | 50 | - (id) init { 51 | 52 | self = [super init]; 53 | 54 | if (self != nil) { 55 | [self setupAudioFormat]; 56 | [self setupPlaybackAudioQueueObject]; 57 | self.stopped = NO; 58 | self.audioPlayerShouldStopImmediately = NO; 59 | } 60 | 61 | return self; 62 | } 63 | 64 | - (void) setupAudioFormat { 65 | } 66 | 67 | - (void) fillBuffer: (void*) buffer 68 | { 69 | } 70 | 71 | - (void) setupPlaybackAudioQueueObject { 72 | 73 | // create the playback audio queue object 74 | AudioQueueNewOutput ( 75 | &audioFormat, 76 | playbackCallback, 77 | (__bridge void *)(self), 78 | nil, 79 | nil, 80 | 0, // run loop flags 81 | &queueObject 82 | ); 83 | 84 | AudioQueueSetParameter ( 85 | queueObject, 86 | kAudioQueueParam_Volume, 87 | 1.0f 88 | ); 89 | 90 | } 91 | 92 | - (void) setupAudioQueueBuffers { 93 | 94 | // prime the queue with some data before starting 95 | // allocate and enqueue buffers 96 | int bufferIndex; 97 | 98 | for (bufferIndex = 0; bufferIndex < 3; ++bufferIndex) { 99 | 100 | AudioQueueAllocateBuffer ( 101 | [self queueObject], 102 | [self bufferByteSize], 103 | &buffers[bufferIndex] 104 | ); 105 | 106 | playbackCallback ( 107 | (__bridge void *)(self), 108 | [self queueObject], 109 | buffers[bufferIndex] 110 | ); 111 | 112 | if ([self stopped]) break; 113 | } 114 | } 115 | 116 | 117 | - (void) play { 118 | 119 | [self setupAudioQueueBuffers]; 120 | 121 | AudioQueueStart ( 122 | self.queueObject, 123 | NULL // start time. NULL means ASAP. 124 | ); 125 | } 126 | 127 | - (void) stop { 128 | 129 | AudioQueueStop ( 130 | self.queueObject, 131 | self.audioPlayerShouldStopImmediately 132 | ); 133 | 134 | } 135 | 136 | 137 | - (void) pause { 138 | 139 | AudioQueuePause ( 140 | self.queueObject 141 | ); 142 | } 143 | 144 | 145 | - (void) resume { 146 | 147 | AudioQueueStart ( 148 | self.queueObject, 149 | NULL // start time. NULL means ASAP 150 | ); 151 | } 152 | 153 | @end 154 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/CharReceiver.h: -------------------------------------------------------------------------------- 1 | // 2 | // CharReceiver.h 3 | // FSK Terminal 4 | // 5 | // Created by George Dean on 1/18/09. 6 | // Copyright 2009 Perceptive Development. All rights reserved. 7 | // 8 | // Edited by Ezequiel Franca on 20/04/14 9 | 10 | #import 11 | 12 | 13 | @protocol CharReceiver 14 | 15 | - (void) receivedChar:(char)input; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/FSKByteQueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSKByteQueue.h 3 | // SoftModemTerminal 4 | // 5 | // Created by arms22 on 10/07/22. 6 | // Copyright 2010 __MyCompanyName__. All rights reserved. 7 | // 8 | // Edited by Ezequiel Franca on 20/04/14 9 | 10 | #import "lockfree.h" 11 | 12 | struct FSKByteQueue: public lock_free::queue { 13 | FSKByteQueue(): lock_free::queue(256){}; 14 | }; 15 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/FSKModemConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSKModemConfig.h 3 | // 4 | // Created by arms22 on 10/05/06. 5 | // Copyright 2010 __MyCompanyName__. All rights reserved. 6 | // 7 | // Edited by Ezequiel Franca on 20/04/14 8 | 9 | //#define FREQ_LOW 882 10 | //#define FREQ_HIGH 1764 11 | //#define BAUD 126 12 | 13 | //#define FREQ_LOW 630 14 | //#define FREQ_HIGH 1260 15 | //#define BAUD 126 16 | 17 | //#define FREQ_LOW 800 18 | //#define FREQ_HIGH 1600 19 | //#define BAUD 100 20 | 21 | //#define FREQ_LOW 1575 22 | //#define FREQ_HIGH 3150 23 | //#define BAUD 315 24 | 25 | //#define FREQ_LOW 2666 26 | //#define FREQ_HIGH 4000 27 | //#define BAUD 600 28 | 29 | //#define FREQ_LOW 3150 30 | //#define FREQ_HIGH 6300 31 | //#define BAUD 630 32 | 33 | #define FREQ_LOW 4900 34 | #define FREQ_HIGH 7350 35 | #define BAUD 1225 36 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/FSKRecognizer.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSKRecognizer.h 3 | // FSK Terminal 4 | // 5 | // Created by George Dean on 12/22/08. 6 | // Copyright 2008 Perceptive Development. All rights reserved. 7 | // 8 | // Edited by Ezequiel Franca on 20/04/14 9 | 10 | #import "PatternRecognizer.h" 11 | 12 | #define FSK_SMOOTH 3 13 | 14 | typedef enum 15 | { 16 | FSKStart, 17 | FSKBits, 18 | FSKSuccess, 19 | FSKFail 20 | } FSKRecState; 21 | 22 | @class MultiDelegate; 23 | 24 | @protocol CharReceiver; 25 | 26 | struct FSKByteQueue; 27 | 28 | @interface FSKRecognizer : NSObject { 29 | unsigned recentLows; 30 | unsigned recentHighs; 31 | unsigned halfWaveHistory[FSK_SMOOTH]; 32 | unsigned bitPosition; 33 | unsigned recentWidth; 34 | unsigned recentAvrWidth; 35 | char bits; 36 | FSKRecState state; 37 | MultiDelegate* receivers; 38 | struct FSKByteQueue* byteQueue; 39 | } 40 | 41 | - (void) addReceiver:(id)receiver; 42 | 43 | - (void) edge: (int)height width:(UInt64)nsWidth interval:(UInt64)nsInterval; 44 | - (void) idle: (UInt64)nsInterval; 45 | - (void) reset; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/FSKRecognizer.mm: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // FSKRecognizer.mm 4 | // FSK Terminal 5 | // 6 | // Created by George Dean on 12/22/08. 7 | // Copyright 2008 Perceptive Development. All rights reserved. 8 | // 9 | // Edited by Ezequiel Franca on 20/04/14 10 | 11 | #import "FSKModemConfig.h" 12 | #import "FSKRecognizer.h" 13 | #import "FSKByteQueue.h" 14 | #import "MultiDelegate.h" 15 | #import "CharReceiver.h" 16 | 17 | #define WL_HIGH (1000000000 / FREQ_HIGH) 18 | #define WL_LOW (1000000000 / FREQ_LOW) 19 | #define HWL_HIGH (500000000 / FREQ_HIGH) 20 | #define HWL_LOW (500000000 / FREQ_LOW) 21 | 22 | #define SMOOTHER_COUNT (FSK_SMOOTH * (FSK_SMOOTH + 1) / 2) 23 | 24 | #define DISCRIMINATOR (SMOOTHER_COUNT * (WL_HIGH + WL_LOW) / 4) 25 | 26 | #define BIT_PERIOD (1000000000 / BAUD) 27 | #define HALF_BIT_PERIOD (500000000 / BAUD) 28 | 29 | @implementation FSKRecognizer 30 | 31 | - (id) init 32 | { 33 | if(self = [super init]) 34 | { 35 | receivers = [[MultiDelegate alloc] init]; 36 | byteQueue = new FSKByteQueue(); 37 | [self reset]; 38 | } 39 | 40 | return self; 41 | } 42 | 43 | - (void) addReceiver:(id)receiver 44 | { 45 | [receivers addDelegate:receiver]; 46 | } 47 | 48 | - (void) commitBytes 49 | { 50 | char input; 51 | while (byteQueue->get(input)) 52 | { 53 | //NSLog(@"Byte: %c (%02x)", input, (unsigned char)input); 54 | [receivers receivedChar:input]; 55 | } 56 | } 57 | 58 | - (void) dataBit:(BOOL)one 59 | { 60 | if(one) 61 | bits |= (1 << bitPosition); 62 | bitPosition++; 63 | } 64 | 65 | - (void) freqRegion:(unsigned)length high:(BOOL)high 66 | { 67 | FSKRecState newState = FSKFail; 68 | switch (state) { 69 | case FSKStart: 70 | if(!high) // Start Bit 71 | { 72 | //NSLog(@"Start bit: %c %d", high?'H':'L', length); 73 | newState = FSKBits; 74 | bits = 0; 75 | bitPosition = 0; 76 | } 77 | else 78 | newState = FSKStart; 79 | break; 80 | case FSKBits: 81 | //NSLog(@"Bit: %c %d", high?'H':'L', length); 82 | if((bitPosition <= 7)){ //Data Bits 83 | newState = FSKBits; 84 | [self dataBit:high]; 85 | } 86 | else if(bitPosition == 8){ // Stop Bit 87 | newState = FSKStart; 88 | byteQueue->put(bits); 89 | [self performSelectorOnMainThread:@selector(commitBytes) 90 | withObject:nil 91 | waitUntilDone:NO]; 92 | bits = 0; 93 | bitPosition = 0; 94 | } 95 | break; 96 | case FSKSuccess: 97 | NSLog(@"FSKSucess"); 98 | break; 99 | case FSKFail: 100 | NSLog(@"FSKFail"); 101 | break; 102 | } 103 | state = newState; 104 | } 105 | 106 | - (void) halfWave:(unsigned)width 107 | { 108 | for (int i = FSK_SMOOTH - 2; i >= 0; i--) { 109 | halfWaveHistory[i+1] = halfWaveHistory[i]; 110 | } 111 | halfWaveHistory[0] = width; 112 | 113 | unsigned waveSum = 0; 114 | for(int i=0; i recentLows) 138 | { 139 | // NSLog(@"False start: %d", recentLows); 140 | recentLows = recentHighs = 0; 141 | } 142 | } 143 | 144 | if(recentLows + recentHighs >= BIT_PERIOD) 145 | { 146 | [self freqRegion:recentLows high:FALSE]; 147 | recentWidth = recentAvrWidth = 0; 148 | if(recentLows < BIT_PERIOD) 149 | { 150 | recentLows = 0; 151 | } 152 | else 153 | { 154 | recentLows -= BIT_PERIOD; 155 | } 156 | if(!high) 157 | recentHighs = 0; 158 | } 159 | } 160 | else 161 | { 162 | if(high) 163 | recentHighs += avgWidth; 164 | else 165 | recentLows += avgWidth; 166 | 167 | if(recentLows + recentHighs >= BIT_PERIOD) 168 | { 169 | BOOL regionHigh = (recentHighs > recentLows); 170 | [self freqRegion:regionHigh?recentHighs:recentLows high:regionHigh]; 171 | 172 | recentWidth -= BIT_PERIOD; 173 | recentAvrWidth -= BIT_PERIOD; 174 | 175 | if(state == FSKStart) 176 | { 177 | // The byte ended, reset the accumulators 178 | recentLows = recentHighs = 0; 179 | return; 180 | } 181 | 182 | unsigned* matched = regionHigh?&recentHighs:&recentLows; 183 | unsigned* unmatched = regionHigh?&recentLows:&recentHighs; 184 | if(*matched < BIT_PERIOD) 185 | { 186 | *matched = 0; 187 | } 188 | else 189 | { 190 | *matched -= BIT_PERIOD; 191 | } 192 | if(high == regionHigh) 193 | *unmatched = 0; 194 | } 195 | } 196 | } 197 | 198 | - (void) edge: (int)height width:(UInt64)nsWidth interval:(UInt64)nsInterval 199 | { 200 | if(nsInterval <= HWL_LOW + HWL_HIGH) 201 | [self halfWave:(unsigned)nsInterval]; 202 | else { 203 | // NSLog(@"skip"); 204 | } 205 | 206 | } 207 | 208 | - (void) idle: (UInt64)nsInterval 209 | { 210 | [self reset]; 211 | } 212 | 213 | - (void) reset 214 | { 215 | bits = 0; 216 | bitPosition = 0; 217 | state = FSKStart; 218 | for (int i = 0; i < FSK_SMOOTH; i++) { 219 | halfWaveHistory[i] = (WL_HIGH + WL_LOW) / 4; 220 | } 221 | recentLows = recentHighs = 0; 222 | } 223 | 224 | @end 225 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/FSKSerialGenerator.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSKSerialGenerator.h 3 | // FSK Terminal 4 | // 5 | // Created by George Dean on 1/7/09. 6 | // Copyright 2009 Perceptive Development. All rights reserved. 7 | // 8 | // Edited by Ezequiel Franca on 20/04/14 9 | 10 | #import "AudioSignalGenerator.h" 11 | 12 | struct FSKByteQueue; 13 | 14 | @interface FSKSerialGenerator : AudioSignalGenerator { 15 | float nsBitProgress; 16 | unsigned sineTableIndex; 17 | 18 | unsigned bitCount; 19 | UInt16 bits; 20 | 21 | BOOL byteUnderflow; 22 | BOOL sendCarrier; 23 | 24 | struct FSKByteQueue* byteQueue; 25 | } 26 | 27 | - (void) writeByte:(UInt8)byte; 28 | - (void) writeBytes:(const UInt8 *)bytes length:(int)length; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/FSKSerialGenerator.mm: -------------------------------------------------------------------------------- 1 | // 2 | // FSKSerialGenerator.m 3 | // FSK Terminal 4 | // 5 | // Created by George Dean on 1/7/09. 6 | // Copyright 2009 Perceptive Development. All rights reserved. 7 | // 8 | // Edited by Ezequiel Franca on 20/04/14 9 | 10 | #import "FSKModemConfig.h" 11 | #import "FSKSerialGenerator.h" 12 | #import "FSKByteQueue.h" 13 | 14 | #define SAMPLE_RATE 44100 15 | #define SAMPLE SInt16 16 | #define SAMPLE_MAX 32767 17 | #define NUM_CHANNELS 1 18 | 19 | #define BITS_PER_CHANNEL (sizeof(SAMPLE) * 8) 20 | #define BYTES_PER_FRAME (NUM_CHANNELS * sizeof(SAMPLE)) 21 | 22 | #define SAMPLE_DURATION (1000000000 / SAMPLE_RATE) 23 | #define SAMPLES_TO_NS(__samples__) (((UInt64)(__samples__) * 1000000000) / SAMPLE_RATE) 24 | #define NS_TO_SAMPLES(__nanosec__) (unsigned)(((UInt64)(__nanosec__) * SAMPLE_RATE) / 1000000000) 25 | #define US_TO_SAMPLES(__microsec__) (unsigned)(((UInt64)(__microsec__) * SAMPLE_RATE) / 1000000) 26 | #define MS_TO_SAMPLES(__millisec__) (unsigned)(((UInt64)(__millisec__) * SAMPLE_RATE) / 1000) 27 | 28 | #define WL_HIGH (1000000000 / FREQ_HIGH) 29 | #define WL_LOW (1000000000 / FREQ_LOW) 30 | #define HWL_HIGH (500000000 / FREQ_HIGH) 31 | #define HWL_LOW (500000000 / FREQ_LOW) 32 | 33 | #define BIT_PERIOD (1000000000 / BAUD) 34 | 35 | #define SINE_TABLE_LENGTH 441 36 | 37 | #define PRE_CARRIER_BITS ((40000000+BIT_PERIOD)/BIT_PERIOD) 38 | #define POST_CARRIER_BITS (( 5000000+BIT_PERIOD)/BIT_PERIOD) 39 | 40 | // TABLE_JUMP = phase_per_sample / phase_per_entry 41 | // phase_per_sample = 2pi * time_per_sample / time_per_wave 42 | // phase_per_entry = 2pi / SINE_TABLE_LENGTH 43 | // TABLE_JUMP = time_per_sample / time_per_wave * SINE_TABLE_LENGTH 44 | // time_per_sample = 1000000000 / SAMPLE_RATE 45 | // time_per_wave = 1000000000 / FREQ 46 | // TABLE_JUMP = FREQ / SAMPLE_RATE * SINE_TABLE_LENGTH 47 | #define TABLE_JUMP_HIGH (FREQ_HIGH * SINE_TABLE_LENGTH / SAMPLE_RATE) 48 | #define TABLE_JUMP_LOW (FREQ_LOW * SINE_TABLE_LENGTH / SAMPLE_RATE) 49 | 50 | SAMPLE sineTable[SINE_TABLE_LENGTH]; 51 | 52 | @implementation FSKSerialGenerator 53 | 54 | - (id) init 55 | { 56 | if (self = [super init]) 57 | { 58 | byteQueue = new FSKByteQueue(); 59 | byteUnderflow = YES; 60 | for(int i=0; iempty()) 89 | { 90 | bits = 1; 91 | bitCount = PRE_CARRIER_BITS; 92 | sendCarrier = YES; 93 | byteUnderflow = NO; 94 | return YES; 95 | } 96 | } 97 | else 98 | { 99 | if(byteQueue->get(byte)) 100 | { 101 | bits = ((UInt16)byte << 1) | (0x0200); 102 | bitCount = 10; 103 | sendCarrier = NO; 104 | return YES; 105 | } 106 | else 107 | { 108 | bits = 1; 109 | bitCount = POST_CARRIER_BITS; 110 | sendCarrier = YES; 111 | byteUnderflow = YES; 112 | return YES; 113 | } 114 | } 115 | bits = 1; // Make sure the output is HIGH when there is no data 116 | return NO; 117 | } 118 | 119 | - (void) fillBuffer:(void*)buffer 120 | { 121 | SAMPLE* sample = (SAMPLE*)buffer; 122 | BOOL underflow = NO; 123 | 124 | if(!bitCount) 125 | underflow = ![self getNextByte]; 126 | 127 | for(int i=0; i= BIT_PERIOD) 130 | { 131 | if(bitCount) 132 | { 133 | --bitCount; 134 | if(!sendCarrier) 135 | bits >>= 1; 136 | } 137 | nsBitProgress -= BIT_PERIOD; 138 | if(!bitCount) 139 | underflow = ![self getNextByte]; 140 | } 141 | 142 | if(underflow){ 143 | *sample = 0; 144 | } 145 | else{ 146 | sineTableIndex += (bits & 1)?TABLE_JUMP_HIGH:TABLE_JUMP_LOW; 147 | if(sineTableIndex >= SINE_TABLE_LENGTH) 148 | sineTableIndex -= SINE_TABLE_LENGTH; 149 | *sample = sineTable[sineTableIndex]; 150 | } 151 | 152 | if(bitCount) 153 | nsBitProgress += SAMPLE_DURATION; 154 | } 155 | } 156 | 157 | - (void) writeByte:(UInt8)byte 158 | { 159 | byteQueue->put((char)byte); 160 | } 161 | 162 | - (void) writeBytes:(const UInt8 *)bytes length:(int)length 163 | { 164 | for(int i = 0; iput((char)*bytes++); 166 | } 167 | } 168 | 169 | @end 170 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/MultiDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // MultiDelegate.h 3 | // iNfrared 4 | // 5 | // Created by George Dean on 1/19/09. 6 | // Copyright 2009 Perceptive Development. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CharReceiver.h" 11 | 12 | @interface MultiDelegate : NSObject { 13 | NSMutableSet* delegateSet; 14 | Protocol* proto; 15 | } 16 | 17 | - (id) initWithProtocol:(Protocol*)p; 18 | - (void) addDelegate:(id)delegate; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/MultiDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // MultiDelegate.m 3 | // iNfrared 4 | // 5 | // Created by George Dean on 1/19/09. 6 | // Copyright 2009 Perceptive Development. All rights reserved. 7 | // 8 | 9 | #import "MultiDelegate.h" 10 | #import 11 | 12 | @implementation MultiDelegate 13 | 14 | - (id) initWithProtocol:(Protocol*)p 15 | { 16 | if(self = [super init]) 17 | { 18 | proto = p; 19 | } 20 | 21 | return self; 22 | } 23 | 24 | - (void) addDelegate:(id)delegate 25 | { 26 | if(!delegateSet) 27 | delegateSet = [[NSMutableSet alloc] init]; 28 | [delegateSet addObject:delegate]; 29 | } 30 | 31 | - (NSMethodSignature*) methodSignatureForSelector:(SEL)selector 32 | { 33 | if([delegateSet count]) 34 | return [[delegateSet anyObject] methodSignatureForSelector:selector]; 35 | 36 | if(proto) 37 | { 38 | struct objc_method_description desc = protocol_getMethodDescription(proto, selector, YES, YES); 39 | return [NSMethodSignature signatureWithObjCTypes:desc.types]; 40 | } 41 | 42 | // return void-void signature by default 43 | return nil; 44 | //return [self methodSignatureForSelector:@selector(void)]; 45 | } 46 | 47 | - (void) forwardInvocation:(NSInvocation*)invocation 48 | { 49 | if(delegateSet) for (id delegate in delegateSet) { 50 | if([delegate respondsToSelector:[invocation selector]]) 51 | [invocation invokeWithTarget:delegate]; 52 | } 53 | } 54 | 55 | //- (void) receivedChar:(char)input{ 56 | // // 57 | //} 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/PatternRecognizer.h: -------------------------------------------------------------------------------- 1 | // 2 | // PatternRecognizer.h 3 | // iNfrared 4 | // 5 | // Created by George Dean on 12/22/08. 6 | // Copyright 2008 Perceptive Development. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @protocol PatternRecognizer 13 | 14 | - (void) edge: (int)height width:(UInt64)nsWidth interval:(UInt64)nsInterval; 15 | - (void) idle: (UInt64)nsInterval; 16 | - (void) reset; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /FSK-Demo/FSK-Demo/Class/SoftModem/lockfree.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #ifdef __APPLE__ 6 | 7 | #include 8 | 9 | #endif 10 | 11 | 12 | // This is a collection of lock-free data structures that use atomic operations 13 | // to ensure thread safety. Based on the C# examples from a series of articles 14 | // by Julian M. Bucknall. The first article can be found here: 15 | // 16 | // http://www.boyet.com/Articles/LockfreeStack.html 17 | 18 | namespace lock_free 19 | { 20 | 21 | // The linked list node for lock-free data structures 22 | template 23 | struct node 24 | { 25 | node* volatile next; 26 | T data; 27 | 28 | node():next(NULL),data(){} 29 | }; 30 | 31 | // This is the classic atomic compare-and-swap operation. Pseudocode: 32 | // if (dest == oldValue){ 33 | // dest = newValue; 34 | // return true; 35 | // }else{ 36 | // return false; 37 | // } 38 | template 39 | inline static bool atomic_cas(node* volatile &dest, node* oldValue, node* newValue) 40 | { 41 | #ifdef WIN32 42 | return oldValue == (node*)InterlockedCompareExchangePointer((volatile PVOID*)&dest, newValue, oldValue); 43 | #endif 44 | #ifdef __APPLE__ 45 | return OSAtomicCompareAndSwapPtr(oldValue, newValue, (void* volatile *)&dest); 46 | #endif 47 | } 48 | 49 | 50 | 51 | // Basic functionality of a lock-free stack implemented as a linked list 52 | template 53 | class node_stack 54 | { 55 | public: 56 | node_stack() 57 | { 58 | head = NULL; 59 | } 60 | 61 | bool empty() const 62 | { 63 | return head; 64 | } 65 | 66 | protected: 67 | // Add a node to the head of the list 68 | void node_add(node* pNewHead) 69 | { 70 | // Just keep trying to push until it succeeds 71 | do{ 72 | pNewHead->next = head; 73 | }while(!atomic_cas(head, pNewHead->next, pNewHead)); 74 | } 75 | 76 | // Pop a node from the head of the list 77 | node* node_remove() 78 | { 79 | node* pOldHead; 80 | 81 | // Keep trying to pop until it succeeds or the list is empty 82 | do{ 83 | // If the head is NULL then the list is empty, so return NULL 84 | if(!(pOldHead = head)) 85 | return NULL; 86 | }while(!atomic_cas(head, pOldHead, pOldHead->next)); 87 | return pOldHead; 88 | } 89 | 90 | // Pointer to the head of the node list 91 | node* volatile head; 92 | }; 93 | 94 | 95 | 96 | // Basic functionality of a lock-free queue implemented as a linked list 97 | template 98 | class node_queue 99 | { 100 | public: 101 | node_queue():tail(NULL),dummy(NULL){} 102 | 103 | bool empty() const 104 | { 105 | return tail == dummy; 106 | } 107 | 108 | protected: 109 | // Add a node to the tail of the list 110 | void node_add(node* pNewTail) 111 | { 112 | node *pOldTail = nullptr, *pOldNext; 113 | 114 | // Loop until we have managed to update the tail's Next link 115 | // to point to our new node 116 | bool done = false; 117 | while(!done) 118 | { 119 | pOldTail = tail; 120 | pOldNext = pOldTail->next; 121 | 122 | // A lot could have changed between those statements, so check 123 | // if things still look the same 124 | if(tail != pOldTail) 125 | continue; 126 | 127 | if(pOldNext) 128 | { 129 | // If the tail's Next field was non-null, then another thread 130 | // has pushed a new tail, so try to advance the tail pointer 131 | atomic_cas(tail, pOldTail, pOldNext); 132 | continue; 133 | } 134 | 135 | // Make our new node the tail's Next node 136 | done = atomic_cas(pOldTail->next, pOldNext, pNewTail); 137 | } 138 | 139 | // Try to advance the tail pointer to point to our node; if this fails, 140 | // that means another thread already took care of it 141 | atomic_cas(tail, pOldTail, pNewTail); 142 | } 143 | 144 | // Pop a node from the head of the list 145 | node* node_remove() 146 | { 147 | T tempData = T(); 148 | node *pOldDummy = nullptr, *pOldHead; 149 | 150 | // Keep trying to pop until it succeeds or the list is empty 151 | bool done = false; 152 | while(!done) 153 | { 154 | pOldDummy = dummy; 155 | pOldHead = pOldDummy->next; 156 | node* pOldTail = tail; 157 | 158 | // A lot could have changed between those statements, so check 159 | // if things still look the same 160 | if(dummy != pOldDummy) 161 | continue; 162 | 163 | // If the head is NULL then the list is empty, so return NULL 164 | if(!pOldHead) 165 | return NULL; 166 | 167 | // If the tail is pointed at the dummy but the list is not empty, 168 | // then we should try to advance the tail 169 | if(pOldTail == pOldDummy) 170 | { 171 | atomic_cas(tail, pOldTail, pOldHead); 172 | continue; 173 | } 174 | 175 | // Store the data in case this succeeds 176 | tempData = pOldHead->data; 177 | 178 | // Try to advance the dummy so the head becomes the new dummy 179 | done = atomic_cas(dummy, pOldDummy, pOldHead); 180 | } 181 | 182 | pOldDummy->data = tempData; 183 | return pOldDummy; 184 | } 185 | 186 | // Pointer to the dummy node at the head of the list 187 | node* volatile dummy; 188 | 189 | // Pointer to the tail of the list 190 | node* volatile tail; 191 | }; 192 | 193 | 194 | 195 | // A simple new/delete allocator for lock-free nodes 196 | template 197 | class node_allocator 198 | { 199 | public: 200 | node* acquire() 201 | { 202 | return new node; 203 | } 204 | 205 | void release(node* pNode) 206 | { 207 | delete pNode; 208 | } 209 | }; 210 | 211 | 212 | 213 | // A free-node list used to store and allocate nodes for lock-free structures 214 | template 215 | class cached_node_allocator: public node_stack 216 | { 217 | using node_stack::node_remove; 218 | 219 | public: 220 | cached_node_allocator(int nPreAllocate = 0) 221 | { 222 | // Preallocate some nodes and add them to the free node list 223 | for(int i=0; i); 226 | } 227 | } 228 | 229 | ~cached_node_allocator() 230 | { 231 | // Pop and delete all nodes from the list 232 | node* pNode; 233 | while((pNode = node_remove())) 234 | delete pNode; 235 | } 236 | 237 | 238 | // Get a free node 239 | node* acquire() 240 | { 241 | // Try to get one from the head of the list 242 | node* pOldHead = node_remove(); 243 | 244 | // If the free node list is empty, allocate a new one 245 | if(!pOldHead) 246 | pOldHead = new node; 247 | 248 | // Clear the Next pointer 249 | pOldHead->next = NULL; 250 | return pOldHead; 251 | } 252 | 253 | // Add a node to the head of the free node list 254 | void release(node* pNode) 255 | { 256 | this->node_add(pNode); 257 | } 258 | }; 259 | 260 | 261 | 262 | // A lock-free collection implementation layer with node allocator support 263 | template