मेरे earlier question से निम्नलिखित के बाद, मेरा लक्ष्य सी # से डब्लूएवी फ़ाइल में डीटीएमएफ टोन का पता लगाना है। हालांकि, मैं वास्तव में यह समझने के लिए संघर्ष कर रहा हूं कि यह कैसे किया जा सकता है।एक डब्ल्यूएवी फ़ाइल से डीटीएमएफ डीकोडिंग
मैं समझता हूं कि डीटीएमएफ आवृत्तियों के संयोजन का उपयोग करता है, और एक गोर्टज़ेल एल्गोरिदम का उपयोग किया जा सकता है ... किसी भी तरह। मैं एक Goertzel कोड स्निपेट को पकड़ा है और मैं इसे में एक .WAV फ़ाइल धकेल कर की कोशिश की है (फ़ाइल है, जो एक 8KHz मोनो 16-बिट पीसीएम WAV है पढ़ने के लिए NAudio उपयोग करते हुए):
using (WaveFileReader reader = new WaveFileReader(@"dtmftest_w.wav"))
{
byte[] buffer = new byte[reader.Length];
int read = reader.Read(buffer, 0, buffer.Length);
short[] sampleBuffer = new short[read/2];
Buffer.BlockCopy(buffer, 0, sampleBuffer, 0, read/2);
Console.WriteLine(CalculateGoertzel(sampleBuffer,8000,16));
}
public static double CalculateGoertzel(short[] sample, double frequency, int samplerate)
{
double Skn, Skn1, Skn2;
Skn = Skn1 = Skn2 = 0;
for (int i = 0; i < sample.Length; i++)
{
Skn2 = Skn1;
Skn1 = Skn;
Skn = 2 * Math.Cos(2 * Math.PI * frequency/samplerate) * Skn1 - Skn2 + sample[i];
}
double WNk = Math.Exp(-2 * Math.PI * frequency/samplerate);
return 20 * Math.Log10(Math.Abs((Skn - WNk * Skn1)));
}
मुझे पता है कि मैं कर रहा हूं गलत है: मुझे लगता है कि मुझे बफर के माध्यम से पुन: प्रयास करना चाहिए, और केवल एक समय में एक छोटे हिस्से के लिए गोर्टज़ेल मूल्य की गणना करना - क्या यह सही है?
दूसरा, मैं वास्तव में समझ नहीं पा रहा हूं कि गोर्टज़ेल विधि का आउटपुट मुझे क्या बता रहा है: मुझे दोहरा मिलता है (उदाहरण: 210.985812
) लौटा, लेकिन मुझे यह पता नहीं है कि इसकी उपस्थिति और मूल्य ऑडियो फ़ाइल में डीटीएमएफ टोन।
मैंने this उत्तर में संदर्भित पुस्तकालयों सहित उत्तर के लिए हर जगह खोज की है; दुर्भाग्य से, कोड here काम नहीं करता है (जैसा कि साइट पर टिप्पणियों में उल्लेख किया गया है)। TAPIEx द्वारा प्रदान की जाने वाली एक वाणिज्यिक लाइब्रेरी है; मैंने अपनी मूल्यांकन लाइब्रेरी की कोशिश की है और यह वही है जो मुझे चाहिए - लेकिन वे ईमेल का जवाब नहीं दे रहे हैं, जो मुझे वास्तव में अपने उत्पाद को खरीदने के बारे में सावधान करता है।
मुझे बहुत सचेत है कि मुझे एक जवाब की तलाश है जब शायद मुझे सही सवाल नहीं पता है, लेकिन आखिरकार मुझे केवल एक .WAV फ़ाइल में डीटीएमएफ टन खोजने का एक तरीका है। क्या मैं सही लाइनों पर हूं, और यदि नहीं, तो क्या कोई मुझे सही दिशा में इंगित कर सकता है?
संपादित करें: आधार के रूप में @Abbondanza कोड का उपयोग करना, और (संभवतः मौलिक रूप से गलत) धारणा है कि मुझे ऑडियो फ़ाइल के छोटे वर्गों को ड्रिप-फीड करने की आवश्यकता है, अब मेरे पास यह है (बहुत मोटा, सबूत- अवधारणा केवल) कोड:
const short sampleSize = 160;
using (WaveFileReader reader = new WaveFileReader(@"\\mac\home\dtmftest.wav"))
{
byte[] buffer = new byte[reader.Length];
reader.Read(buffer, 0, buffer.Length);
int bufferPos = 0;
while (bufferPos < buffer.Length-(sampleSize*2))
{
short[] sampleBuffer = new short[sampleSize];
Buffer.BlockCopy(buffer, bufferPos, sampleBuffer, 0, sampleSize*2);
var frequencies = new[] {697.0, 770.0, 852.0, 941.0, 1209.0, 1336.0, 1477.0};
var powers = frequencies.Select(f => new
{
Frequency = f,
Power = CalculateGoertzel(sampleBuffer, f, 8000)
});
const double AdjustmentFactor = 1.05;
var adjustedMeanPower = AdjustmentFactor*powers.Average(result => result.Power);
var sortedPowers = powers.OrderByDescending(result => result.Power);
var highestPowers = sortedPowers.Take(2).ToList();
float seconds = bufferPos/(float)16000;
if (highestPowers.All(result => result.Power > adjustedMeanPower))
{
// Use highestPowers[0].Frequency and highestPowers[1].Frequency to
// classify the detected DTMF tone.
switch (Convert.ToInt32(highestPowers[0].Frequency))
{
case 1209:
switch (Convert.ToInt32(highestPowers[1].Frequency))
{
case 697:
Console.WriteLine("1 pressed at " + bufferPos + " (" + seconds + "s)");
break;
case 770:
Console.WriteLine("4 pressed at " + bufferPos + " (" + seconds + "s)");
break;
case 852:
Console.WriteLine("7 pressed at " + bufferPos + " (" + seconds + "s)");
break;
case 941:
Console.WriteLine("* pressed at " + bufferPos);
break;
}
break;
case 1336:
switch (Convert.ToInt32(highestPowers[1].Frequency))
{
case 697:
Console.WriteLine("2 pressed at " + bufferPos + " (" + seconds + "s)");
break;
case 770:
Console.WriteLine("5 pressed at " + bufferPos + " (" + seconds + "s)");
break;
case 852:
Console.WriteLine("8 pressed at " + bufferPos + " (" + seconds + "s)");
break;
case 941:
Console.WriteLine("0 pressed at " + bufferPos + " (" + seconds + "s)");
break;
}
break;
case 1477:
switch (Convert.ToInt32(highestPowers[1].Frequency))
{
case 697:
Console.WriteLine("3 pressed at " + bufferPos + " (" + seconds + "s)");
break;
case 770:
Console.WriteLine("6 pressed at " + bufferPos + " (" + seconds + "s)");
break;
case 852:
Console.WriteLine("9 pressed at " + bufferPos + " (" + seconds + "s)");
break;
case 941:
Console.WriteLine("# pressed at " + bufferPos + " (" + seconds + "s)");
break;
}
break;
}
}
else
{
Console.WriteLine("No DTMF at " + bufferPos + " (" + seconds + "s)");
}
bufferPos = bufferPos + (sampleSize*2);
}
यह ऑडैसिटी में देखी गई नमूना फ़ाइल है; मैं DTMF keypresses में जोड़ दिया है कि
pressed- और ... यह लगभग काम करता रहे थे। इसके बाद के संस्करण फ़ाइल से, मैं किसी भी DTMF लगभग ठीक है जब तक नहीं देखना चाहिए 3 सेकंड में, हालांकि, मेरी कोड रिपोर्ट:
9 pressed at 1920 (0.12s)
1 pressed at 2880 (0.18s)
* pressed at 3200
1 pressed at 5120 (0.32s)
1 pressed at 5440 (0.34s)
7 pressed at 5760 (0.36s)
7 pressed at 6080 (0.38s)
7 pressed at 6720 (0.42s)
5 pressed at 7040 (0.44s)
7 pressed at 7360 (0.46s)
7 pressed at 7680 (0.48s)
1 pressed at 8000 (0.5s)
7 pressed at 8320 (0.52s)
... जब तक यह करने के लिए हो जाता है 3 सेकंड, और फिर इसे करने के लिए बसने के लिए शुरू होता है सही उत्तर: कि 1
दबाया गया था:
7 pressed at 40000 (2.5s)
# pressed at 43840 (2.74s)
No DTMF at 44800 (2.8s)
1 pressed at 45120 (2.82s)
1 pressed at 45440 (2.84s)
1 pressed at 46080 (2.88s)
1 pressed at 46720 (2.92s)
4 pressed at 47040 (2.94s)
1 pressed at 47360 (2.96s)
1 pressed at 47680 (2.98s)
1 pressed at 48000 (3s)
1 pressed at 48960 (3.06s)
4 pressed at 49600 (3.1s)
1 pressed at 49920 (3.12s)
1 pressed at 50560 (3.16s)
1 pressed at 51520 (3.22s)
1 pressed at 52160 (3.26s)
4 pressed at 52480 (3.28s)
अगर मैं AdjustmentFactor
1.2 परे तक सामने लाना, मैं बिल्कुल भी बहुत कम पता लगाने मिलता है।
मुझे लगता है कि मैं लगभग वहां हूं, लेकिन क्या कोई यह देख सकता है कि मैं क्या खो रहा हूं?
EDIT2: उपरोक्त परीक्षण फ़ाइल here उपलब्ध है।adjustedMeanPower
उदाहरण में ऊपर 47.6660450354638
है, और शक्तियां हैं:
डीटीएमएफ टोम कम से कम 40 मिमी लंबी जगह के साथ कम से कम 40 मिमी होना चाहिए। देखें http://www.genave.com/dtmf-mark-space.htm –
http: //www.genave के अनुसार आपको जिन आवृत्तियों को पहचानने की आवश्यकता है वे 697Hz, 770Hz, 852Hz, 941Hz, 1209Hz, 1336Hz और 1477Hz हैं। com/dtmf.htm –
मैंने अपने उत्तर में एक कोड स्निपेट जोड़ा। अगर आपको आपकी समस्या पर प्रगति करने में मदद मिली तो मुझे बताएं। –