comparison base/Pitch.cpp @ 1025:88b54a185a0a

Use double instead of float for frequencies in Pitch, just for confidence
author Chris Cannam
date Mon, 08 Dec 2014 15:37:12 +0000
parents d1ce7a4a920b
children cc27f35aa75c
comparison
equal deleted inserted replaced
1024:d1ce7a4a920b 1025:88b54a185a0a
17 #include "Preferences.h" 17 #include "Preferences.h"
18 #include "system/System.h" 18 #include "system/System.h"
19 19
20 #include <cmath> 20 #include <cmath>
21 21
22 float 22 double
23 Pitch::getFrequencyForPitch(int midiPitch, 23 Pitch::getFrequencyForPitch(int midiPitch,
24 float centsOffset, 24 double centsOffset,
25 float concertA) 25 double concertA)
26 { 26 {
27 if (concertA <= 0.0) { 27 if (concertA <= 0.0) {
28 concertA = Preferences::getInstance()->getTuningFrequency(); 28 concertA = Preferences::getInstance()->getTuningFrequency();
29 } 29 }
30 float p = float(midiPitch) + (centsOffset / 100); 30 double p = double(midiPitch) + (centsOffset / 100);
31 return concertA * powf(2.0, (p - 69.0) / 12.0); 31 return concertA * pow(2.0, (p - 69.0) / 12.0);
32 } 32 }
33 33
34 int 34 int
35 Pitch::getPitchForFrequency(float frequency, 35 Pitch::getPitchForFrequency(double frequency,
36 float *centsOffsetReturn, 36 double *centsOffsetReturn,
37 float concertA) 37 double concertA)
38 { 38 {
39 if (concertA <= 0.0) { 39 if (concertA <= 0.0) {
40 concertA = Preferences::getInstance()->getTuningFrequency(); 40 concertA = Preferences::getInstance()->getTuningFrequency();
41 } 41 }
42 float p = 12.0 * (log(frequency / (concertA / 2.0)) / log(2.0)) + 57.0; 42 double p = 12.0 * (log(frequency / (concertA / 2.0)) / log(2.0)) + 57.0;
43 43
44 int midiPitch = int(p + 0.00001); 44 int midiPitch = int(round(p));
45 float centsOffset = (p - midiPitch) * 100.0; 45 double centsOffset = (p - midiPitch) * 100.0;
46 46
47 if (centsOffset >= 50.0) { 47 if (centsOffset >= 50.0) {
48 midiPitch = midiPitch + 1; 48 midiPitch = midiPitch + 1;
49 centsOffset = -(100.0 - centsOffset); 49 centsOffset = -(100.0 - centsOffset);
50 } 50 }
51 if (centsOffset < -50.0) {
52 midiPitch = midiPitch - 1;
53 centsOffset = (100.0 + centsOffset);
54 }
51 55
52 if (centsOffsetReturn) *centsOffsetReturn = centsOffset; 56 if (centsOffsetReturn) *centsOffsetReturn = centsOffset;
53 return midiPitch; 57 return midiPitch;
54 } 58 }
55 59
56 int 60 int
57 Pitch::getPitchForFrequencyDifference(float frequencyA, 61 Pitch::getPitchForFrequencyDifference(double frequencyA,
58 float frequencyB, 62 double frequencyB,
59 float *centsOffsetReturn, 63 double *centsOffsetReturn,
60 float concertA) 64 double concertA)
61 { 65 {
62 if (concertA <= 0.0) { 66 if (concertA <= 0.0) {
63 concertA = Preferences::getInstance()->getTuningFrequency(); 67 concertA = Preferences::getInstance()->getTuningFrequency();
64 } 68 }
65 69
66 if (frequencyA > frequencyB) { 70 if (frequencyA > frequencyB) {
67 std::swap(frequencyA, frequencyB); 71 std::swap(frequencyA, frequencyB);
68 } 72 }
69 73
70 float pA = 12.0 * (log(frequencyA / (concertA / 2.0)) / log(2.0)) + 57.0; 74 double pA = 12.0 * (log(frequencyA / (concertA / 2.0)) / log(2.0)) + 57.0;
71 float pB = 12.0 * (log(frequencyB / (concertA / 2.0)) / log(2.0)) + 57.0; 75 double pB = 12.0 * (log(frequencyB / (concertA / 2.0)) / log(2.0)) + 57.0;
72 76
73 float p = pB - pA; 77 double p = pB - pA;
74 78
75 int midiPitch = int(p + 0.00001); 79 int midiPitch = int(p + 0.00001);
76 float centsOffset = (p - midiPitch) * 100.0; 80 double centsOffset = (p - midiPitch) * 100.0;
77 81
78 if (centsOffset >= 50.0) { 82 if (centsOffset >= 50.0) {
79 midiPitch = midiPitch + 1; 83 midiPitch = midiPitch + 1;
80 centsOffset = -(100.0 - centsOffset); 84 centsOffset = -(100.0 - centsOffset);
81 } 85 }
127 note = midiPitch % 12; 131 note = midiPitch % 12;
128 } 132 }
129 133
130 QString 134 QString
131 Pitch::getPitchLabel(int midiPitch, 135 Pitch::getPitchLabel(int midiPitch,
132 float centsOffset, 136 double centsOffset,
133 bool useFlats) 137 bool useFlats)
134 { 138 {
135 int note, octave; 139 int note, octave;
136 getNoteAndOctaveForPitch(midiPitch, note, octave); 140 getNoteAndOctaveForPitch(midiPitch, note, octave);
137 141
138 QString plain = (useFlats ? flatNotes : notes)[note].arg(octave); 142 QString plain = (useFlats ? flatNotes : notes)[note].arg(octave);
139 143
140 int ic = lrintf(centsOffset); 144 int ic = lrint(centsOffset);
141 if (ic == 0) return plain; 145 if (ic == 0) return plain;
142 else if (ic > 0) return QString("%1+%2c").arg(plain).arg(ic); 146 else if (ic > 0) return QString("%1+%2c").arg(plain).arg(ic);
143 else return QString("%1%2c").arg(plain).arg(ic); 147 else return QString("%1%2c").arg(plain).arg(ic);
144 } 148 }
145 149
146 QString 150 QString
147 Pitch::getPitchLabelForFrequency(float frequency, 151 Pitch::getPitchLabelForFrequency(double frequency,
148 float concertA, 152 double concertA,
149 bool useFlats) 153 bool useFlats)
150 { 154 {
151 if (concertA <= 0.0) { 155 if (concertA <= 0.0) {
152 concertA = Preferences::getInstance()->getTuningFrequency(); 156 concertA = Preferences::getInstance()->getTuningFrequency();
153 } 157 }
154 float centsOffset = 0.0; 158 double centsOffset = 0.0;
155 int midiPitch = getPitchForFrequency(frequency, &centsOffset, concertA); 159 int midiPitch = getPitchForFrequency(frequency, &centsOffset, concertA);
156 return getPitchLabel(midiPitch, centsOffset, useFlats); 160 return getPitchLabel(midiPitch, centsOffset, useFlats);
157 } 161 }
158 162
159 QString 163 QString
160 Pitch::getLabelForPitchRange(int semis, float cents) 164 Pitch::getLabelForPitchRange(int semis, double cents)
161 { 165 {
162 if (semis > 0) { 166 if (semis > 0) {
163 while (cents < 0.f) { 167 while (cents < 0.0) {
164 --semis; 168 --semis;
165 cents += 100.f; 169 cents += 100.0;
166 } 170 }
167 } 171 }
168 if (semis < 0) { 172 if (semis < 0) {
169 while (cents > 0.f) { 173 while (cents > 0.0) {
170 ++semis; 174 ++semis;
171 cents -= 100.f; 175 cents -= 100.0;
172 } 176 }
173 } 177 }
174 178
175 int ic = lrintf(cents); 179 int ic = lrint(cents);
176 180
177 if (ic == 0) { 181 if (ic == 0) {
178 if (semis >= 12) { 182 if (semis >= 12) {
179 return QString("%1'%2").arg(semis/12).arg(semis - 12*(semis/12)); 183 return QString("%1'%2").arg(semis/12).arg(semis - 12*(semis/12));
180 } else { 184 } else {
196 } 200 }
197 } 201 }
198 } 202 }
199 203
200 bool 204 bool
201 Pitch::isFrequencyInMidiRange(float frequency, 205 Pitch::isFrequencyInMidiRange(double frequency,
202 float concertA) 206 double concertA)
203 { 207 {
204 float centsOffset = 0.0; 208 double centsOffset = 0.0;
205 int midiPitch = getPitchForFrequency(frequency, &centsOffset, concertA); 209 int midiPitch = getPitchForFrequency(frequency, &centsOffset, concertA);
206 return (midiPitch >= 0 && midiPitch < 128); 210 return (midiPitch >= 0 && midiPitch < 128);
207 } 211 }
208 212