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

相关文章

BD错误集锦5——java.nio.file.FileSystemException 客户端没有所需的特权

问题:在运行storm本地模式程序时,java.nio.file.FileSystemException  客户端没有所需的特权   解决方式:以管理员身份运行IDEA即可。

BD错误集锦1——[Hive]ERROR StatusLogger No log4j2 configuration file found. Using default configuration:

错误描述:在使用IDEA进行jdbc方式连接到hive数据仓库时,出现以下错误:                ERROR StatusLogger No log4j2 configuration file found. 问题原因:缺少log4j2.xml文件   <?xml version="1.0" encoding="UTF-8"?><Configuration><Appender

iOS:编译时出现no such file or directory:xxx以及use twice...filenames are used to distinguish private dec

简    注册  登录   添加关注 作者  婉卿容若 2016.04.29 11:22 写了21870字,被16人关注,获得了14个喜欢 iOS:编译时出现"no such file or directory:xxx"以及"use twice...filenames are used to distinguish private

vue dist文件打开index.html报Failed to load resource: net::ERR_FILE_NOT_FOUND

本地正常。打包好的dist文件打开index.html报Failed to load resource: net::ERR_FILE_NOT_FOUND 解决办法: 在webpack.prod.conf.js 中output添加参数publicPath:’./’ 在webpack.base.conf.js里 publicPath: process.env.NODE_ENV === ‘pro

github 报错 git fatal: unable to write new index file

错误一:git fatal: unable to write new index file主要原因就是服务器磁盘空间不够导致的,增加服务器空间就OK了在百度上面搜索没得到什么有效信息,在gooogle上搜索得到很多有效信息 Finding large directories with something like the following helped clean up some log fi

STM32CubeIDE提示找不到头文件(No such file or directory)的解决办法

0 前言 最近在使用STM32CubeIDE时,发现为工程添加了头文件路径,但编译的时候还是报错,提示找不到头文件: 1 解决办法 1.1 为工程添加头文件路径 右键我们的工程,然后添加头文件路径(最好是相对路径): 1.2 为源文件夹添加头文件路径 右键我们包含了头文件的源文件夹,也将头文件路径添加进去(最好是相对路径): 最后编译就可以通过了: 2 更好的解决办法 这样

springboot报错:A bean with that name has already been defined in file

springboot报错:A bean with that name has already been defined in file  Action : Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

libcudart.so.9.0: cannot open shared object file: No such file or directory

使用torch 或者 torchvision的时候,报错:libcudart.so.9.0: cannot open shared object file: No such file or directory 经过gg一下,发现这个错误是 没有正确安装 英伟达的 CUDA 9 工具包。 但我一想 不对!我是服务器上根本没有GPU 根本不需要安装cuda啊! 后来torch官网发现,必须专门指

SyntaxError- Non-ASCII character '-xe8' in file

python编译报错: SyntaxError: Non-ASCII character ‘\xe8’ in file xxx原因是不支持中文注释,如这种中英文混杂注释: # Subtract off the mean and divide by the variance of the pixels.#减去平均值并除以像素的方差 解决办法: 在文件第一行加上 #encoding:utf

解决File协议导致的CORS限制,用Node.js搭建本地服务器

文章目录 一、前言二、分析报错原因三、如何解决四、具体步骤 你是否曾遇到这样的困境:在本地使用file://协议直接打开HTML文件时,由于现代浏览器的安全限制,无法跨源请求(CORS)本地资源?尤其是当你试图通过 <script type="module">标签导入本地JS模块时,浏览器会将其视为跨源请求,但file://协议并不支持CORS,导致你的代码无法正常运行。 现