吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|www.40881110.com

 找回密码
 注册[Register]

QQ登录

只需一步£¬快速开始

查看: 6261|回复: 78
上一主题 下一主题

[原创源码] 使用电脑声卡来实现2FSK数据调制解调传输

  [复制链接]
跳转到指定楼层
楼主
lizhirui 发表于 2019-4-9 08:43 回帖奖励
本帖最后由 lizhirui 于 2019-4-19 11:36 编辑



此程序在物理层上使用10KHz的频率表示逻辑¡°0?#20445;?#20351;用15KHz的频率表示逻辑¡°1¡±
在物理层之上£¨假设就叫传输层吧£©用一个单位时间的0和一个单位时间的1表示逻辑¡°0?#20445;?#29992;一个单位时间的0和两个单位时间的1表示逻辑¡°1?#20445;?#24182;且每个?#32440;?#30340;结尾都有一个偶校验位以及一个保?#32440;?#38271;时间的0用于分隔?#32440;?br /> 在传输层之上£¨假设就叫网络层吧£©£¬以包为单位传输数据£¬0x55表示包?#32602;?xAA表示包尾£¬无校验

程序解调原理是£º
首先利用10KHz和15KHz带通滤波器将声卡?#37038;?#26469;的波形进?#26032;?#27874;£¬然后将两通道分别通过两个包络检波器£¬之后在门限噪声过滤后进行比较£¬谁幅度大判决结果就是谁
滤波器使用MATLAB生成的£¬?#31561;?#19979;所示£º
[C#] 纯文本查看 复制代码
        private const int BandPass_Size = 45;

        private static double[] BandPass_10KHz = new double[]{
          0.0009781904976227,2.310687083045e-05,-0.001850921386016,-0.0009604556387189,
           0.002732177361363, 0.002454026683306,-0.003530807893481,-0.005033359378625,
           0.003268338256639, 0.008046002294271,-0.001785884965235, -0.01118839681511,
          -0.001425109899399,  0.01337602169719, 0.005932600339844, -0.01398968593694,
           -0.01124059666706,  0.01232758211354,    0.016159778255,-0.008524876132051,
           -0.01973020933926, 0.003023046445069,  0.02098489087997, 0.003023046445069,
           -0.01973020933926,-0.008524876132051,    0.016159778255,  0.01232758211354,
           -0.01124059666706, -0.01398968593694, 0.005932600339844,  0.01337602169719,
          -0.001425109899399, -0.01118839681511,-0.001785884965235, 0.008046002294271,
           0.003268338256639,-0.005033359378625,-0.003530807893481, 0.002454026683306,
           0.002732177361363,-0.0009604556387189,-0.001850921386016,2.310687083045e-05,
          0.0009781904976227
        };

        private static double[] BandPass_15KHz = new double[]{
          -0.0009981746791559, 0.000759180810415,0.0006404064214932,-0.002457709613472,
            0.00238467384023,0.0007556946095888,-0.004687333695163, 0.004906581539168,
          0.0005502824808439,-0.007567247883353,  0.00864646206089,-0.0006606208202895,
           -0.01018615121518,  0.01288307335994,-0.002755953433256, -0.01205731207217,
            0.01703290275592,-0.005710913930339, -0.01241906755974,  0.01996890238488,
          -0.008755521713043, -0.01126587989407,  0.02109366603246, -0.01126587989407,
          -0.008755521713043,  0.01996890238488, -0.01241906755974,-0.005710913930339,
            0.01703290275592, -0.01205731207217,-0.002755953433256,  0.01288307335994,
           -0.01018615121518,-0.0006606208202895,  0.00864646206089,-0.007567247883353,
          0.0005502824808439, 0.004906581539168,-0.004687333695163,0.0007556946095888,
            0.00238467384023,-0.002457709613472,0.0006404064214932, 0.000759180810415,
          -0.0009981746791559
        };


滤波程序如下£¨原理是将信号与滤波器进行卷积£¬卷积使用了一个滚动缓冲区来解决£©£º
[C#] 纯文本查看 复制代码
         private int[] Filter_10KHz(int[] Data)
        {
            double[] dData = new double[Data.Length];
            int i,j,k;
            
            for(i = 0;i < dData.Length;i++)
            {
                dData[i] = 0;
                k = BandPass_Size - 1;

                for(j = i + 1;j < BandPass_Size;j++)
                {
                    dData[i] += BandPassBuf_10KHz[j] * BandPass_10KHz[k--];
                }

                for(j = Math.Max(0,i - BandPass_Size + 1);j <= i;j++)
                {
                    dData[i] += ((double)Data[j]) * BandPass_10KHz[k--];
                }

                if(k != -1)
                {
                    throw new Exception();
                }
            }

            for(i = Data.Length - 1,j = BandPass_Size - 1;j >= 0;i--,j--)
            {
                BandPassBuf_10KHz[j] = (double)Data[i];
            }

            int[] r = new int[Data.Length];

            for(i = 0;i < Data.Length;i++)
            {
                r[i] = (int)dData[i];
            }
            
            return r;
        }

        private int[] Filter_15KHz(int[] Data)
        {
            double[] dData = new double[Data.Length];
            int i,j,k;
            
            for(i = 0;i < dData.Length;i++)
            {
                dData[i] = 0;
                k = BandPass_Size - 1;

                for(j = i + 1;j < BandPass_Size;j++)
                {
                    dData[i] += BandPassBuf_15KHz[j] * BandPass_15KHz[k--];
                }

                for(j = Math.Max(0,i - BandPass_Size + 1);j <= i;j++)
                {
                    dData[i] += ((double)Data[j]) * BandPass_15KHz[k--];
                }

                if(k != -1)
                {
                    throw new Exception();
                }
            }

            for(i = Data.Length - 1,j = BandPass_Size - 1;j >= 0;i--,j--)
            {
                BandPassBuf_15KHz[j] = (double)Data[i];
            }

            int[] r = new int[Data.Length];

            for(i = 0;i < Data.Length;i++)
            {
                r[i] = (int)dData[i];
            }
            
            return r;
        }


包络检波器代码如下£¨同样采用了滚动缓冲区£©£º
[C#] 纯文本查看 复制代码
        private double env_3(double x,double rct)
        {
            if(rct == 0.0)
            {
                old_y = 0.0;
            }
            else
            {
                x = Math.Abs(x);

                if(x > old_y)
                {
                    old_y = x;
                }
                else
                {
                    old_y *= rct / (rct + 1);
                }
            }

            return old_y;
        }

        private void env_4(double[] x,out double[] y,int N,double rct)
        {
            double xx = 0.0;
            int i;

            old_y = 0.0;

            y = new double[N];

            y[0] = Math.Abs(x[0]);

            for(i = 1; i < N; i++)
            {
                xx = Math.Abs(x[i]);

                if(xx > y[i - 1])
                {
                    y[i] = xx;
                }
                else
                {
                    y[i] = y[i - 1] * rct / (rct + 1);
                }
            }
        }

        private int[] Env_10KHz(int[] Data)
        {
            double[] dData = null;
            double[] dr;
            int i,j,k;

            if(Env10KHzInit)
            {
                dData = new double[Data.Length];

                for(i = 0;i < Data.Length;i++)
                {
                    dData[i] = Data[i];
                }

                Env10KHzInit = false;
            }
            else
            {
                dData = new double[Data.Length << 1];

                for(i = 0;i < Data.Length;i++)
                {
                    dData[i] = Env10KHzBuf[i];
                }

                for(i = 0;i < Data.Length;i++)
                {
                    dData[Data.Length + i] = Data[i];
                }
            }

            env_4(dData,out dr,dData.Length,rc);

            int[] r = new int[Data.Length];

            if(Data.Length == dr.Length)
            {
                for(i = 0;i < dr.Length;i++)
                {
                    r[i] = (int)dr[i];
                }
            }
            else
            {
                for(i = Data.Length;i < dr.Length;i++)
                {
                    r[i - Data.Length] = (int)dr[i];
                }
            }

            Env10KHzBuf = Data.ToArray();
            
            return r;
        }

        private int[] Env_15KHz(int[] Data)
        {
            double[] dData = null;
            double[] dr;
            int i,j,k;

            if(Env15KHzInit)
            {
                dData = new double[Data.Length];

                for(i = 0;i < Data.Length;i++)
                {
                    dData[i] = Data[i];
                }

                Env15KHzInit = false;
            }
            else
            {
                dData = new double[Data.Length << 1];

                for(i = 0;i < Data.Length;i++)
                {
                    dData[i] = Env15KHzBuf[i];
                }

                for(i = 0;i < Data.Length;i++)
                {
                    dData[Data.Length + i] = Data[i];
                }
            }

            env_4(dData,out dr,dData.Length,rc);

            int[] r = new int[Data.Length];

            if(Data.Length == dr.Length)
            {
                for(i = 0;i < dr.Length;i++)
                {
                    r[i] = (int)dr[i];
                }
            }
            else
            {
                for(i = Data.Length;i < dr.Length;i++)
                {
                    r[i - Data.Length] = (int)dr[i];
                }
            }

            Env15KHzBuf = Data.ToArray();
            
            return r;
        }


传输层数据?#37038;?#31243;序£º
[C#] 纯文本查看 复制代码
       private void DataArrived_Audio(int[] audioData)
        {
            var r10 = Filter_10KHz(audioData);
            var re10 = Env_10KHz(r10);
            var r15 = Filter_15KHz(audioData);
            var re15 = Env_15KHz(r15);
            var v = 0;

            for(int i = 0;i < re10.Length;i++)
            {
                statusChart1.Value = v = (((re10[i] < CurTValue) && (re15[i] < CurTValue)) ? 0 : (re10[i] > re15[i] ? 10000 : 30000));
                statusChart2.Value = re10[i];
                statusChart3.Value = re15[i];
                
                if(v == 30000)
                {
                    if(LastOne)
                    {
                        OneCnt++;
                    }
                    else
                    {
                        LastOne = true;
                        OneCnt = 1;
                    }
                }
                else if(v == 0)
                {
                    //无效
                    ZeroCnt = 0;
                    OneCnt = 0;
                    LastOne = false;
                    CurBit = 0;
                    CurValue = 0;
                }
                else
                {
                    if(LastOne)
                    {
                        //一个bit?#37038;?#23436;成

                        if((ZeroCnt >= LowValue) && (OneCnt >= LowValue))
                        {
                            if(OneCnt > CenterValue)
                            {
                                //判定为1
                                CurValue |= (1 << CurBit);
                                CurBit++;
                            }
                            else
                            {
                                //判定为0
                                CurBit++;
                            }

                            if(CurBit >= 9)
                            {
                                var check = 0;

                                for(int j = 0;j < 8;j++)
                                {
                                    check ^= (CurValue >> j) & 0x01;
                                }

                                if(check == (CurValue >> 8))
                                {
                                    RevQ.Enqueue((byte)(CurValue & 0xFF));   
                                }
                                
                                ZeroCnt = 0;
                                CurBit = 0;
                                CurValue = 0;
                            }
                        }

                        LastOne = false;
                        ZeroCnt = 1;
                    }
                    else
                    {
                        ZeroCnt++;
                    }
                }
            }

            
        }


传输层数据发送函数£º
[C#] 纯文本查看 复制代码
        private void DataSendThread()
        {
            while(true)
            {
                var check = 0;
                var list = new List<byte>();

                if(SendQ.Count > 0)
                {
                    var x = SendQ.Dequeue();

                    for(int i = 0;i < 8;i++)
                    {
                        if((x & (1 << i)) == 0)
                        {
                            check ^= 0;
                            /*m_Fifo.Write(Signal10KHz,0,Signal10KHz.Length / 2);
                            m_Fifo.Write(Signal15KHz,0,Signal15KHz.Length / 2);*/
                            AddToList(list,Signal10KHz,Signal10KHz.Length / ZeroDiv);
                            AddToList(list,Signal15KHz,Signal15KHz.Length / ZeroDiv);
                        }
                        else
                        {
                            check ^= 1;
                            /*m_Fifo.Write(Signal10KHz,0,Signal10KHz.Length / 2);
                            m_Fifo.Write(Signal15KHz,0,Signal15KHz.Length);*/
                            AddToList(list,Signal10KHz,Signal10KHz.Length / ZeroDiv);
                            AddToList(list,Signal15KHz,Signal15KHz.Length / OneDiv);
                        }
                    }

                    if(check == 0)
                    {
                        AddToList(list,Signal10KHz,Signal10KHz.Length / ZeroDiv);
                        AddToList(list,Signal15KHz,Signal15KHz.Length / ZeroDiv);
                    }
                    else
                    {
                        AddToList(list,Signal10KHz,Signal10KHz.Length / ZeroDiv);
                        AddToList(list,Signal15KHz,Signal15KHz.Length / OneDiv);
                    }

                    AddToList(list,Signal10KHz,Signal10KHz.Length / 2);
                }

                m_Fifo.Write(list.ToArray(),0,list.Count);
            }
        }


该代码抗干扰能力很强£¬大声说?#21543;?#33267;喊叫都不会影响到声音传输£¬如果你那里一直?#37038;?#19981;到数据£¬可能是你的扬声器发不出10KHz和15KHz的声音或者声音太小£¬这时可以采用音频线直接连接声卡的输入端和输出端
该程序在Windows 7 x64旗舰版下测试通过£¬由于受限于Windows的多任务调度机制£¬程序的实时性很?#35757;?#21040;保证£¬因此传输速度只能达到4bit/s即0.5Byte/s或者说2s/Byte
发送速率可以由¡°speed¡±变量控制£¬该变量位于Form1类成员中

已经编译好的EXE需要在至少.net Framework 4.7.1的环境下启动£¨版本过低可能会报异常£©£¬并且可能需要在插入麦克风?#33073;?#22768;器之后才能成功启动£¬否则对于某些声卡可能会报异常
代码基于VS2017开发
窗口左下角的发送值只能填0-255之间的一个数£¬否则会报异常£¬那里是单?#32440;?#30340;发送测试
右上角那个文?#31350;?#21487;以输入?#25105;?#25991;本£¬点击发送之后等待?#37038;?#21363;可£¬那里是以包为单位发送的£¬因此若发送x个?#22336;û£?#23454;际发送的是(f(x)+2)*9个bit£¨包头一个?#32440;Ú£?#21253;尾一个?#32440;Ú£¬UTF-8编码表示编码的长度不定£¬所以x?#22336;?#23454;?#35782;?#24212;的?#22336;?#25968;用f(x)表示£¬对于汉字而言£¬是三个?#32440;?#34920;示一个?#22336;û£©£?br /> 下载链接£º
音频数据传输GUI.rar (476.74 KB, 下载次数: 116)

免费评分

参与人数 30吾爱币 +34 热心值 +28 收起 理由
oxxo119 + 1 + 1 谢谢@Thanks£¡感觉牛逼了
jixun66 + 3 + 1 用心讨论£¬?#19981;?#25552;升£¡
xxxlsy + 1 + 1 热心回复£¡
小Q主人 + 1 + 1 谢谢@Thanks£¡
kerwining + 1 + 1 用心讨论£¬?#19981;?#25552;升£¡
tanghengvip + 1 + 1 惊£¡电脑之间?#20302;?#29992;高频率进行沟通£¡
chixinfeng + 1 + 1 热心回复£¡
wohose + 1 + 1 我很赞同£¡
guoruihotel + 1 + 1 谢谢@Thanks£¡
名字以后会后悔 + 1 + 1 谢谢@Thanks£¡
安倚静轩 + 1 + 1 用心讨论£¬?#19981;?#25552;升£¡
wangbingbing + 1 + 1 仰视大?#26657;?#25265;大腿
yangsd973 + 1 + 1 热心回复£¡
daniel7785 + 1 + 1 用心讨论£¬?#19981;?#25552;升£¡
如影随风 + 1 + 1 我很赞同£¡
hwolf1 + 1 + 1 方式很新?#20445;?/td>
ayoma + 1 + 1 欢迎分析讨论交流£¬吾爱破解论坛有你更精彩£¡
snowhalation + 1 用心讨论£¬?#19981;?#25552;升£¡
HDxian + 1 + 1 用心讨论£¬?#19981;?#25552;升£¡
qiangcl + 1 热心回复£¡
qq3bot + 1 + 1 谢谢@Thanks£¡
fanssong + 1 + 1 表示一脸懵逼
moodykeke + 1 + 1 谢谢@Thanks£¡
qsvren + 1 + 1 青果摄像头就是使用的音频传输的数据来连接?#29992;Üwifi
wingingangel + 1 + 1 用心讨论£¬?#19981;?#25552;升£¡
whc2001 + 2 + 1 卧槽牛逼, 之前那种音频口的刷卡器似乎就是用这种协议通讯的, 一直没研究透
cunzher + 1 + 1 牛逼
苏紫方璇 + 1 ?#34892;?#21457;布原创作?#32602;?#21566;爱破解论坛因你更精彩£¡
Gentlewang + 3 + 1 ?#34892;?#21457;布原创作?#32602;?#21566;爱破解论坛因你更精彩£¡
zzzain46 + 1 + 1 ?#34892;?#21457;布原创作?#32602;?#21566;爱破解论坛因你更精彩£¡

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用¡¾论坛搜索¡¿功能£¬那里可能会有你要找的答案或者已经有人发布过相同内容了£¬请勿重复发帖¡£

推荐
 楼主| lizhirui 发表于 2019-4-13 13:30 |楼主
ayoma 发表于 2019-4-13 01:38
这个其实我们HAM玩的无线电 JT65 PSK JT9... 和现在流行的FT8软件wsjtx和jtdx是一样?#33041;?#29702;¡£希望能有?#24418;?#20256; ...

支?#32844;?我?#24425;ÇHAM 23333
推荐
 楼主| lizhirui 发表于 2019-4-9 12:15 |楼主
zwo 发表于 2019-4-9 09:40
如果为了提高传速率£¬改到4FSK, 8FSK£¬是不是误码率会很大£¿

如果频?#22987;?#38548;比较大的话£¬并且你的滤波器够窄的话 问题也不大
其实这玩意如果不用PC改用嵌入式处理器运?#26032;?#26426;程序的话£¬传输速度上到几KB/s是一点压力没有
如果提高两个传输频?#23454;?#35805;£¬传输上到几MB/s 几十MB/s的也没啥大问题
沙发
chensure 发表于 2019-4-9 09:16
之前听说过£¬黑一台无网络的计算器£¬就用这种方式£¿
3#
goldli 发表于 2019-4-9 09:21
一运行就报错¡£win10

点评

已经编译好的EXE需要在至少.net Framework 4.7.1的环境下启动£¨版本过低可能会报异常£©£¬并且可能需要在插入麦克风?#33073;?#22768;器之后才能成功启动£¬否则对于某些声卡可能会报异常  详情 回复 发表于 2019-4-9 09:23
4#
 楼主| lizhirui 发表于 2019-4-9 09:23 |楼主
goldli 发表于 2019-4-9 09:21
一运行就报错¡£win10

已经编译好的EXE需要在至少.net Framework 4.7.1的环境下启动£¨版本过低可能会报异常£©£¬并且可能需要在插入麦克风?#33073;?#22768;器之后才能成功启动£¬否则对于某些声卡可能会报异常
5#
zwo 发表于 2019-4-9 09:40
如果为了提高传速率£¬改到4FSK, 8FSK£¬是不是误码率会很大£¿

点评

?#22771;?FSK在PC上现有速率下的测试显示 ?#22771;?#20256;输还没出过错£¬所以不知道误码率是多少  详情 回复 发表于 2019-4-9 12:15
如果频?#22987;?#38548;比较大的话£¬并且你的滤波器够窄的话 问题也不大 其实这玩意如果不用PC改用嵌入式处理器运?#26032;?#26426;程序的话£¬传输速度上到几KB/s是一点压力没有 如果提高两个传输频?#23454;?#35805;£¬传输上到几MB/s 几十MB/s的也  详情 回复 发表于 2019-4-9 12:15
6#
chengan1998 发表于 2019-4-9 09:58
大佬我来了
7#
苏紫方璇 发表于 2019-4-9 10:59
大佬好厉害£¬长知识了
9#
 楼主| lizhirui 发表于 2019-4-9 12:15 |楼主
zwo 发表于 2019-4-9 09:40
如果为了提高传速率£¬改到4FSK, 8FSK£¬是不是误码率会很大£¿

?#22771;?FSK在PC上现有速率下的测试显示
?#22771;?#20256;输还没出过错£¬所以不知道误码率是多少
10#
goldli 发表于 2019-4-9 14:18
lizhirui 发表于 2019-4-9 09:23
已经编译好的EXE需要在至少.net Framework 4.7.1的环境下启动£¨版本过低可能会报异常£©£¬并且可能需要在 ...

我这有4.7.2了¡£ 没有麦克风
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告£º禁止回复与主题无关内容£¬违者重罚£¡

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2019-5-22 10:44

Powered by Discuz!

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表
Çò̽ÍøÀºÇòÖ¸Êý