プログラムでDTMF音声を番号から生成しスピーカーで再生したがIP電話をダイアルできない
解決したいこと
会社のIP電話ACD08-0359001をPCの画面を見ながらダイアルを押すのが面倒であったため、
こちらをC#に書き直したコードにてDTMF信号生成し通話しようとした。
しかし、正しい手順であるはずにもかかわらず通話開始ができない。
コールは下記の手順で行った。
- 受話器を本体から離す
- PCのスピーカーを受話器のマイクに直接押し当てる
- 番号を入力シエンターを押す
- DTMF信号を流す
- (スピーカーから音がループバックして聞こえる。妥当な音っぽいのが聞こえる。)
他の既知のプログラムを調査したが、適当なものが見つからなかったため自作コードを使用している。
既存のがあれば紹介いただければと思う。
探したが無かった。ただし根気が足りないだけの可能性は十二分にある。
発生している問題・エラー
通話開始ができない。
ソフト的な間違いはなさそうに見えるが、
物理側の手順が間違っている可能性がある。
該当するソースコード
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NAudio.Wave; // NAudioライブラリを使用して音声信号を扱う
using System.Text.Json;
using TONE = System.Collections.Generic.Dictionary<string, (int low, int high)>;
namespace DTMFSignalGenerator {
class Program {
// 設定を変更するには設定ファイルから読み込む
static int SAMPLING_RATE;
static double SIGNAL_DURATION;
static double PAUSE_DURATION;
// ダイヤル番号の周波数テーブル
static readonly TONE TONE_TABLE = new TONE(){
{ "1", (697, 1209) }, { "2", (697, 1336) }, { "3", (697, 1477) },
{ "4", (770, 1209) }, { "5", (770, 1336) }, { "6", (770, 1477) },
{ "7", (852, 1209) }, { "8", (852, 1336) }, { "9", (852, 1477) },
{ "*", (941, 1209) }, { "0", (941, 1336) }, { "#", (941, 1477) }
};
static void Main(string[] args) {
LoadSettings();
if (args.Length > 0) {
ProcessDial(args[0]);
}
else {
while (true) {
Console.Write("電話番号入力: ");
string dialNumber = Console.ReadLine();
ProcessDial(dialNumber);
}
}
}
static void ProcessDial(string dialNumber) {
// 「+」を「010-」に置換
if (dialNumber.Contains("+")) {
dialNumber = dialNumber.Replace("+", "010-");
}
dialNumber = "0" + dialNumber;
// DTMF信号の生成
var data = GenerateDTMFWave(dialNumber);
// 信号の再生
PlayAudio(data);
}
static void LoadSettings() {
try {
using (var stream = File.OpenRead("settings.json")) {
Settings settings = JsonSerializer.Deserialize<Settings>(new StreamReader(stream).ReadToEnd());
SAMPLING_RATE = settings.SamplingRate;
SIGNAL_DURATION = settings.SignalDuration;
PAUSE_DURATION = settings.PauseDuration;
}
}
catch (Exception ex) {
Console.WriteLine($"設定ファイルの読み込みに失敗しました: {ex.Message}");
SAMPLING_RATE = 48000;
SIGNAL_DURATION = 0.1;
PAUSE_DURATION = 0.1;
}
}
static float[] GenerateDTMFWave(string numbers) {
Console.WriteLine(numbers);
var data = new List<float>();
var t = Enumerable.Range(0, (int)(SAMPLING_RATE * SIGNAL_DURATION)).Select(i => i / (double)SAMPLING_RATE).ToArray();
var u = Enumerable.Range(0, (int)(SAMPLING_RATE * PAUSE_DURATION)).Select(i => 0f).ToArray();
foreach (char n in numbers) {
if (TONE_TABLE.ContainsKey(n.ToString())) {
var (lowFreq, highFreq) = TONE_TABLE[n.ToString()];
var lowTone = t.Select(time => (float)Math.Sin(2 * Math.PI * lowFreq * time)).ToArray();
var highTone = t.Select(time => (float)Math.Sin(2 * Math.PI * highFreq * time)).ToArray();
var combinedTone = lowTone.Zip(highTone, (low, high) => low + high).ToArray();
data.AddRange(combinedTone);
data.AddRange(u);
}
}
return data.ToArray();
}
static void PlayAudio(float[] data) {
using (var waveOut = new WaveOutEvent()) {
var waveProvider = new BufferedWaveProvider(new WaveFormat(SAMPLING_RATE, 1));
waveProvider.AddSamples(data.SelectMany(BitConverter.GetBytes).ToArray(), 0, data.Length * sizeof(float));
waveOut.Init(waveProvider);
waveOut.Play();
while (waveOut.PlaybackState == PlaybackState.Playing && waveProvider.BufferedBytes > 0) {
System.Threading.Thread.Sleep(100);
}
}
}
class Settings {
public int SamplingRate { get; set; }
public double SignalDuration { get; set; }
public double PauseDuration { get; set; }
}
}
}
追記
なんか音声が元コードに比べキーが低くなっていたような…??
0