⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 voice.c

📁 话带数据中传真解调程序
💻 C
字号:
/* * "Voice" support for ltmodem * * Actually, as long as we don't want to use onboard DSP, * this is going to be used not only for voice but for * _everything_. * * Copyright 1999 Pavel Machek * Copyright 1999 Jamie Lokier * Copyright 1999 R.J.M. Close * * Can be distributed under GPL */#include "voice.h"// Voice specific initialisation stuff.void voice_init(void){  int i;  dp_spk_volume = 0x8ab8;  io_voice_count = 0;  io_voice_count_rx= 0;  S_synthetic_ring_volume = 0x0a;  dp_sleep = 0;  //x68229 = 0x81;  dp_vt_cntrl = 0;  //x6822a = 1; // hmm, setting to 1 basically crashes modem  // Initialise io_dce_tx_buff array.  for ( i=0; i < 32; i = (i + 4)) {    io_dce_tx_buff[i] = 0;    io_dce_tx_buff[i + 1] = 50;    io_dce_tx_buff[i + 2] = 100;    io_dce_tx_buff[i + 3] = 50;  }}// ** Stuff robbed from jamie.cint voice_transmit(int fd_to_exit){  struct timeval tv_timeout;  int retval;  fd_set rfds;  PRINTF( "Starting tad: " );  dp_start_tad(0x80);	/* d0, b0, 90 looks nice but does not work! */                        /* 0x80 seems to work */  x_modem_state = 0xc;  dp_state = 0x28;  PRINTF( "ok\n" );  fcntl(0, F_SETFL, O_NONBLOCK);  fprintf( stderr, "+Fullduplex transmit/receive started\n" );  while(1) {    io_voice_count_rx = 0;    /* Watch stdin (fd 0) to see when it has input. */    FD_ZERO(&rfds);    FD_SET(0, &rfds);    if (fd_to_exit > 0)      FD_SET(fd_to_exit, &rfds);    tv_timeout.tv_sec = 0;    tv_timeout.tv_usec = 20;    retval = select(4, &rfds, NULL, NULL, &tv_timeout);    /* Don't rely on the value of tv now! */    if (FD_ISSET(0, &rfds)) {      int res;      res = read(0, io_dce_tx_sptr, 0x100 - io_voice_count);      io_voice_count += res;      while (!dp_dualport_vc_Tx()) {	usleep(1);      }    }    if (fd_to_exit > 0 && FD_ISSET(fd_to_exit, &rfds)) {      PRINTF( "Exiting fullduplex mode\n" );      return 0;    }    if (dp_dualport_vc_Rc())      if (write(1, io_dce_rx_sptr, 0x100)!=0x100) {	PRINTF("Could not write on stdout\n" );      }#if TRY_INTERRUPTS	PRINTF("voice_transmit: dp_dsp_isr is disabled!\n");#else    dp_dsp_isr();#endif  }}int dp_dualport_vc_Rc(void){  int cnt, ebx, al;  char *ebp;  int readreg = 0; /* 0x10(%esp,1) */  if (io_voice_count_rx != 0)    return 0;  cnt = dp_read_dsp_ram(0xe7);  if (0x100 > cnt) {    if (LT_DEBUG)      PRINTF( "Rc count too low: %x\n", cnt );    return 0;  }  ebp = io_dce_rx_sptr;#if 0  if (0x100 >= io_voice_count_rx) {    io_voice_count = 0;    return 0;  }#endif  do {    if (dp_regread(0xb0)) {      readreg = 0x90;      do {	al = dp_regread(readreg);	//	PRINTF( "%x", al );	*ebp++ = al;	readreg++;      } while (readreg <= 0x9f);      io_voice_count_rx += 0x10;    }    dp_regread(0xb0);    ebx = x_current_time();    while(1) {      if (dp_regread(0xb7) & 0x10)	break;      if (x_elapsed_time(ebx) > 0x32) {	PRINTF( "Timeout receiving\n" );	io_voice_count = 0;	return 0;      }    }  } while (0x100 > io_voice_count_rx);  return 1;}int dp_dualport_vc_Tx(void){  int writereg, esi, ebx, al;  char *edi;  if (io_voice_count != 0x100) {    //    PRINTF( "io_voice_count != 0x100 (%x)\n", io_voice_count );    return 1;  }  if ((0x100 > (esi = dp_read_dsp_ram(0xe1)))) {    if (LT_DEBUG)      PRINTF( "read_dsp_ram(0xe1) returned less than 0x100 (%x)\n", esi );    return 0;  }  edi = io_dce_tx_sptr;  if (0 != io_voice_count) {    do {      writereg = 0x80;	/* -4(%ebp) */      do {	al = *edi++;	dp_regwrite(writereg++, al);      } while (0x8f >= writereg);      dp_regwrite(0xb0, 0x10);      io_voice_count -= 0x10;      ebx = x_current_time();      while (1) {	if (dp_regread(0xb7) & 1)	  break;	if (x_elapsed_time(ebx) >= 0x32) {	  PRINTF( "Timeout while sending :-(\n" );	  io_voice_count = 0;	  return 0;	}      }    } while (io_voice_count != 0);  }  return 1;}voiddp_download_fdsp(void){  dp_modem_command(0x13, 0, 0);  //printf( "Size of wDspFdsp is %x, should be %x\n", sizeof(wDspFdsp), 0xcb9*2);  dp_download_dsp(wDspFdsp, 0xcb9);}voiddp_init_fdsp(void){  dp_write_dsp_ram(0x86, 0);  dp_write_dsp_ram(0x880, 0x9a54);  dp_write_dsp_ram(0x86c, 0x20);  dp_write_dsp_ram(0x86e, 0xfff8);}voiddp_mute_fdsp(int arg){  printf( "dp_mute_fdsp: %d\n", arg );  if (arg != 0)    dp_write_dsp_ram(0x885, dp_spk_volume /* ??? 0x6821c */);  else    dp_write_dsp_ram(0x885, 0);}voiddp_stop_fdsp(void){  dp_modem_command(0x13, 0, 0);  x_output(0x18);  dp_modem_command(0x27, 1, 0);  dp_set_mercury_gain();  //  if (something)  //   dp_stop_fdsp();  //	else v8bis_init();}voiddp_fdsp_record_start(void){  // movb $0x01,0x67d32  dp_write_dsp_ram(0x871, dp_read_dsp_ram(0x871) | 0x02);}/* Strange, dp_start_spkphone is always called with 0 as argument ? */voiddp_start_spkphone(int arg){  // dp_change_mercury_gain(...);  dp_write_dsp_ram(0x86, 0);  dp_modem_command(0x13, 0, 0);  dp_download_fdsp();#if 0	/* It seems to hangup. I do not want to hangup! */  printf( "X_output: 0x07\n" );  x_output(0x07);  printf( "X_output: 0x17\n" );  x_output(0x17);#endif  dp_write_dsp_ram(0x800, 0x1c);  if (arg) {    //    dp_apollo_command(....);    //    dp_init_hdsp();    die( "must not happen\n" );  } else {    //    dp_apollo_command(....);    dp_init_fdsp();  }  printf( "Write volume\n" );  dp_write_dsp_ram(0x885, dp_spk_volume );  dp_write_dsp_ram(0x724, 0x400);  printf( "Done\n" );}voiddp_init_hdsp(void){  dp_write_dsp_ram(0x8e6, 0x21);  dp_write_dsp_ram(0x86e, 0xfffd);  dp_write_dsp_ram(0x87b, 0x8100);  dp_write_dsp_ram(0x87e, 0x800);  dp_write_dsp_ram(0x724, 0x400);  dp_write_dsp_ram(0x87f, 0x1000);  dp_write_dsp_ram(0x723, 0x08);  dp_write_dsp_ram(0x880, 0x4000);  dp_write_dsp_ram(0x747, 0x14);  dp_write_dsp_ram(0x86c, 0x20);  //  if (byte_68255)    dp_write_dsp_ram(0x710, 0x4000);}voiddp_start_hdsp(void){  dp_start_spkphone(0);  dp_write_dsp_ram(0x85, 0x905);  dp_write_dsp_ram(0x85, 0x9205);  // dp_set_speakerphone_gain();  dp_write_dsp_ram(0x725, 0xb6a);}voiddp_switch_fdsp(void){  dp_write_dsp_ram(0x97, 0);  dp_init_fdsp();  dp_write_dsp_ram(0x85, 0x9f05);  dp_write_dsp_ram(0x871, 0xc004);  //  dp_set_speakerphone_gain();  if (0x67d32 != 1)    dp_fdsp_record_start();}/* * Ouch, speakerphone is _not_ what is interesting for us. * TAD mode (telephone answering device) IS! */voiddp_download_tad(void){  dp_download_dsp(wDspTad, 0x949);  dp_modem_command(0x13, 0, 0);}voiddp_detect_dtmf(void){  /* This is actually pretty long function */  dp_write_dsp_ram(0x37, 0x50 /* dp_set_threshold() */ );  //  dp_set_iirs();  dp_write_dsp_ram(0x27, 0);  dp_write_dsp_ram(0x28, 0);  dp_write_dsp_ram(0x26, 0x1e);  if (0) {    dp_write_dsp_ram(0x26, 0x2f);  }  if (0) {    //dp_write_dsp_array(0x1c, 0x15e28, 0xa);    /* ... */  } else {    //dp_write_dsp_array(0x1c, 0x15e40, 0xa);    dp_write_dsp_ram(0x24, 0x2a49);    dp_write_dsp_ram(0xfc0, 0x28d5);  }  dp_modem_command(8, 0x0b, 0);  /* ... = */ x_current_time();              x_current_time();              x_current_time();  /* ... */}voiddp_start_tad(int arg){  //int vsm2 = 0, var_30 = 0;  int var_minus4 = 0;  //int vsm;	// Sampling mode, as set by AT+VSM  int al;  printf( "Starting dp_start_tad\n" );   if (dp_sleep == 1)    dp_init_modem();  dp_modem_command(0x13, 0, 0);  dp_vt_cntrl = arg;	/* Strange: uninitialized! */  x_sleep(0x32);  if (dp_tad_downloaded == 0) {    x_output(0x07);	/* Basically hangup */    dp_modem_command(0x13, 0, 0);    dp_download_tad();    dp_vsp = 0;    x_output(0x17);  }  dp_monitor_hec = 0;  dp_dialtone_enable = 1;  if (0 == x_dma_xfer && dp_vt_cntrl) {	/* Hmm, if I do if (0), I basically crash the modem */    dp_write_dsp_ram(0x3d, 0x200);    dp_regwrite(0xb6, 0xff);    dp_regread(0xb0);    dp_regread(0xb0);    al = dp_vt_cntrl;  }  /* 38aa0: */  /* ecx = sampling mode, from 68229. 0x84 == ADPCM, confirmed now.     0x81 is 16-bit linear, which should be closest to native.     ecx -= 0x80 */  switch (S (0x49)) {  case 0x80: arg |= 0x0e; break;  case 0x82: arg |= 0x09; break;  case 0x81:  case 0x83: break;  default: arg |= 0x04; break;  }  al = S (0x4a);  if (al!=1) {	//  L7:     //PRINTF( "Sorry, I dunno what setne does\n" ); 	//if zero flag is clear (ne) then al = 1, else al = 0;    if (al != 0x02)      al = 1;    else       al = 0;    al--;    al &= 0x08;    var_minus4 = al;  } else    var_minus4 = 0x04;	/* This is 8kHz */  // L8: label not used!  dp_apollo_command(0x20, arg, 0, 					7, H_TAD_tx_level_dB -3, 					0, 0, var_minus4 );  // dp_set_tad_speaker_gain();  // dp_set_tad_mic_gain();  // dp_detect_dtmf();  dp_write_dsp_ram(0x3c, 0x28);  al = dp_vt_cntrl;  if ((al == 0xc0) ||      (al == 0xe0) ||      (al == 0x40) ||      (al == 0x80)) {    dp_write_dsp_ram(0x85, 0x105);    dp_write_dsp_ram(0x85, 0x1305);  }  else     dp_write_dsp_ram(0x85, 0x1205);  /* bc2: */  al = dp_vt_cntrl;  if (!(al & 0x80))    goto L13;  if ((al == 0xa0) || (al == 0xf0))    /* bda */    dp_write_dsp_ram(0x87e, 0xa000);  else	dp_write_dsp_ram(0x87e, 0x8000);  dp_write_dsp_ram(0x87c, 0x3000);  /* bf0 */  goto L14; L13:  dp_write_dsp_ram(0x87e, 0); L14:  dp_write_dsp_ram(0xe0, 0x80);  dp_write_dsp_ram(0xe4, 0x80);  dp_write_dsp_ram(0xe5, 0xfff0);  dp_dsp_data_in_progress = 0;  dp_tad_downloaded = 1;  printf( "dp_start_tad done\n" );}voiddp_synth_ring_freq1(void){  printf( "FAKE: I just selected one set of values\n" );  dp_write_dsp_ram(0x5, 0x24b5);  dp_write_dsp_ram(0x6, 0x346c);}voiddp_synth_ring_freq2(void){  printf( "FAKE: I just selected one set of values\n" );  dp_write_dsp_ram(0x5, 0x2d41);  dp_write_dsp_ram(0x6, 0x2d41);}voiddp_synth_ring_init(void){  dp_write_dsp_ram(0x11, 6+S_synthetic_ring_volume);  dp_modem_command(0x13, 0, 0);  dp_download_tad();  dp_write_dsp_ram(0x85, 0);  dp_apollo_command(0x20, 0x20, 0, 0, 0, 0, 0, 0x40);  x_output(0x17);  dp_modem_command(0x7, 0x1, 0);  dp_write_dsp_ram(0x17, 0xbb8);  dp_synth_ring_freq1();  dp_write_dsp_ram(0x85, 0x20);  x_output(0x17);  dp_enable_ring_int();}voiddp_synth_ring_on(void){  dp_write_dsp_ram(0x11, S_synthetic_ring_volume);  sleep(1);  dp_synth_ring_freq2();}voiddp_synth_ring_off(void){  dp_write_dsp_ram(0x85, 0);  dp_modem_command(0x13, 0, 0);  x_output(0x18);}// Stuff robbed from jamie.cvoid dp_apollo_command(int a8, int aC, int a10, int a14, int a18, int a1c, int a20, int a24){  dp_regwrite(0xD8, 0x18);  dp_regwrite(0x30, a24);  dp_regwrite(0x31, a20);  dp_regwrite(0x32, a1c);  dp_regwrite(0x33, a18);  dp_regwrite(0x34, a14);  dp_regwrite(0x35, a10);  dp_regwrite(0x36, aC);  dp_regwrite(0x37, a8);  wait_for_core_read();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -