?? ixj-redhat.c
字號:
if (write_retval != -EFAULT) { ixj_PostWrite(j, 0L); j->write_buffer_wp += count; j->write_buffers_empty--; } break; case NOPOST: write_retval = ixj_write(file_p, buf, count, ppos); if (write_retval != -EFAULT) { j->write_buffer_wp += count; j->write_buffers_empty--; } break; case POSTONLY: ixj_PostWrite(j, 0L); break; default: write_retval = pre_retval; } return write_retval;}static void ixj_read_frame(int board){ int cnt, dly; IXJ *j = &ixj[board]; if (j->read_buffer) { for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) { if (!(cnt % 16) && !IsRxReady(board)) { dly = 0; while (!IsRxReady(board)) { if (dly++ > 5) { dly = 0; break; } udelay(10); } } // Throw away word 0 of the 8021 compressed format to get standard G.729. if (j->rec_codec == G729 && (cnt == 0 || cnt == 5 || cnt == 10)) { inb_p(j->DSPbase + 0x0E); inb_p(j->DSPbase + 0x0F); } *(j->read_buffer + cnt) = inb_p(j->DSPbase + 0x0E); *(j->read_buffer + cnt + 1) = inb_p(j->DSPbase + 0x0F); }#ifdef PERFMON_STATS ++j->framesread;#endif if (j->intercom != -1) { if (IsTxReady(j->intercom)) { for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) { if (!(cnt % 16) && !IsTxReady(board)) { dly = 0; while (!IsTxReady(board)) { if (dly++ > 5) { dly = 0; break; } udelay(10); } } outb_p(*(j->read_buffer + cnt), ixj[j->intercom].DSPbase + 0x0C); outb_p(*(j->read_buffer + cnt + 1), ixj[j->intercom].DSPbase + 0x0D); }#ifdef PERFMON_STATS ++ixj[j->intercom].frameswritten;#endif } } else { j->read_buffer_ready = 1; wake_up_interruptible(&j->read_q); // Wake any blocked readers wake_up_interruptible(&j->poll_q); // Wake any blocked selects if (j->async_queue) kill_fasync(ixj[board].async_queue, SIGIO, POLL_IN); } }}static void ixj_write_frame(int board){ int cnt, frame_count, dly; BYTES blankword; IXJ *j = &ixj[board]; frame_count = 0; if (j->write_buffer && j->write_buffers_empty < 2) { if (j->write_buffer_wp > j->write_buffer_rp) { frame_count = (j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2); } if (j->write_buffer_rp > j->write_buffer_wp) { frame_count = (j->write_buffer_wp - j->write_buffer) / (j->play_frame_size * 2) + (j->write_buffer_end - j->write_buffer_rp) / (j->play_frame_size * 2); } if (frame_count >= 1) { if (j->ver.low == 0x12 && j->play_mode && j->flags.play_first_frame) { switch (j->play_mode) { case PLAYBACK_MODE_ULAW: case PLAYBACK_MODE_ALAW: blankword.low = blankword.high = 0xFF; break; case PLAYBACK_MODE_8LINEAR: case PLAYBACK_MODE_16LINEAR: blankword.low = blankword.high = 0x00; break; case PLAYBACK_MODE_8LINEAR_WSS: blankword.low = blankword.high = 0x80; break; } for (cnt = 0; cnt < 16; cnt++) { if (!(cnt % 16) && !IsTxReady(board)) { dly = 0; while (!IsTxReady(board)) { if (dly++ > 5) { dly = 0; break; } udelay(10); } } outb_p((blankword.low), j->DSPbase + 0x0C); outb_p((blankword.high), j->DSPbase + 0x0D); } j->flags.play_first_frame = 0; } for (cnt = 0; cnt < j->play_frame_size * 2; cnt += 2) { if (!(cnt % 16) && !IsTxReady(board)) { dly = 0; while (!IsTxReady(board)) { if (dly++ > 5) { dly = 0; break; } udelay(10); } }// Add word 0 to G.729 frames for the 8021. Right now we don't do VAD/CNG // so all frames are type 1. if (j->play_codec == G729 && (cnt == 0 || cnt == 5 || cnt == 10)) { outb_p(0x01, j->DSPbase + 0x0C); outb_p(0x00, j->DSPbase + 0x0D); } outb_p(*(j->write_buffer_rp + cnt), j->DSPbase + 0x0C); outb_p(*(j->write_buffer_rp + cnt + 1), j->DSPbase + 0x0D); *(j->write_buffer_rp + cnt) = 0; *(j->write_buffer_rp + cnt + 1) = 0; } j->write_buffer_rp += j->play_frame_size * 2; if (j->write_buffer_rp >= j->write_buffer_end) { j->write_buffer_rp = j->write_buffer; } j->write_buffers_empty++; wake_up_interruptible(&j->write_q); // Wake any blocked writers wake_up_interruptible(&j->poll_q); // Wake any blocked selects if (j->async_queue) kill_fasync(ixj[board].async_queue, SIGIO, POLL_IN);#ifdef PERFMON_STATS ++j->frameswritten;#endif } } else { j->drybuffer++; }}static int idle(int board){ IXJ *j = &ixj[board]; if (ixj_WriteDSPCommand(0x0000, board)) // DSP Idle return 0; if (j->ssr.high || j->ssr.low) return 0; else return 1;}static int set_base_frame(int board, int size){ unsigned short cmd; int cnt; IXJ *j = &ixj[board]; aec_stop(board); for (cnt = 0; cnt < 10; cnt++) { if (idle(board)) break; } if (j->ssr.high || j->ssr.low) return -1; if (j->dsp.low != 0x20) { switch (size) { case 30: cmd = 0x07F0; /* Set Base Frame Size to 240 pg9-10 8021 */ break; case 20: cmd = 0x07A0; /* Set Base Frame Size to 160 pg9-10 8021 */ break; case 10: cmd = 0x0750; /* Set Base Frame Size to 80 pg9-10 8021 */ break; default: return -1; } } else { if (size == 30) return size; else return -1; } if (ixj_WriteDSPCommand(cmd, board)) { j->baseframe.high = j->baseframe.low = 0xFF; return -1; } else { j->baseframe.high = j->ssr.high; j->baseframe.low = j->ssr.low; } return size;}static int set_rec_codec(int board, int rate){ int retval = 0; IXJ *j = &ixj[board]; j->rec_codec = rate; switch (rate) { case G723_63: if (j->ver.low != 0x12 || ixj_convert_loaded) { j->rec_frame_size = 12; j->rec_mode = 0; } else { retval = 1; } break; case G723_53: if (j->ver.low != 0x12 || ixj_convert_loaded) { j->rec_frame_size = 10; j->rec_mode = 0; } else { retval = 1; } break; case TS85: if (j->dsp.low == 0x20 || j->flags.ts85_loaded) { j->rec_frame_size = 16; j->rec_mode = 0; } else { retval = 1; } break; case TS48: if (j->ver.low != 0x12 || ixj_convert_loaded) { j->rec_frame_size = 9; j->rec_mode = 0; } else { retval = 1; } break; case TS41: if (j->ver.low != 0x12 || ixj_convert_loaded) { j->rec_frame_size = 8; j->rec_mode = 0; } else { retval = 1; } break; case G728: if (j->dsp.low != 0x20) { j->rec_frame_size = 48; j->rec_mode = 0; } else { retval = 1; } break; case G729: if (j->dsp.low != 0x20) { if (!j->flags.g729_loaded) { retval = 1; break; } switch (j->baseframe.low) { case 0xA0: j->rec_frame_size = 10; break; case 0x50: j->rec_frame_size = 5; break; default: j->rec_frame_size = 15; break; } j->rec_mode = 0; } else { retval = 1; } break; case ULAW: switch (j->baseframe.low) { case 0xA0: j->rec_frame_size = 80; break; case 0x50: j->rec_frame_size = 40; break; default: j->rec_frame_size = 120; break; } j->rec_mode = 4; break; case ALAW: switch (j->baseframe.low) { case 0xA0: j->rec_frame_size = 80; break; case 0x50: j->rec_frame_size = 40; break; default: j->rec_frame_size = 120; break; } j->rec_mode = 4; break; case LINEAR16: switch (j->baseframe.low) { case 0xA0: j->rec_frame_size = 160; break; case 0x50: j->rec_frame_size = 80; break; default: j->rec_frame_size = 240; break; } j->rec_mode = 5; break; case LINEAR8: switch (j->baseframe.low) { case 0xA0: j->rec_frame_size = 80; break; case 0x50: j->rec_frame_size = 40; break; default: j->rec_frame_size = 120; break; } j->rec_mode = 6; break; case WSS: switch (j->baseframe.low) { case 0xA0: j->rec_frame_size = 80; break; case 0x50: j->rec_frame_size = 40; break; default: j->rec_frame_size = 120; break; } j->rec_mode = 7; break; default: j->rec_frame_size = 0; j->rec_mode = -1; if (j->read_buffer) { kfree(j->read_buffer); j->read_buffer = NULL; j->read_buffer_size = 0; } retval = 1; break; } return retval;}static int ixj_record_start(int board){ unsigned short cmd = 0x0000; IXJ *j = &ixj[board]; if (j->read_buffer) { ixj_record_stop(board); } if (!j->rec_mode) { switch (j->rec_codec) { case G723_63: cmd = 0x5131; break; case G723_53: cmd = 0x5132; break; case TS85: cmd = 0x5130; // TrueSpeech 8.5 break; case TS48: cmd = 0x5133; // TrueSpeech 4.8 break; case TS41: cmd = 0x5134; // TrueSpeech 4.1 break; case G728: cmd = 0x5135; break; case G729: cmd = 0x5136; break; default: return 1; } if (ixj_WriteDSPCommand(cmd, board)) return -1; } if (!j->read_buffer) { if (!j->read_buffer) j->read_buffer = kmalloc(j->rec_frame_size * 2, GFP_ATOMIC); if (!j->read_buffer) { printk("Read buffer allocation for ixj board %d failed!\n", board); return -ENOMEM; } } j->read_buffer_size = j->rec_frame_size * 2; if (ixj_WriteDSPCommand(0x5102, board)) // Set Poll sync mode return -1; switch (j->rec_mode) { case 0: cmd = 0x1C03; // Record C1 break; case 4: if (j->ver.low == 0x12) { cmd = 0x1E03; // Record C1 } else { cmd = 0x1E01; // Record C1 } break; case 5: if (j->ver.low == 0x12) { cmd = 0x1E83; // Record C1 } else { cmd = 0x1E81; // Record C1 } break; case 6: if (j->ver.low == 0x12) { cmd = 0x1F03; // Record C1 } else { cmd = 0x1F01; // Record C1 } break; case 7: if (j->ver.low == 0x12) { cmd = 0x1F83; // Record C1 } else { cmd = 0x1F81; // Record C1 } break; } if (ixj_WriteDSPCommand(cmd, board)) return -1; return 0;}static void ixj_record_stop(int board){ IXJ *j = &ixj[board]; if (j->read_buffer) { kfree(j->read_buffer); j->read_buffer = NULL; j->read_buffer_size = 0; } if (j->rec_mode > -1) { ixj_WriteDSPCommand(0x5120, board); j->rec_mode = -1; }}static void ixj_vad(int board, int arg){ if (arg) ixj_WriteDSPCommand(0x513F, board); else ixj_WriteDSPCommand(0x513E, board);}static void set_rec_depth(int board, int depth){ if (depth > 60) depth = 60; if (depth < 0) depth = 0; ixj_WriteDSPCommand(0x5180 + depth, board);}static void set_rec_volume(int board, int volume){ ixj_WriteDSPCommand(0xCF03, board); ixj_WriteDSPCommand(volume, board);}static int get_rec_level(int board){ IXJ *j = &ixj[board]; ixj_WriteDSPCommand(0xCF88, board); return j->ssr.high << 8 | j->ssr.low;}static void ixj_aec_start(int board, int level){ IXJ *j = &ixj[board]; j->aec_level = level; if (!level) { ixj_WriteDSPCommand(0xB002, board); } else { if (j->rec_codec == G729 || j->play_codec == G729) { ixj_WriteDSPCommand(0xE022, board); // Move AEC filter buffer ixj_WriteDSPCommand(0x0300, board); } ixj_WriteDSPCommand(0xB001, board); // AEC On ixj_WriteDSPCommand(0xE013, board); // Advanced AEC C1 switch (level) { case AEC_LOW: ixj_WriteDSPCommand(0x0000, board); // Advanced AEC C2 = off ixj_WriteDSPCommand(0xE011, board); ixj_WriteDSPCommand(0xFFFF, board); break; case AEC_MED: ixj_WriteDSPCommand(0x0600, board); // Advanced AEC C2 = on medium
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -