File transfer over sound card

2024-05-27 02:38
文章标签 file card transfer sound

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

转载墙外的文章,慢慢翻译,慢慢看

Be­fore I even start, a word of 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. 

This will be you if you don't take my warn­ing se­ri­ously: 



Back­ground and prob­lem 

I have an old lap­top lay­ing about .  A while back, I was in a bit of trou­ble get­ting it to work .  It's so old that sev­eral parts of it has shut down .  The USB sys­tem is fried, and it can't read mod­ern burned DVD:s .  I needed to move soft­ware to it to get the net­work up and run­ning again .  The only pe­riph­eral that was work­ing (be­sides the key­board and the screen) was the sound card .  It was run­ning an old ver­sion of  Slack­ware  .  

Ah, I thought, and wrote a pro­gram that en­coded data in sound .  When I did it back then I used a bad al­go­rithm. It was very noise sen­si­tive and tried to do too much at the same time .  As of then, I've im­proved (and sim­pli­fied) the con­cept to using a sort of pulse width mod­u­la­tion (an idea I got when I read about the  ZX Spec­trum Tape Loader .

The basic pro­to­col is triv­ial:
For every character:For every bit:Send a short pulse if the bit is 1. Send a long pulse if the bit is 0.Send a silence.Send a very long pulse (4 times as long as the shortest pulse).Send a silence.


This is nice and not very error prone .  The end-of-byte sig­nal means that er­rors don't taint their neigh­bors .  

The crux isn't the sig­nal gen­er­a­tion (which is laugh­ably triv­ial), it is the analy­sis on the re­ceiv­ing end; or rather deal­ing with the noise in the sig­nal .  The naive im­ple­men­ta­tion would be to sum the square of the sig­nal am­pli­tude over time pe­ri­ods--the pres­ence of a sine wave would con­verge to­wards some value and a silent sig­nal would con­verge to­wards 0 .  In a noisy sig­nal, it al­most al­ways con­verges to­wards some­thing non-zero, so no such luck .  

So, the sec­ond ap­proach would be to use a Fourier trans­form, to se­lect the part of the spec­trum where our sig­nal re­sides (400 Hz is what I chose) .  

A sim­ple im­ple­men­ta­tion of such a func­tion looks like this: 

double fourier1(double x_in[], double n, int length) { 
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); 

return sqrt(x_complex[0]*x_complex[0] + x_complex[1]*x_complex[1]) / (double) length; 



Where x_in is a se­ries of num­bers be­tween -1 and 1, and n is the mod­i­fied fre­quency (which is to say: length * fre­quency / rate) .  This func­tion would give you a num­ber cor­re­spond­ing to how much of a given fre­quency is in a sam­ple .  But you can do one bet­ter:  Har­mon­ics  .  Al­most every loud­speaker will pro­duce some level of har­mon­ics even though the sig­nal broad­casted is a plain sine wave with no har­mon­ics .  

So, to check if our sig­nal is in a given seg­ment, the fol­low­ing code can be used: 
double sum = 0; 
for(harmonic = 1; 2*harmonic < length / frq; harmonic++) { 
sum += fourier1(data, frq * harmonic, length); 



To check if the sig­nal is pre­sent in a given sig­nal, you must com­pare this against some form of thresh­old .  What's a good thresh­old varies with noise. A bad thresh­old value may ei­ther cause the pro­gram to in­ter­pret ran­dom noise as mean­ing­ful data, or re­ject good data as ran­dom noise .  

if(sum > threshold) { /* Signal is present in data block */ } 
else { /* Signal isn't present */ } 


The pro­to­col de­scribed above can be re­al­ized with the fol­low­ing code: 

if(sum < threshold) { 
if(signal_length) { 
if(signal_length > 10) { 
if(bit != 0) printf("(?)"); 
bit = 0; 
signal_length = 0; 
} else { 
bit_data = 2 * bit_data + (signal_length < 6); 
if(++bit == 8) { 
printf("%c", bit_data); 
fflush(NULL); 
bit = 0; 


signal_length = 0; 

} else { 
signal_length++; 



This does work .  It's not just some crazy pipe dream. Fol­low­ing is all the code you need for trans­fer­ring files from two com­put­ers using their sound­cards .  



Gar­bled trans­fers like this may soon ar­rive through a sound­card near you .  


Util­ity pro­grams 

Be­fore I get deeper into to the main pro­gram, I'm going to con­tribute some util­ity pro­grams. record and play­back .  They are both wrap­pers for OSS, and reads and di­gests data from the sound­card; or writes di­gested data to the sound­card at given sam­ple rates .  They deal in signed char ar­rays only, and may con­vert them for the sound­card .  Ex­actly what they do and how they work is a bit off topic, so I'll just post the code list­ings .  

play­back.c 
record.c 

The broad­cast­ing end 
As pre­vi­ously dis­cussed, the broad­cast­ing part of the pro­gram is pretty sim­ple . The only real gotcha is the sam­ple rate fac­tor in the fre­quency .  Since we're gen­er­at­ing a sig­nal with N bytes per sec­ond, we must de­crease our fre­quen­cies by a fac­tor 1/N .  Be­yond that, it's re­ally quite triv­ial. 

gen­er­ate.

The math parts 
Al­most there now .  We just need some fourier trans­forms and things of such na­ture .  The analy­sis end of the pro­gram can also make a XPM file of the fre­quency spec­trum of the input, which is why you see a bunch of XPM code .  

fourier.c 
fourier.h 

Fi­nally.. .  the re­ceiv­ing end 

Most of what this one does has al­ready been dis­cussed .  The thresh­old is hard-coded .  You may want to change it or what­ever. 

an­a­lyze.

... one file to com­pile them all, and into ob­jects link them 

Make­file 

To com­pile, you just run 
> make  

Using the pro­grams 

Be­fore I get to ac­tu­ally using the pro­grams, I re­peat my 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. 

Not there yet. It's quite an elab­o­rate mat­ter to use all these pro­grams. First you'll want to gen­er­ate your raw sound data .  Let's trans­fer /etc/fstab (don't do this as root! Some­thing might go hor­ri­bly wrong !

First, at­tach the mi­cro­phone on the re­ceiv­ing end to the speak­ers on the trans­mit­ting end .  Use duct tape or what­ever. I had an old hands free head­set that I wrapped so that the mi­cro­phone was held in place by the ear­piece .  





On the trans­mit­ting com­puter, run the fol­low­ing com­mand: 
./generate -b 25 -r 48000 -o out.data /etc/fstab 


Enter, but do not start the fol­low­ing on the trans­mit­ting com­puter: 
./playback -r 48000 < out.data # don't press enter yet! 


Now, on the re­ceiv­ing com­puter, run the fol­low­ing com­mand: 
./record -r 48000 -o out.recdata 

Note that out . ​recdata will grow very fast. In this case, 48000 bytes/sec­ond .  

Run the com­mand pre-typed in the trans­mit­ting com­puter's ter­mi­nal .  Be very quitet, and lis­ten to the noise com­ing from of the speaker .  This may take quite some time. Prac­tice your Zen. Find en­light­en­ment. When the noise stops, press Ctrl+C on the re­ceiv­ing com­puter .  

Run the fol­low­ing com­mand on the re­ceiv­ing com­puter: 
./analyze -b 25 out.recdata 


Watch a semi-gar­bled /etc/fstab be printed across your screen .  The -b switch is to be taken with a grain of salt. It is pro­por­tional to how fast the trans­fer is .  It must (ob­vi­ously) be the same on the re­ceiv­ing and the trans­mit­ting end .  I've got­ten it to work at -b 50 -r 48000. Sam­ple rate (-r) in­creases the pro­cess­ing time, but it also al­lows faster trans­fers .  There are a few fixed pos­si­ble sam­ple rates, 8000 al­ways works, oth­ers that are sup­ported by most sound­cards are 11025,16000,22050,24000,32000,44100 and 48000 .  

So, in sum­mary: -b de­ter­mines how fast the trans­fer is, and the max­i­mum pos­si­ble trans­fer speed is lim­ited by the sam­pling rate .  

If it doesn't work, try play­ing what you recorded with play­back .  If you can hear and dis­tin­guish the beeps, then so should the com­puter be able to .  If record or play­back fails, chances are you don't have per­mis­sions to ac­cess /dev/dsp .  If all you get is char­ac­ter salad, fid­dle with thresh­old in an­a­lyze . c. 

An even more elab­o­rate ver­sion of this pro­gram is de­scribed in  File Trans­fer Over Sound Card II - Phase Shift Key­ing  .  

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


If it doesn't work, try playing what you recorded with playback. If you can hear and distinguish the beeps, then so should the computer be able to. If record or playback fails, chances are you don't have permissions to access /dev/dsp. If all you get is character salad, fiddle with threshold in analyze.c



An even more elaborate version of this program is described in File Transfer Over Sound Card II - Phase Shift Keying. 

2011 update: Moved the sources to a github repo.

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



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

相关文章

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

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

file-max与ulimit的关系与差别

http://zhangxugg-163-com.iteye.com/blog/1108402 http://ilikedo.iteye.com/blog/1554822

瑞芯微Parameter File Format解析

Rockchip android系统平台使用parameter文件来配置一些系统参数 主要包含:串口号:nandflash分区 固件版本,按键信息等; 如下是台电P98HD的parameter参数: FIRMWARE_VER:4.1.1        // 固件版本 //固件版本,打包 updata.img 时会使用到,升级工具会根据这个识别固件版本。 //Boot loader 会读取

error while loading shared libraries: libnuma.so.1: cannot open shared object file:

腾讯云CentOS,安装Mysql时: 1.yum remove libnuma.so.1 2.yum install numactl.x86_64

Vue3图片上传报错:Required part ‘file‘ is not present.

错误 "Required part 'file' is not present" 通常表明服务器期望在接收到的 multipart/form-data 请求中找到一个名为 file 的部分(即文件字段),但实际上没有找到。这可能是因为以下几个原因: 请求体构建不正确:在发送请求时,可能没有正确地将文件添加到 FormData 对象中,或者使用了错误的字段名。 前端代码错误:在前端代码中,可能

File 的创建

在做音频录制的时候,用到创建一个音频文件,所以用到了如下方法 File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+ System.currentTimeMillis()+".mp3");if (!file.exists()){file.createNewFile();} 可是

clang: error: no such file or directory: '/Users/bigxin/Desktop/not file xxx

这样的问题,解决方法有以下几种: 第一:一般多人开发的时候会出现文件缺失的问题,遇到这个问题就根据提示找到对应的地址,然后会发现这个文件名字是红色的把红色的文件删除,然后重新addfile,然后把缺失的文件拷贝过来就可以了。。第二:如果第一种方法不行的话,可以移步到 TARGETS —-> Build Phases ——> Compile Sources(编译源) 里面来找,看有没有失效的文件