- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
【这不是重复的。类似的问题是关于人们可以控制源数据的场景。我没有。】
在日本有一种叫做“紧急警报广播系统”的东西。激活时看起来像这样:http://www.youtube.com/watch?v=9hjlYvp9Pxs
在上面的视频中,在 2:37 左右,发送了一个 FSK 调制信号。我想解析这个信号;即给定一个包含信号的 WAV 文件,我想以一个包含 0 和 1 的 StringBuilder 结束,以便稍后处理它们。我有二进制数据和所有规范,但问题是我对音频编程一无所知。 :(
这只是一个爱好项目,但我迷上了。电视和 radio 制造商可以接收到这个信号并让他们的设备对其使用react,所以这不会那么难,对吧? :(
关于信号的事实:
到目前为止我做了什么:
我遇到的问题:
我的问题:
读取样本的代码是(简化):
StringBuilder ews_bits = new StringBuilder();
double[] samples = new double[(int)(samplesPerMs * 16.625D)];
int index = 0, readTo = /* current offset + RIFF subChunk2Size */;
BinaryReader br = /* at start of PCM data */;
while (br.BaseStream.Position < readTo)
{
switch (bitsPerSample / 8)
{
case 1: // 8bit
samples[index++] = ((double)br.ReadByte() - 127.5D) / 256D;
break;
case 2: // 16bit
samples[index++] = (double)br.ReadInt16() / 32768D;
break;
}
if (index != samples.Length)
continue;
/****** The sample buffer is full and we must process it. ******/
if (AudioProcessor.IsSilence(ref samples))
{
silence_count++;
if (state == ParserState.Decoding && silence_count > 150)
{
// End of EWS broadcast reached.
EwsSignalParser.Parse(ews_bits.ToString());
/* ... reset state; go back looking for silence... */
}
goto Done;
}
/****** The signal was not silence. ******/
if (silence_count > 120 && state == ParserState.SearchingSilence)
state = ParserState.Decoding;
if (state == ParserState.Decoding)
{
AudioProcessor.Decode(ref samples, sampleRate, ref ews_bits);
bool continue_decoding = /* check first 20 bits for signature */;
if (continue_decoding) goto Done;
// If we get here, we were decoding a junk signal.
state = ParserState.SearchingSilence;
}
/* Not enough silence yet */
silence_count = 0;
Done:
index = 0;
}
音频处理器只是一个类:
public static void Decode(ref double[] samples, int sampleRate, ref StringBuilder bitHolder)
{
double freq_640 = GoertzelMagnitude(ref samples, 640, sampleRate);
double freq_1024 = GoertzelMagnitude(ref samples, 1024, sampleRate);
if (freq_640 > freq_1024)
bitHolder.Append("0");
else
bitHolder.Append("1");
}
public static bool IsSilence(ref double[] samples)
{
// power_RMS = sqrt(sum(x^2) / N)
double sum = 0;
for (int i = 0; i < samples.Length; i++)
sum += samples[i] * samples[i];
double power_RMS = Math.Sqrt(sum / samples.Length);
return power_RMS < 0.01;
}
/// <remarks>http://www.embedded.com/design/embedded/4024443/The-Goertzel-Algorithm</remarks>
private static double GoertzelMagnitude(ref double[] samples, double targetFrequency, int sampleRate)
{
double n = samples.Length;
int k = (int)(0.5D + ((double)n * targetFrequency) / (double)sampleRate);
double w = (2.0D * Math.PI / n) * k;
double cosine = Math.Cos(w);
double sine = Math.Sin(w);
double coeff = 2.0D * cosine;
double q0 = 0, q1 = 0, q2 = 0;
for (int i = 0; i < samples.Length; i++)
{
double sample = samples[i];
q0 = coeff * q1 - q2 + sample;
q2 = q1;
q1 = q0;
}
double magnitude = Math.Sqrt(q1 * q1 + q2 * q2 - q1 * q2 * coeff);
return magnitude;
}
感谢阅读。我希望你能帮助我。
最佳答案
这就是我的做法(高级描述)
关于c# - FSK 解调 - 解析日本 EWS 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20418630/
我有一个二进制数据流,想将其转换为原始波形声音数据,然后将其发送到扬声器。 这就是老式调制解调器所做的,以便通过电话线传输二进制数据(产生典型的现代声音)。它被称为调制。 然后我需要一个反向过程 -
我正在使用此功能在 Android 中调制我自己的 AFSK 信号 public static double[] MyFSK(char bit) //bit 1 or 0 { double[]
我对 GNU Radio 和 SDR 世界还很陌生。我目前正在尝试对来 self 的 Logitech 无线键盘的信号进行逆向工程。除了我从电气工程教育中获得的知识外,我还使用了各种指南来帮助我完成这
【这不是重复的。类似的问题是关于人们可以控制源数据的场景。我没有。】 在日本有一种叫做“紧急警报广播系统”的东西。激活时看起来像这样:http://www.youtube.com/watch?v=9h
我正在尝试使用 GNU Radio Companion 解调信号。信号为 FSK(频移键控),标记频率和空间频率分别为 1200 和 2200 Hz。 信号文本数据中的数据由名为GeoStamp Au
我目前正在创建一个卫星地面站, future 几个月将用于控制我们的立方体卫星。使用的调制方案是 GFSK,波特率为 9600。在尝试通过直接连接流程图中的 tx 和 rx block 与卫星通信之前
我是一名优秀的程序员,十分优秀!