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

📄 phonerec.c

📁 基于AVR制作的电话语音录制系统
💻 C
📖 第 1 页 / 共 5 页
字号:
        //dtmf_string[9]='$';    } else {        //dtmf_string[9]=' ';#endif // HAVE_MMC                if (monitor_mode) {            OCR2=(monitor_mode==2 || last_reported_hook==OffHook)?sample8:0;        } else {            OCR2=0;        } #ifdef HAVE_MMC            }    if (audio_status & AS_RECORDING_IN_PROGRESS) {        *p=sample8;    }    if (audio_status) {        audio_cnt++;        audio_cnt&=(MMC_BLOCK_SIZE-1);    }#endif // HAVE_MMC    unsigned char out=sample8;        // ADPCM compression and on-hook/off-hook/disconnect logic    // We are actually working with the previous sample; we run while the ADC    // is busy converting, since it takes 832 cycles perform a conversion    // (adc clock=64 main clock cycles * 13 adc clocks = 832 cycles).    // Remember that we get here every 1000 cycles (8MHz/8KHz sampling rate)#ifdef USE_ADPCM_COMPRESSION#ifdef ADPCM_USES_LONGS    unsigned char sign;      /* Current adpcm sign bit */    unsigned char delta;     /* Current adpcm output value */    long step;               /* Stepsize */    long diff;               /* Difference between val and valprev */    long vpdiff;             /* Current change to valpred */#else // ADPCM_USES_LONGS    unsigned char sign;      /* Current adpcm sign bit */    unsigned char delta;     /* Current adpcm output value */    short step;               /* Stepsize */    short diff;               /* Difference between val and valprev */    short vpdiff;             /* Current change to valpred */#endif // ADPCM_USES_LONGS#endif // USE_ADPCM_COMPRESSION    enum hook_status_t hook=HookUnknown;    // if (in>=126 && in<=130) val=128;    // Transmit only if off-hook    // if (!(ACSR & _BV(ACO))) xmit(val);#ifdef USE_ADPCM_COMPRESSION#ifdef USE_PROGMEM_CONSTANTS    step = pgm_read_word(stepsizeTable+idx);#else    step = stepsizeTable[idx];#endif	diff = sample16 - inpred;	sign = (diff < 0) ? 8 : 0;	if ( sign ) diff = (-diff);	/* Step 2 - Divide and clamp */	/* Note:	** This code *approximately* computes:	**    delta = diff*4/step;	**    vpdiff = (delta+0.5)*step/4;	** but in shift step bits are dropped. The net result of this is	** that even if you have fast mul/div hardware you cannot put it to	** good use since the fixup would be too expensive.	*/	delta = 0;	vpdiff = (step >> 3);		if ( diff >= step ) {	    delta = 4;	    diff -= step;	    vpdiff += step;	}	step >>= 1;	if ( diff >= step  ) {	    delta |= 2;	    diff -= step;	    vpdiff += step;	}	step >>= 1;	if ( diff >= step ) {	    delta |= 1;	    vpdiff += step;	}#ifdef ADPCM_USES_LONGS	/* Step 3 - Update previous value */	if ( sign )	  inpred -= vpdiff;	else	  inpred += vpdiff;	/* Step 4 - Clamp previous value to 16 bits */	if ( inpred > 32767 )	  inpred = 32767;	else if ( inpred < -32768 )	  inpred = -32768;#else	/* Step 3 - Update previous value */    if (sign) {        if (vpdiff>0 && inpred<vpdiff-32767)            inpred=-32768;        else            inpred-=vpdiff;    } else {        if (vpdiff>0 && inpred>32767-vpdiff)            inpred=32767;        else            inpred+=vpdiff;    }#endif // ADPCM_USES_LONGS	/* Step 5 - Assemble value, update index and step values */	delta |= sign;#ifdef USE_PROGMEM_CONSTANTS    idx += (char)pgm_read_byte(indexTable+delta);	#else	idx += indexTable[delta];#endif	if ( idx < 0 )  idx = 0;	if ( idx > 88 ) idx = 88;	/* Step 6 - Output value */    if (pending & 128) {        out = (pending<<4)|delta;        pending=0;         if (!--count) {            count=AUDIO_BLOCK_LENGTH;            xmit(CMD_BLOCK_START);            xmit(CMD_ADPCM_STATE);            xmit_short(inpred);            xmit(idx);            /* On-hook/Off-hook/Disconnected detection logic & debounce */            if (ACSR & _BV(ACO)) {                hook=Disconnected;            } else {                if (PINB & _BV(PB3)) {                    hook=OnHook;                } else {                    hook=OffHook;                }            }            if (inverts<0) inverts++;            if (ring_age>0) {                if (ring_age<255) ring_age--;            } else {                ring_age=255;                call_timer_stop();                call_status=CallIdle;                stop_recording();                ring_count=0;            }                    if (hook != last_hook) {                steady=0; last_hook=hook;                if (inverts>=0) {                    inverts++;                    if (inverts==4) {                        lcd_home();                        ring_count++;                        if (ring_count==1) {                            if (call_status!=CallIncoming) {                                call_timer_reset();                                 call_status=CallIncoming;                                start_recording(0);                            }                        }                        inverts=-70;                        ring_age=250;                    }                }            } else {                if (steady==STEADY_COUNT) {                    if (inverts>0) inverts=0;                    if (last_reported_hook!=hook) {                        xmit(CMD_BLOCK_START);                        xmit(hook);                        steady=0;                        last_reported_hook=hook;                        if (hook==OffHook) {                            if (call_status==CallIdle) {                                call_timer_reset();                                call_status=CallOutgoing;                                dtmf_string_clear(); dialing_digits=TRUE;                                digit_age=0;                                start_recording(0);                            }                        }                        if (hook==OnHook) {                            call_timer_stop();                            call_status=CallIdle;                            stop_recording();                            ring_count=0;                            dtmf_string_clear();                        }                    }                } else {                    steady++;                }            }        }        if (out==CMD_BLOCK_START) xmit(out);        xmit(out);    } else {        pending = (delta&15)|128;     }#else   // USE_ADPCM_COMPRESSION#ifdef HAVE_MMC    spi_next_xmit();#endif // HAVE_MMC    //unsigned char ringdet=PINB & _BV(PB3);    if (!ringdet_quell) {        unsigned char ringdet=2;        if (sample8>250) ringdet=1;        if (sample8<5)   ringdet=0;        if (ringdet==1) {            ringdet_mids=0;            if (last_ringdet) {                ringdet_his++;            } else {                ringdet_his=0;                if (ringdet_los>=60 || ringdet_los<=140) {                    ringlike++;                } else {                    ringlike--;                }            }        } else if (ringdet==0) {            ringdet_mids=0;            if (last_ringdet) {                ringdet_los=0;                if (ringdet_his>=60 || ringdet_his<=140) {                    ringlike++;                } else {                    ringlike--;                }            } else {                ringdet_los++;            }        } else {            ringdet_mids++;            if (ringdet_mids>100) ringdet_his=ringdet_los=ringlike=0;        }        last_ringdet=ringdet;    }    if (!--count) {        count=AUDIO_BLOCK_LENGTH;#define DO_HOOK_LOGIC#ifdef DO_HOOK_LOGIC        /* On-hook/Off-hook/Disconnected detection logic & debounce */        if (ACSR & _BV(ACO)) {            hook=Disconnected;        } else {            if (PINB & _BV(PB3)) {                hook=OnHook;            } else {                hook=OffHook;            }        }        if (hook != last_hook) {            steady=0; last_hook=hook;        } else {            if (steady==STEADY_COUNT) {                if (last_reported_hook!=hook) {                    xmit(CMD_BLOCK_START);                    xmit(hook);                    steady=0;                    last_reported_hook=hook;                    if (hook==OffHook) {                        if (call_status==CallIdle) {                            call_timer_reset(); call_status=CallOutgoing;                            dtmf_string_clear(); dialing_digits=TRUE;#ifdef HAVE_LCD                            digit_age=0;#endif // HAVE_LCD#ifdef HAVE_MMC                            start_recording(0);#endif // HAVE_MMC                        } else if (call_status==CallIncoming) {                            ring_age=255;                        }                    } else if (hook==OnHook) {                        call_timer_stop();                        call_status=CallIdle;#ifdef HAVE_MMC                        stop_recording();#endif // HAVE_MMC                        dtmf_string_clear();                        ring_age=255;                    }                }            } else {                steady++;            }        }#endif // DO_HOOK_LOGIC        xmit(CMD_BLOCK_START);        xmit(CMD_RAW_BLOCK);    }    //out=TCNT0;    //if (out==CMD_BLOCK_START) xmit(out);    //xmit(out);#endif  // USE_ADPCM_COMPRESSION    do_xmit();#ifdef HAVE_MMC#ifdef MMC_MANY_IO_BLOCKS    spi_next_xmit(); ////////////// --- THIS    /* MMC/SD read/write block 2 */    do_block_mmc_io();#endif // MMC_MANY_IO_BLOCKS#endif // HAVE_MMC// -- Goertzel algorithm for DTMF, ring and dial/ring/busy tone detection#ifdef HAVE_GOERTZEL            //unsigned char n;    //for (n=0;n<3;n++) {    //    unsigned char one=n<<1;    //    unsigned char two=one+1;    //    coef=pgm_read_word(gcos+n);    //    short y=((d[one]*coef)>>8)-d[two]+sample8;    //    d[two]=d[one]; d[one]=y;    //}        asm("lds    r30,(%0)+1  \n\t"         "eor   r31,r31     \n\t"         "sbrc  r30,7       \n\t"         "com   r31         \n\t": : "m"(sample16) : "r30","r31");    // Saves r1, which is clobbered by goertzel_inner    asm("push r1\n\t");     // Gets Y pointing to 'd'    asm("lds  r28,%0     \n\t"         "lds  r29,(%0)+1 \n\t"           : : "m" (d) : "r28", "r29");    goertzel_inner_16(GCOS0440);    goertzel_inner_16(GCOS0697);    goertzel_inner_16(GCOS0770);    goertzel_inner_16(GCOS0852);    goertzel_inner_16(GCOS0941);    goertzel_inner_16(GCOS1209);    goertzel_inner_00(GCOS1336);    goertzel_inner_08(GCOS1477);    goertzel_inner_08(GCOS1633);            do_xmit();        // Restores r1    asm("pop r1\n\t");#ifdef HAVE_MMC    spi_next_xmit();#ifdef MMC_MANY_IO_BLOCKS    /* MMC/SD read/write block 2 */    do_block_mmc_io();#endif // MMC_MANY_IO_BLOCKS#endif // HAVE_MMC                //y=((d[ 2]*0x1E3)>>8)-d[ 3]+c; d[ 3]=d[ 2]; d[ 2]=y;    //y=((d[ 2]*0x1E3L)>>8)-d[ 3]+c; d[ 3]=d[ 2]; d[ 2]=y;    //y=((d[ 4]*0x1B4L)>>8)-d[ 5]+c; d[ 5]=d[ 4]; d[ 4]=y;    //y=((d[ 6]*0x1A3L)>>8)-d[ 7]+c; d[ 7]=d[ 6]; d[ 6]=y;

⌨️ 快捷键说明

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