File transfer over sound card II: Phase Shift Keying

2024-05-27 02:38

本文主要是介绍File transfer over sound card II: Phase Shift Keying,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

墙外的文章,转载贴过来慢慢看,慢慢翻译。

I've played around further with the file transfer over sound card idea, and developed a more advanced method that uses a technique called Phase Shift Keying. Similar techniques are used in wireless network connections. 

I've played around further with the file transfer over sound card idea, and developed a more advanced method that uses a technique called  Phase Shift Keying . Similar techniques are used in wireless network connections.

I've played around fur­ther with the file trans­fer over sound card idea, and de­vel­oped a more ad­vanced method that uses a tech­nique called Phase Shift Key­ing .Sim­i­lar tech­niques are used in wire­less net­work con­nec­tions. 

In­stead of cod­ing data in the am­pli­tude or fre­quency of the car­rier sig­nal, phase shift key­ing (as the name in­di­cates) en­codes it in the phase. It is sig­nif­i­cantly faster, par­tially be­cause it doesn't waste as much time with si­lences, but also be­cause it's more re­liant. 




I must admit it's a good thing I wasn't drink­ing cof­fee when tin­ker­ing with this tech­nique, be­cause it's very likely I would have blown cof­fee through my nose and onto the key­board when I first saw trans­fer rates over around 200 baud, with no ran­dom gar­bling .  I'm sure it's pos­si­ble to go higher with bet­ter equip­ment than my cheaper-than-dirt head­sets that came with my we­b­cams. 

How it works 

The math­e­mat­ics of the method is as fol­low­ing, if the sig­nal is ex­pressed as 

S(t) = A 0  sin(ωt + φ) 

Then the Fourier trans­form of S would give you 

F ω (S) = A 0  e  

Nor­mally, one would sim­ply dis­card the phase fac­tor by tak­ing the norm of the fre­quency co­ef­fi­cient, but for this we're going to make use of it .  You can't just yank the phase out of the ex­pres­sion as it is though (phase is al­ways rel­a­tive to some­thing) .  But! You can com­pare this phase with the phase of the last sam­ple you got (this is called dif­fer­en­tial phase-shift key­ing, by the way) .  

So, I pro­pose the fol­low­ing scheme:

Δφ Mean­ing
0 Still the same sam­ple as last time
π / 2 Next bit is 1
π Next bit is 0
3 &pi / 2 New byte
This has sev­eral nice fea­tures .  You can jump into the sig­nal al­most any­where and at most one byte will be gar­bled .  Fur­ther­more, every­thing has an uni­form length, so bit rate doesn't de­pend on how many ones and zeros is in the byte .  

Mod­i­fy­ing the fourier code from the last blog post on sonic file trans­fers, the fol­low­ing func­tion will allow you to make use of the phase: 

double fourier1p(double x_in[], double n, int length, double* phase_r, double* phase_i) { 
double x_complex[2] = { 0, 0 }; 
int i; 

for(i = 0; i < length; i++) { 
x_complex[0] += x_in[i] * cos(M_PI * 2 * i * n / (double) length); 
x_complex[1] += x_in[i] * sin(M_PI * 2 * i * n / (double) length); 


double norm = sqrt(x_complex[0]*x_complex[0] + x_complex[1]*x_complex[1]); 
*phase_i = x_complex[1] / norm; 
*phase_r = x_complex[0] / norm; 
return norm / length; 
}
 


So how do we fig­ure out the phase dif­fer­ence ?  Let φ be the phase of the cur­rent sam­ple, and ψ be the phase of the pre­vi­ous sam­ple .  

e e -iψ  = e i(φ - ψ)  = cos(φ - ψ) + i sin(φ - ψ) 

The real term will dom­i­nate if φ - ψ ~ nπ , and the imag­i­nary term will dom­i­nate if φ - ψ ~ (n+1)π/2 and their sign will fur­ther tell you if n is odd or even .  

The de­mod­u­la­tion al­go­rithm is fairly short: 


double carrier_phase[2]; 
double carrier_strength = fourier1p(dbuffer, (float) length * carrier / (float)rate, length, &carrier_phase[0], &carrier_phase[1]); 

if(carrier_strength < threshold) continue; 

double delta_re = carrier_phase[0] * old_carrier_phase[0] + carrier_phase[1]*old_carrier_phase[1]; 
double delta_im = -carrier_phase[1]*old_carrier_phase[0] + carrier_phase[0] * old_carrier_phase[1]; 

if(delta_re * delta_re > delta_im * delta_im) { /* Phase difference is a multiple of pi */ 
if(delta_re > 0); /* No change */ 
else { 
bit_data = bit_data * 2; 

} else { 
if(delta_im > 0) { 
bit_data = bit_data * 2 + 1; 
} else { 
if(isprint(bit_data)) printf("%c", bit_data); 
else printf("<%.2x>", bit_data); 
bit_data = 0; 


old_carrier_phase[0] = carrier_phase[0]; 
old_carrier_phase[1] = carrier_phase[1]; 




For sev­eral rea­sons, it's a good idea to use a pretty high car­rier fre­quency for this method .  At some point, your speaker or mi­cro­phone will not be able to process the in­for­ma­tion, so you'll want to stay under that, but a high fre­quency will re­sult in less per­tur­ba­tion of the sig­nal since fairly few ob­jects have eigen­fre­quen­cies in the 5 kHz range or higher, and even os­cil­la­tion at har­monic fre­quen­cies drops off pretty sig­nif­i­cantly at such fre­quen­cies .  

Sources  

The com­plete source code for the pro­gram: 

gen­er­ate_psk.
an­a­lyze_psk.c 

You may have grabbed these the last time, but they are slightly al­tered now, so get them again: 

fourier.
fourier.c 

You also need the play­back and record pro­grams I posted in the pre­vi­ous post . They haven't changed though. 

play­back.
record.c 


Using  

Same old warn­ing: Never try these pro­grams with your head­phones on .  THEY MAKE LOUD NOISES! It is pos­si­ble to con­fig­ure these pro­grams to make noises way louder than you ever imag­ined your head­phones could make .  You can dam­age your hear­ing when play­ing with audio pro­gram­ming .   Tin­ni­tus  isn't fun .  

To trans­fer a file (let's trans­fer /etc/fstab again), put the mi­cro­phone next to the speaker, pre-type the fol­low­ing on the trans­mit­ting com­puter (with­out run­ning it): 

>./generate_psk -r 48000 -c 8000 -b 100 /etc/fstab | ./playback -r 48000  

Type the fol­low­ing on the re­ceiv­ing com­puter: 

>./record -r 48000 > mydata  

Press enter on the trans­mit­ting com­puter .  Be quiet (this should be fairly quick. Maybe 30 sec­onds ? ) When the high pitched noise stops, press Ctrl+C on the re­ceiv­ing com­puter's ter­mi­nal .  

Run­ning 
./analyze_psk -r 48000 -c 8000 -b 100 mydata  
on the re­ceiv­ing com­puter should re­treive the mes­sage .  

The pa­ra­me­ters are 
-r : Sam­ple rate -- car­rier fre­quency and sig­nal qual­ity 
-c : Car­rier fre­quency -- lim­its baud rate and sig­nal qual­ity 
-b : Baud rate -- de­ter­mines how fast the trans­fer is 

What works and doesn't with the sam­pling rates and fre­quen­cies is a bit tricky . It all boils down to  Nyquist-Shan­non  .  That the­o­rem is all in­no­cent look­ing, until you make it mad .  Then it turns green and grows three times it's size and goes on a fu­ri­ous ram­page through your hopes and dreams. 

Any­ways, have fun ex­per­i­ment­ing with this tech­nique .  

2011 up­date: Moved the sources to a  github repo.   

This has several nice features. You can jump into the signal almost anywhere and at most one byte will be garbled. Furthermore, everything has an uniform length, so bit rate doesn't depend on how many ones and zeros is in the byte. 

Modifying the fourier code from the last blog post on sonic file transfers, the following function will allow you to make use of the phase:

这篇关于File transfer over sound card II: Phase Shift Keying的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1006294

相关文章

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

从0到1,AI我来了- (7)AI应用-ComfyUI-II(进阶)

上篇comfyUI 入门 ,了解了TA是个啥,这篇,我们通过ComfyUI 及其相关Lora 模型,生成一些更惊艳的图片。这篇主要了解这些内容:         1、哪里获取模型?         2、实践如何画一个美女?         3、附录:               1)相关SD(稳定扩散模型的组成部分)               2)模型放置目录(重要)

学习记录:js算法(二十八):删除排序链表中的重复元素、删除排序链表中的重复元素II

文章目录 删除排序链表中的重复元素我的思路解法一:循环解法二:递归 网上思路 删除排序链表中的重复元素 II我的思路网上思路 总结 删除排序链表中的重复元素 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 图一 图二 示例 1:(图一)输入:head = [1,1,2]输出:[1,2]示例 2:(图

Open a folder or workspace... (File -> Open Folder)

问题:vscode Open with Live Server 时 显示Open a folder or workspace... (File -> Open Folder)报错 解决:不可以单独打开文件1.html ; 需要在文件夹里打开 像这样

android java.io.IOException: open failed: ENOENT (No such file or directory)-api23+权限受权

问题描述 在安卓上,清单明明已经受权了读写文件权限,但偏偏就是创建不了目录和文件 调用mkdirs()总是返回false. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_E

LeetCode:3177. 求出最长好子序列 II 哈希表+动态规划实现n*k时间复杂度

3177. 求出最长好子序列 II 题目链接 题目描述 给你一个整数数组 nums 和一个非负整数k 。如果一个整数序列 seq 满足在下标范围 [0, seq.length - 2] 中 最多只有 k 个下标i满足 seq[i] != seq[i + 1] ,那么我们称这个整数序列为好序列。请你返回 nums中好子序列的最长长度。 实例1: 输入:nums = [1,2,1,1,3],

代码训练营 Day26 | 47.排序II | 51. N-皇后 |

47.排序II 1.跟46题一样只不过加一个树层去重 class Solution(object):def backtracking(self,nums,path,result,used):# recursion stopif len(path) == len(nums):# collect our setresult.append(path[:])return for i in range(

bash: arm-linux-gcc: No such file or directory

ubuntu出故障重装了系统,一直用着的gcc使用不了,提示bash: arm-linux-gcc: No such file or directorywhich找到的命令所在的目录 在google上翻了一阵发现此类问题的帖子不多,后来在Freescale的的LTIB环境配置文档中发现有这么一段:     # Packages required for 64-bit Ubuntu

编译linux内核出现 arm-eabi-gcc: error: : No such file or directory

external/e2fsprogs/lib/ext2fs/tdb.c:673:29: warning: comparison between : In function 'max2165_set_params': -。。。。。。。。。。。。。。。。。。 。。。。。。。。。。。。。 。。。。。。。。 host asm: libdvm <= dalvik/vm/mterp/out/Inte

代码随想录训练营day37|52. 携带研究材料,518.零钱兑换II,377. 组合总和 Ⅳ,70. 爬楼梯

52. 携带研究材料 这是一个完全背包问题,就是每个物品可以无限放。 在一维滚动数组的时候规定了遍历顺序是要从后往前的,就是因为不能多次放物体。 所以这里能多次放物体只需要把遍历顺序改改就好了 # include<iostream># include<vector>using namespace std;int main(){int n,m;cin>>n>>m;std::vector<i