求助 关于V17调制解调算法

目前需要用 Java 或 C 实现 v17 调制解调的软件模拟,但是本人对此几乎没有了解,在网上也搜集不到相关资料,求个位大侠相助,讲解流程算法,有代码更好,不胜感激!

spandsp是一个软件传真处理引擎,包含了从调制,发送,解调,编码各种功能。下面详细介绍spandsp的安装、使用方法。

安装spandsp需要预先安装libtiff和audiofile库(最新的spandsp已自带audiofile库),从http://www.libtiff.org/下载libtiff安装好后,再从http://www.soft-switch.org/downloads/spandsp/下载spandsp安装。安装过程都很简单:

./configure

make

sudo make install

spandsp支持v17,v21,v27,v29三种不同的调制功能,实现了T.30,T.4,HDLC协议。如果已从电话线中获取到了包含传真信息的音频文件,则可以用下面的程序进行解调,获得原始传真文件:

#define SAMPLES_PER_CHUNK 160

fsk_rx_state_t fsk;//v21解调器

v17_rx_state_t v17;//v17解调器

v29_rx_state_t v29;//v29解调器

v27ter_rx_state_t v27ter;//v27解调器

int16_t amp[SAMPLES_PER_CHUNK];

AFfilehandle inhandle;//音频文件句柄

int len;

const char *filename;

float x;

filename = "fax_samp.wav";//音频文件名

if (argc > 1)

filename = argv[1];

if ((inhandle = afOpenFile(filename, "r", NULL)) == AF_NULL_FILEHANDLE){//调用audiofile库函数打开音频文件

fprintf(stderr, " Cannot open wave file '%s'\n", filename);

exit(2);

}

if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0) {

printf(" Unexpected frame size in speech file '%s' (%f)\n", filename, x);

exit(2);

}

if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE){

printf(" Unexpected sample rate in speech file '%s' (%f)\n", filename, x);

exit(2);

}

if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0){

printf(" Unexpected number of channels in speech file '%s' (%f)\n", filename, x);

exit(2);

}

memset(&t30_dummy, 0, sizeof(t30_dummy));

span_log_init(&t30_dummy.logging, SPAN_LOG_FLOW, NULL);//初始化日志对象

span_log_set_protocol(&t30_dummy.logging, "T.30");

hdlc_rx_init(&hdlcrx, FALSE, TRUE, 5, hdlc_accept, NULL);//初始化HDLC规程,注册hdlc_accept回调函数

fsk_rx_init(&fsk, &preset_fsk_specs[FSK_V21CH2], TRUE, v21_put_bit, NULL);//初始化v21解调器,注册回调函数v21_put_bit

v17_rx_init(&v17, 14400, v17_put_bit, NULL);//初始化v17和回调函数

v29_rx_init(&v29, 9600, v29_put_bit, NULL);//初始化v29和回调函数

//v29_rx_init(&v29, 7200, v29_put_bit, NULL);

v27ter_rx_init(&v27ter, 4800, v27ter_put_bit, NULL);

//v27ter_rx_init(&v27ter, 2400, v27ter_put_bit, NULL);

fsk_rx_signal_cutoff(&fsk, -45.5);//配置参数

v17_rx_signal_cutoff(&v17, -45.5);

v29_rx_signal_cutoff(&v29, -45.5);

v27ter_rx_signal_cutoff(&v27ter, -40.0);

span_log_init(&v17.logging, SPAN_LOG_FLOW, NULL);//配置日志

span_log_set_protocol(&v17.logging, "V.17");

span_log_set_level(&v17.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);

span_log_init(&v29.logging, SPAN_LOG_FLOW, NULL);

span_log_set_protocol(&v29.logging, "V.29");

span_log_set_level(&v29.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);

span_log_init(&v27ter.logging, SPAN_LOG_FLOW, NULL);

span_log_set_protocol(&v27ter.logging, "V.27ter");

span_log_set_level(&v27ter.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);

if (t4_rx_init(&t4_state, "fax_decode.tif", T4_COMPRESSION_ITU_T4_2D) == NULL) {//初始化t4

fprintf(stderr, "Failed to init\n");

exit(0);

}

for (;;)

{

len = afReadFrames(inhandle, AF_DEFAULT_TRACK, amp, SAMPLES_PER_CHUNK);//读取音频文件,解调

if(len<=0)

break;

fsk_rx(&fsk, amp, len);

//v17_rx(&v17, amp, len);

//v29_rx(&v29, amp, len);

v27ter_rx(&v27ter, amp, len);

}

if(t4_up) t4_end();//保存已解调的传真文件

t4_rx_end(&t4_state);

if (afCloseFile(inhandle) != 0){//关闭音频文件夹

fprintf(stderr, " Cannot close wave file '%s'\n", filename);

exit(2);

}

由以上代码可知,一个软件传真接收器必须包好v21解调器和hdlc规程,可选v17,v27,v29等不同速率的解调器。最后,一定要关闭传真文件,否则转化的传真图像可能未写到磁盘中。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/foxwit/archive/2010/12/29/6106068.aspx
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-07-05
书山有路勤为径本回答被提问者采纳
相似回答