-
Notifications
You must be signed in to change notification settings - Fork 0
/
FrequencyDetector.mm
108 lines (91 loc) · 3.42 KB
/
FrequencyDetector.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// -*- Mode: ObjC -*-
//
// Copyright (C) 2011, Brad Howes. All rights reserved.
//
#import "FrequencyDetector.h"
#import "WeightedAverager.h"
NSString* kFrequencyDetectorUnknownBit = @"?";
NSString* kFrequencyDetectorLowBit = @"0";
NSString* kFrequencyDetectorHighBit = @"1";
@implementation FrequencyDetector
@synthesize lowFrequency, highFrequency, observer, nominalHalfBitLength, nominalLowWaveLength, nominalHighWaveLength;
@synthesize currentBitLength, currentBitState;
+ (FrequencyDetector*)createForSampleRate:(Float32)samplesPerSecond bitRate:(Float32)bitsPerSecond
lowFreq:(Float32)lowFreqInHz highFreq:(Float32)highFreqInHz
{
return [[[FrequencyDetector alloc] initForSampleRate:samplesPerSecond
bitRate:bitsPerSecond
lowFreq:lowFreqInHz
highFreq:highFreqInHz] autorelease];
}
- (id)initForSampleRate:(Float32)theSamplesPerSecond bitRate:(Float32)bitsPerSecond
lowFreq:(Float32)lowFreqInHz highFreq:(Float32)highFreqInHz
{
if (self = [super init]) {
samplesPerSecond = theSamplesPerSecond;
Float32 samplesPerBit = samplesPerSecond / bitsPerSecond; // 44100 / 150 = 294 samples / bit
nominalHalfBitLength = samplesPerBit / 2; // 147 samples
self.lowFrequency = lowFreqInHz;
self.highFrequency = highFreqInHz;
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (void)setLowFrequency:(Float32)lowFreqInHz
{
nominalLowWaveLength = samplesPerSecond / lowFreqInHz;
maxLowWaveDeviation = 0.10 * nominalLowWaveLength;
[self reset];
}
- (void)setHighFrequency:(Float32)highFreqInHz
{
nominalHighWaveLength = samplesPerSecond / highFreqInHz;
maxHighWaveDeviation = 0.10 * nominalHighWaveLength;
[self reset];
}
- (void)waveCycleDetected:(WaveCycleDetectorInfo*)info
{
Float32 waveLength = info.sampleCount;
Float32 dLow = fabs(waveLength - nominalLowWaveLength);
Float32 dHigh = fabs(waveLength - nominalHighWaveLength);
if (dLow <= maxLowWaveDeviation) {
if (currentBitState != kFrequencyDetectorLowBit) {
currentBitState = kFrequencyDetectorLowBit;
currentBitLength = 0;
}
}
else if (dHigh <= maxHighWaveDeviation) {
if (currentBitState != kFrequencyDetectorHighBit) {
currentBitState = kFrequencyDetectorHighBit;
currentBitLength = 0;
}
}
if (currentBitState != kFrequencyDetectorUnknownBit) {
//
// We don't announce a new bit until we've accumulated about 1/2 of a bit length. There will be twice as many
// cycles for a 8000 Hz signal vs. a 4000 Hz signal, but the samples per bit are constant.
//
currentBitLength += waveLength;
if (currentBitLength >= nominalHalfBitLength) {
currentBitLength -= 2 * nominalHalfBitLength;
LOG(@"nextBitValue: %@", currentBitState);
if (observer != nil) {
[observer performSelectorOnMainThread:@selector(nextBitValue:)
withObject:currentBitState
waitUntilDone:NO];
}
}
}
}
- (void)reset
{
currentBitState = kFrequencyDetectorUnknownBit;
currentBitLength = 0.0;
}
- (void)updateFromSettings
{
}
@end