📄 audbri_utils.c
字号:
dump_sig(test_sig, sample_cnt, aufname("test-rec-mono", auptr)); } /* * get space for fft magnitudes */ if ((lmag = (double *) calloc(fftsize, sizeof(double))) == NULL) { send_message(ERSYS, ERROR, er_mem, (sizeof(double)*fftsize), SYSMSG); } /* * perform fft on test signal */ bin_sel = LEFT; if (fftmag(test_sig, sample_cnt, lmag) != fftsize) { send_message(ERAUDIO, ERROR, er_fftmag); } if (chksig(refp, auptr->lfreq, test_sig, NULL, lmag, NULL, sample_cnt, auptr, thdata.lrms, thdata.lmag) == FALSE) { TRACE_OUT return(FALSE); } } /* * Check STEREO signal. */ else { splitstereo(&lsig, &rsig, test_sig, 2*sample_cnt); fftsize = sample_cnt/2 + 1; rdsize = fftsize * sizeof(double) + sizeof(ref_data_t); if (dump_signals) { dump_sig(lsig, sample_cnt, aufname("test-rec-left", auptr)); dump_sig(rsig, sample_cnt, aufname("test-rec-right", auptr)); } /* * get space for fft magnitudes */ if ((lmag = (double *) calloc(fftsize, sizeof(double))) == NULL) { send_message(ERSYS, ERROR, er_mem, (sizeof(double)*fftsize), SYSMSG); } if ((rmag = (double *) calloc(fftsize, sizeof(double))) == NULL) { send_message(ERSYS, ERROR, er_mem, (sizeof(double)*fftsize), SYSMSG); } /* * perform fft on test signal */ bin_sel = LEFT; if (fftmag(lsig, sample_cnt, lmag) != fftsize) { send_message(ERAUDIO, ERROR, er_fftmag); } bin_sel = RIGHT; if (fftmag(rsig, sample_cnt, rmag) != fftsize) { send_message(ERAUDIO, ERROR, er_fftmag); } send_message(0, DEBUG, left_msg); if (chksig(refp, auptr->lfreq, lsig, rsig, lmag, rmag, sample_cnt, auptr, thdata.lrms, thdata.lmag) == FALSE) { send_message(0, DEBUG, er_lnotvalid); TRACE_OUT return(FALSE); } send_message(0, DEBUG, right_msg); refp = (ref_data_t *) ((caddr_t) refp + rdsize); if (chksig(refp, auptr->rfreq, rsig, lsig, rmag, lmag, sample_cnt, auptr, thdata.rrms, thdata.rmag) == FALSE) { send_message(0, DEBUG, er_rnotvalid); TRACE_OUT return(FALSE); } } TRACE_OUT return(TRUE);}/* * Determines whether or not a signal "matches" the reference signal. * The FFT magnitudes are divided into 4 bands and "matching" means that * the peak FFT magnitudes (in a particular band) for the test signal are * within 'aumag_tol' db of the FFT magnitudes for the reference signal * and that the test signal's RMS value is within 'aurms_tol db. */intchksig(refp, driven, test_sig, alt_sig, testmag, altmag, sample_cnt, auptr, rmsptr, magptr)ref_data_t *refp;int driven;short *test_sig;short *alt_sig;double *testmag;double *altmag;int sample_cnt;au_data_t *auptr;double *rmsptr;double *magptr;{ int i, fftsize, rdsize, count; double alt_rms, rms, tolerance, upper_limit, lower_limit; double ref_fbandrms, alt_threshold; double threshold, *refmag, ref_bandrms, test_bandrms, alt_bandrms; double *lrmsptr, *rrmsptr, *lmagptr, *rmagptr; func_name = "chksig"; TRACE_IN fftsize = sample_cnt/2+1; /* * Perform RMS calculation */ rms = rmscalc(test_sig, sample_cnt); if (!driven) { alt_rms = rmscalc(alt_sig, sample_cnt); } /* * calculate upper and lower limits for rms */ upper_limit = *rmsptr++; lower_limit = *rmsptr++; /* * Verify that RMS is within tolerance */ if (driven) { if (rms < lower_limit || rms > upper_limit) { send_message(0, VERBOSE+DEBUG, er_rms, rms, lower_limit, upper_limit, refp->rms); TRACE_OUT return(FALSE); } else { send_message(0, DEBUG, rms_msg, rms, refp->rms, lower_limit, upper_limit); } } else { upper_limit = alt_rms - upper_limit; if (rms > upper_limit) { send_message(0, VERBOSE+DEBUG, er_rms, rms, lower_limit, upper_limit, refp->rms); TRACE_OUT return(FALSE); } else { send_message(0, DEBUG, rms_msg, rms, refp->rms, lower_limit, upper_limit); } } /* * Determine an alternative non-fundamental band threshold * from the fundamental frequency band. The alternative is * the fundamental RMS - bandrms_tol. It's used if it is * greater than the regular threshold. * */ for (i = 0; auptr->bdata[i].type != NULL; i++) { if (auptr->bdata[i].type == BAND_FUND) { if (driven) { refmag = &refp->mag; } else { refmag = altmag; } ref_fbandrms = bandrms(refmag, fftsize, sample_cnt, auptr->bdata[i].start_freq, auptr->bdata[i].end_freq, auptr->sample_rate); alt_threshold = ref_fbandrms - bandrms_tol; } } /* * check each fft frequency band */ for (i=0, refmag = &refp->mag; auptr->bdata[i].type != NULL; i++) { /* * Find the RMS of the fft mag in the reference signal for * this band and calculate upper limit. */ ref_bandrms = bandrms(refmag, fftsize, sample_cnt, auptr->bdata[i].start_freq, auptr->bdata[i].end_freq, auptr->sample_rate); /* * Find test signal's max fft mag in this band. */ test_bandrms = bandrms(testmag, fftsize, sample_cnt, auptr->bdata[i].start_freq, auptr->bdata[i].end_freq, auptr->sample_rate); /* * If this is a stereo signal and this channel isn't * driven then we need to derive the threshold. This * code assumes that if one channel isn't driven then * the other is. * Mono signal are always driven (of course). */ if (driven) { threshold = *magptr++; } else { alt_bandrms = bandrms(altmag, fftsize, sample_cnt, auptr->bdata[i].start_freq, auptr->bdata[i].end_freq, auptr->sample_rate); threshold = alt_bandrms - *magptr++; } /* * If this is the fundamental's band, then make sure * the test signal's maximum magnitude is above the * reference maximum magnitude (minus tolerance). */ if (driven && (auptr->bdata[i].type == BAND_FUND)) { if (test_bandrms < threshold) { send_message(0, DEBUG+VERBOSE, er_fft, (auptr->bdata[i].type == BAND_FUND ? "Fundamental" : "Non-Fundamental"), auptr->bdata[i].start_freq, (auptr->bdata[i].end_freq == END_FREQ ? auptr->sample_rate/2 : auptr->bdata[i].end_freq), test_bandrms, ref_bandrms, threshold); free(testmag); TRACE_OUT return(FALSE); } else { send_message(0, DEBUG, fft_msg, (auptr->bdata[i].type == BAND_FUND ? "Fundamental" : "Non-Fundamental"), auptr->bdata[i].start_freq, (auptr->bdata[i].end_freq == END_FREQ ? auptr->sample_rate/2 : auptr->bdata[i].end_freq), test_bandrms, ref_bandrms, threshold); } } /* * Otherwise, this is not the fundamental band (or there's * no signal driven) so make sure the test signal's maximum * magnitude is below the reference maximum magnitude * (plus tolerance). */ else { /* * Use the greater of (fundamental RMS - bandrms_tol) * or the previously calculated threshold as the * actual threshold. */ if (threshold < alt_threshold) { threshold = alt_threshold; send_message(0, DEBUG, altth_msg); } if (test_bandrms > threshold) { send_message(0, DEBUG+VERBOSE, er_fft, (auptr->bdata[i].type == BAND_FUND ? "Fundamental" : "Non-Fundamental"), auptr->bdata[i].start_freq, (auptr->bdata[i].end_freq == END_FREQ ? auptr->sample_rate/2 : auptr->bdata[i].end_freq), test_bandrms, ref_bandrms, threshold); free(testmag); TRACE_OUT return(FALSE); } else { send_message(0, DEBUG, fft_msg, (auptr->bdata[i].type == BAND_FUND ? "Fundamental" : "Non-Fundamental"), auptr->bdata[i].start_freq, (auptr->bdata[i].end_freq == END_FREQ ? auptr->sample_rate/2 : auptr->bdata[i].end_freq), test_bandrms, ref_bandrms, threshold); } } } free(testmag); TRACE_OUT return(TRUE);}/* * returns whether or not a signal is clipped. A signal is * considered clipped if any sample is at max. Signal passed in * are expected to be 16 bit PCM but may have been converted from * other encodings. The max value will vary depending upon the * signal original encoding. */intclipchk(sigptr, sample_cnt, encoding)short *sigptr;int sample_cnt;int encoding;{ int i, max; func_name = "clipchk"; TRACE_IN switch (encoding) { case AUDIO_ENCODING_ALAW: max = MAXALAW; break; case AUDIO_ENCODING_ULAW: max = MAXULAW; break; case AUDIO_ENCODING_LINEAR: max = MAXPCM; break; default: send_message(ERAUDIO, ERROR, er_encoding); break; } for (i = 0; i < sample_cnt; sigptr++, i++) { if (abs((int) *sigptr) >= max) { TRACE_OUT return(TRUE); } } TRACE_OUT return(FALSE);}/* * returns whether or not a signal is clipped. */intisclipped(sigptr, sample_cnt, auptr)short *sigptr;int sample_cnt;au_data_t *auptr;{ int i; short *lsig, *rsig; func_name = "st_isclipped"; TRACE_IN if (auptr->channels == MONO) { if (clipchk(sigptr, sample_cnt, auptr->encoding) == TRUE) { send_message(0, DEBUG, clip_msg); TRACE_OUT return(TRUE); } } else { splitstereo(&lsig, &rsig, sigptr, sample_cnt); if (clipchk(lsig, sample_cnt/2, auptr->encoding) == TRUE) { send_message(0, DEBUG, lclip_msg); free(lsig); TRACE_OUT return(TRUE); } free(lsig); if (clipchk(rsig, sample_cnt/2, auptr->encoding) == TRUE) { send_message(0, DEBUG, rclip_msg); free(rsig); TRACE_OUT return(TRUE); } free(rsig); } TRACE_OUT return(FALSE);}/* * Calculate interval in usec. */longintervalcalc(btp, etp)struct timeval *btp, *etp;{ long seconds, useconds; func_name = "intervalcalc"; TRACE_IN seconds = etp->tv_sec - btp->tv_sec; useconds = etp->tv_usec - btp->tv_usec; TRACE_OUT return (seconds*1000000+useconds);}/* * Loopback open. Open audio device for write/read (play/record), * pause the play and record, flush the record and setinfo. */voidloopback_open(info)audio_info_t *info;{ audio_info_t pinfo; func_name = "loopback_open"; TRACE_IN /* * open audio device */ if ((audiofd = open(device_name, O_RDWR|O_NDELAY)) < 0) { send_message(ERSYS, ERROR, er_open, device_name, SYSMSG); } /* * pause play and record */ AUDIO_INITINFO(&pinfo); pinfo.record.pause = 1; pinfo.play.pause = 1; if (ioctl(audiofd, AUDIO_SETINFO, &pinfo) < 0) { send_message(ERSYS, ERROR, er_ioctl, "AUDIO_SETINFO", SYSMSG); } /* * set info and flush */ if (ioctl(audiofd, AUDIO_SETINFO, info) < 0) { send_message(ERSYS, ERROR, er_ioctl, "AUDIO_SETINFO", SYSMSG); } if (ioctl(audiofd, I_FLUSH, FLUSHRW) < 0) { send_message(ERSYS, ERROR, er_ioctl, "I_FLUSH", SYSMSG); } TRACE_OUT}/* * Play open. Open audio device for write (play), pause, * flush and setinfo. */voidplay_open(info)audio_info_t *info;{ audio_info_t pinfo; func_name = "play_open"; TRACE_IN /* * open audio device */ if ((audiofd = open(device_name, O_WRONLY|O_NDELAY)) < 0) { send_message(ERSYS, ERROR, er_open, device_name, SYSMSG); } /* * pause play */ AUDIO_INITINFO(&pinfo); pinfo.play.pause = 1; if (ioctl(audiofd, AUDIO_SETINFO, &pinfo) < 0) { send_message(ERSYS, ERROR, er_ioctl, "AUDIO_SETINFO", SYSMSG); } /* * set info and flush */ if (ioctl(audiofd, AUDIO_SETINFO, info) < 0) { send_message(ERSYS, ERROR, er_ioctl, "AUDIO_SETINFO", SYSMSG); } if (ioctl(audiofd, I_FLUSH, FLUSHW) < 0) { send_message(ERSYS, ERROR, er_ioctl, "I_FLUSH", SYSMSG); } TRACE_OUT}/* * Do a DBRI GETINFO ioctl and print results. */print_auinfo(){ int fd; audio_info_t info; if (ioctl(audioctlfd, AUDIO_GETINFO, &info) < 0) { send_message(ERSYS, ERROR, er_ioctl, "AUDIO_GETINFO", SYSMSG); } send_message(0, DEBUG, "info.play.sample_rate = %d", info.play.sample_rate); send_message(0, DEBUG, "info.play.channels = %d", info.play.channels); send_message(0, DEBUG, "info.play.precision = %d", info.play.precision); send_message(0, DEBUG, "info.play.encoding = %d", info.play.encoding); send_message(0, DEBUG, "info.play.gain = %d", info.play.gain); send_message(0, DEBUG, "info.play.port = %d", info.play.port); send_message(0, DEBUG, "info.play.avail_ports = %d", info.play.avail_ports); send_message(0, DEBUG, "info.play.samples = %d", info.play.samples); send_message(0, DEBUG, "info.play.eof = %d", info.play.eof); send_message(0, DEBUG, "info.play.pause = %d", info.play.pause); send_message(0, DEBUG, "info.play.error = %d", info.play.error); send_message(0, DEBUG, "info.play.waiting = %d", info.play.waiting); send_message(0, DEBUG, "info.play.minordev = %d", info.play.minordev); send_message(0, DEBUG, "info.play.open = %d", info.play.open); send_message(0, DEBUG, "info.play.active = %d", info.play.active); send_message(0, DEBUG, "\ninfo.record.sample_rate = %d", info.record.sample_rate); send_message(0, DEBUG, "info.record.channels = %d", info.record.channels); send_message(0, DEBUG, "info.record.precision = %d", info.record.precision); send_message(0, DEBUG, "info.record.encoding = %d", info.record.encoding); send_message(0, DEBUG, "info.record.gain = %d", info.record.gain); send_message(0, DEBUG, "info.record.port = %d", info.record.port); send_message(0, DEBUG, "info.record.avail_ports = %d", info.record.avail_ports); send_message(0, DEBUG, "info.record.samples = %d", info.record.samples); send_message(0, DEBUG, "info.record.eof = %d", info.record.eof); send_message(0, DEBUG, "info.record.pause = %d", info.record.pause); send_message(0, DEBUG, "info.record.error = %d", info.record.error); send_message(0, DEBUG, "info.record.waiting = %d", info.record.waiting); send_message(0, DEBUG, "info.record.minordev = %d", info.record.minordev); send_message(0, DEBUG, "info.record.open = %d", info.record.open); send_message(0, DEBUG, "info.record.active = %d", info.record.active); send_message(0, DEBUG, "\ninfo.monitor_gain = %d", info.monitor_gain); send_message(0, DEBUG, "info.speaker_muted = %d", info.speaker_muted);}/* * Dump signal to file, used for debug. */intdump_sig(sigptr, sample_cnt, fname)short *sigptr;int sample_cnt;char *fname;{ int i, fd; short *writeptr; func_name = "dump_sig"; TRACE_IN /* * open the file */ if ((fd = open(fname, O_CREAT | O_RDWR | O_TRUNC, 0666)) == -1 ) { send_message(ERSYS, ERROR, er_open, fname, SYSMSG); } /* * map the file */ if (ftruncate(fd, sizeof(short) * sample_cnt) == -1 ) { send_message(ERSYS, ERROR, er_truncate, SYSMSG); } if ((writeptr = (short *) mmap ((caddr_t) 0, sizeof(short) * sample_cnt, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, (off_t) 0)) == (short *)-1 ) { send_message(ERSYS, ERROR, er_mmap, SYSMSG); } close(fd); for (i = 0; i < sample_cnt; i++) { *writeptr++ = *sigptr++; } send_message(0, DEBUG, dump_msg, fname); (void) munmap(writeptr, sample_cnt); TRACE_OUT}/* * Create a filename - used for dumping audio files. */static char fname[256];char *aufname(bn, auptr)char *bn;au_data_t *auptr;{ sprintf(fname, "%s-%d-%d-%d-%d-%s.sig", bn, auptr->sample_rate, auptr->lfreq, auptr->rfreq, auptr->channels, encodestr[auptr->encoding]); return(fname);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -