/* ---------------------------------------------------------------------------- */ ringb_t * ringb_create(size_t sz2) { ringb_t *rb = (ringb_t *) safealloc(1, sizeof(ringb_t), "Ring creation"); rb->buf = safealloc(1, sz2, "Ring buffer buf"); rb->size = sz2; // power-of-2-sized rb->mask = rb->size - 1; rb->wptr = rb->rptr = 0; return rb; }
/* ---------------------------------------------------------------------------- */ ringb_float_t * ringb_float_create(size_t sz2) { ringb_float_t *rb = (ringb_float_t *) safealloc(1, sizeof(ringb_float_t), "Float Ring creation"); rb->buf = (float *) safealloc(1, sz2 * sizeof(float), "Ring buffer float buf"); rb->size = sz2; // power-of-2-sized rb->mask = rb->size - 1; rb->wptr = rb->rptr = 0; return rb; }
DttSP_EXP void *NewCriticalSection() { LPCRITICAL_SECTION cs_ptr; cs_ptr = (LPCRITICAL_SECTION)safealloc(1,sizeof(CRITICAL_SECTION),"Critical Section"); return (void *)cs_ptr; }
CWToneGen newCWToneGen ( REAL gain, // dB REAL freq, // ms REAL rise, // ms REAL fall, // ms int size, // samples REAL samplerate) // samples/sec { CWToneGen cwt = (CWToneGen) safealloc (1, sizeof (CWToneGenDesc), "CWToneGenDesc"); setCWToneGenVals (cwt, gain, freq, rise, fall); cwt->size = size; cwt->sr = samplerate; cwt->osc.gen = newOSC (cwt->size, ComplexTone, (double) cwt->osc.freq, 0.0, cwt->sr, "CWTone osc"); // overload oscillator buf cwt->buf = newCXB (cwt->size, OSCCbase (cwt->osc.gen), "CWToneGen buf"); return cwt; }
IQ newCorrectIQ (REAL phase, REAL gain, REAL mu) { IQ iq = (IQ) safealloc (1, sizeof (iqstate), "IQ state"); iq->phase = phase; iq->gain = gain; iq->mu = mu; iq->leakage = 0.000000f; iq->MASK=15; iq->index=0; iq->w = (COMPLEX *)safealloc(16,sizeof(COMPLEX),"correctIQ w"); iq->y = (COMPLEX *)safealloc(16,sizeof(COMPLEX),"correctIQ y"); iq->del = (COMPLEX *)safealloc(16,sizeof(COMPLEX),"correctIQ del"); memset((void *)iq->w,0,16*sizeof(COMPLEX)); return iq; }
static int swapsystem(char *cmd) { char *prog, *args; int retcode; for (; elvspace(*cmd); cmd++) { } prog = safedup(cmd); for (args = prog; *args && !elvspace(*args); args++) { } if (*args) *args++ = '\0'; retcode = do_exec(prog, args, USE_ALL|HIDE_FILE, 0xFFFF, NULL); if (retcode == RC_NOFILE) { safefree(prog); prog = safealloc(strlen(cmd) + 4, sizeof(char)); strcpy(prog, "/c "); strcat(prog, cmd); retcode = do_exec(tochar8(o_shell), prog, USE_ALL|HIDE_FILE, 0xFFFF, NULL); } safefree(prog); return retcode; }
PRIVATE void setup_local_audio (unsigned int thread) { top[thread].hold.size.frames = uni[thread].buflen; top[thread].hold.size.bytes = top[thread].hold.size.frames * sizeof (float); top[thread].hold.buf.l = (float *) safealloc (top[thread].hold.size.frames, sizeof (float), "main hold buffer left"); top[thread].hold.buf.r = (float *) safealloc (top[thread].hold.size.frames, sizeof (float), "main hold buffer right"); top[thread].hold.aux.l = (float *) safealloc (top[thread].hold.size.frames, sizeof (float), "aux hold buffer left"); top[thread].hold.aux.r = (float *) safealloc (top[thread].hold.size.frames, sizeof (float), "aux hold buffer right"); }
DTTSPAGC newDttSPAgc (AGCMODE mode, COMPLEX * Vec, int BufSize, REAL Limit, REAL attack, REAL decay, REAL slope, REAL hangtime, REAL samprate, REAL MaxGain, REAL MinGain, REAL CurGain, char *tag) { DTTSPAGC a; a = (DTTSPAGC) safealloc (1, sizeof (dttspagc), tag); a->mode = mode; a->attack = (REAL) (1.0 - exp (-1000.0 / (attack * samprate))); a->one_m_attack = (REAL) exp (-1000.0 / (attack * samprate)); a->decay = (REAL) (1.0 - exp (-1000.0 / (decay * samprate))); a->one_m_decay = (REAL) exp (-1000.0 / (decay * samprate)); a->fastattack = (REAL) (1.0 - exp (-1000.0 / (0.2 * samprate))); a->one_m_fastattack = (REAL) exp (-1000.0 / (0.2 * samprate)); a->fastdecay = (REAL) (1.0 - exp (-1000.0 / (3.0 * samprate))); a->one_m_fastdecay = (REAL) exp (-1000.0 / (3.0 * samprate)); strcpy (a->tag, tag); a->mask = 2 * BufSize; a->hangindex = a->indx = 0; a->hangtime = hangtime * 0.001f; a->hangthresh = 0.0; a->sndx = (int) (samprate * attack * 0.003f); a->fastindx = (int)(0.002f*samprate); a->gain.fix = 10.0; a->slope = slope; a->gain.top = MaxGain; a->hangthresh = a->gain.bottom = MinGain; a->gain.fastnow = a->gain.old = a->gain.now = CurGain; a->gain.limit = Limit; a->buff = newCXB (BufSize, Vec, "agc in buffer"); a->circ = newvec_COMPLEX (a->mask, "circular agc buffer"); a->mask -= 1; a->fasthang = 0; a->fasthangtime = 0.1f*a->hangtime; return a; }
newCorrectIQspec2 () { IQ iq = (IQ) safealloc (1, sizeof (iqstate), "IQ state"); int i; // SV1EIA AIR for ( i = 0; i < DEFSPEC; i++) // SV1EIA AIR { // SV1EIA AIR iq->phase[i] = 0.0; // SV1EIA AIR iq->gain[i] = 1.0; // SV1EIA AIR } // SV1EIA AIR return iq; }
IQ newCorrectIQ (REAL phase, REAL gain) { IQ iq = (IQ) safealloc (1, sizeof (iqstate), "IQ state"); int i; // SV1EIA AIR for ( i = 0; i < DEFSPEC; i++) // SV1EIA AIR { // SV1EIA AIR iq->phase[i] = phase; // SV1EIA AIR iq->gain[i] = gain; // SV1EIA AIR } // SV1EIA AIR return iq; }
/* This function creates a window */ static ELVBOOL vio_creategw (char *name, /* name of new window's buffer */ char *attributes) /* other window parameters, if any */ { VWIN *newp; /* if we don't have room for any more windows, then fail */ if (o_ttyrows / (nwindows + 1) < MINHEIGHT) { return ElvFalse; } /* create a window */ newp = safealloc (1, sizeof (VWIN)); /* initialize the window */ if (vwins) { newp->height = 0; newp->pos = o_ttyrows; } else { newp->height = o_ttyrows; newp->pos = 0; } newp->cursx = newp->cursy = 0; newp->shape = CURSOR_NONE; /* insert the new window into the list of windows */ newp->next = vwins; vwins = newp; nwindows++; /* adjust the heights of the other windows to make room for this one */ chgsize (newp, (int)(o_ttyrows / nwindows), ElvFalse); drawborder (newp); /* make elvis do its own initialization */ if (!eventcreate ((GUIWIN *)newp, NULL, name, newp->height, (int)o_ttycolumns)) { /* elvis can't make it -- fail */ safefree (newp); return ElvFalse; } /* make the new window be the current window */ current = newp; return ElvTrue; }
NB new_noiseblanker (CXB sigbuf, REAL threshold) { NB nb = (NB) safealloc (1, sizeof (nbstate), "new nbstate"); nb->sigbuf = sigbuf; nb->threshold = threshold; nb->average_mag = 1.0; nb->hangtime = 0; nb->sigindex = 0; nb->delayindex = 2; memset (nb->delay, 0, 8 * sizeof (COMPLEX)); return nb; }
DttSP_EXP ResStF newPolyPhaseFIRF (int filterMemoryBuffLength, int indexfiltMemBuf, int interpFactor, int filterPhaseNum, int deciFactor) { ResStF tmp; tmp = (ResStF) safealloc (1, sizeof (resamplerF), "PF Resampler"); tmp->indexfiltMemBuf = indexfiltMemBuf; tmp->interpFactor = interpFactor; tmp->filterPhaseNum = filterPhaseNum; tmp->deciFactor = deciFactor; tmp->numFiltTaps = 19839; tmp->filterMemoryBuffLength = nblock2 (max (filterMemoryBuffLength, tmp->numFiltTaps)); tmp->MASK = tmp->filterMemoryBuffLength - 1; tmp->filterMemoryBuff = (float *) safealloc (tmp->filterMemoryBuffLength, sizeof (REAL), "Filter buff: resampler"); tmp->filter = newFIR_Lowpass_REAL (0.45f, (REAL) interpFactor, tmp->numFiltTaps); return tmp; }
DttSP_EXP ResSt newPolyPhaseFIR (int filterMemoryBuffLength, int indexfiltMemBuf, int interpFactor, int filterPhaseNum, int deciFactor) { ResSt tmp; tmp = (ResSt) safealloc (1, sizeof (resampler), "PF Resampler"); tmp->indexfiltMemBuf = indexfiltMemBuf; tmp->interpFactor = interpFactor; tmp->filterPhaseNum = filterPhaseNum; tmp->deciFactor = deciFactor; tmp->numFiltTaps = 31 * deciFactor; tmp->filterMemoryBuffLength = nblock2 (max (filterMemoryBuffLength, tmp->numFiltTaps)); tmp->MASK = tmp->filterMemoryBuffLength - 1; tmp->filterMemoryBuff = (COMPLEX *) safealloc (tmp->filterMemoryBuffLength, sizeof (COMPLEX), "Filter buff: resampler"); tmp->filter = newFIR_Lowpass_REAL (0.45f / (REAL) deciFactor, (REAL) interpFactor, 31 * interpFactor); return tmp; }
void init_spectrum (SpecBlock * sb) { REAL phase_tmp = 0.0; REAL gain_tmp = 1.0; COMPLEX *p; sb->fill = 0; p = newvec_COMPLEX_fftw(sb->size*16,"spectrum accum"); sb->accum = newCXB (sb->size * 16, p, "spectrum accum"); p = newvec_COMPLEX_fftw(sb->size, "spectrum timebuf"); sb->timebuf = newCXB (sb->size, p, "spectrum timebuf"); p = newvec_COMPLEX_fftw(sb->size, "spectrum timebuf"); sb->freqbuf = newCXB (sb->size, p, "spectrum freqbuf"); sb->window = newvec_REAL (sb->size * 16, "spectrum window"); makewindow (BLACKMANHARRIS_WINDOW, sb->size, sb->window); sb->mask = sb->size - 1; sb->polyphase = FALSE; sb->output = (float *) safealloc (sb->size, sizeof (float), "spectrum output"); sb->coutput = (COMPLEX *)safealloc (sb->size, sizeof (COMPLEX), "spectrum output");; sb->plan = fftwf_plan_dft_1d (sb->size, (fftwf_complex *) CXBbase (sb->timebuf), (fftwf_complex *) CXBbase (sb->freqbuf), FFTW_FORWARD, sb->planbits); sb->iqfix = newCorrectIQspec2(); // SV1EIA AIR sb->iqfix->buffer_counter = 0; // SV1EIA AIR sb->iqfix->im_max_actual = 0; // SV1EIA AIR sb->iqfix->im_max_test = 0; // SV1EIA AIR sb->iqfix->im_min_actual = 0; // SV1EIA AIR sb->iqfix->im_min_test = 0; // SV1EIA AIR sb->iqfix->re_max_actual = 0; // SV1EIA AIR sb->iqfix->re_max_test = 0; // SV1EIA AIR sb->iqfix->re_min_actual = 0; // SV1EIA AIR sb->iqfix->re_min_test = 0; // SV1EIA AIR }
void init_spectrum (SpecBlock * sb) { COMPLEX *p; sb->fill = 0; p = newvec_COMPLEX_16(sb->size*16,"spectrum accum"); sb->accum = newCXB (sb->size * 16, p, "spectrum accum"); p = newvec_COMPLEX_16(sb->size, "spectrum timebuf"); sb->timebuf = newCXB (sb->size, p, "spectrum timebuf"); p = newvec_COMPLEX_16(sb->size, "spectrum timebuf"); sb->freqbuf = newCXB (sb->size, p, "spectrum freqbuf"); sb->window = newvec_REAL (sb->size * 16, "spectrum window"); makewindow (BLACKMANHARRIS_WINDOW, sb->size, sb->window); sb->mask = sb->size - 1; sb->polyphase = FALSE; sb->output = (float *) safealloc (sb->size, sizeof (float), "spectrum output"); sb->coutput = (COMPLEX *)safealloc (sb->size, sizeof (COMPLEX), "spectrum output");; sb->plan = fftwf_plan_dft_1d (sb->size, (fftwf_complex *) CXBbase (sb->timebuf), (fftwf_complex *) CXBbase (sb->freqbuf), FFTW_FORWARD, sb->planbits); }
WSCompander newWSCompander (int npts, REAL fac, CXB buff) { WSCompander wsc; wsc = (WSCompander) safealloc (1, sizeof (WSCompanderInfo), "WSCompander struct"); wsc->npts = npts; wsc->nend = npts - 1; wsc->tbl = newvec_REAL (npts, "WSCompander table"); wsc->buff = newCXB (CXBsize (buff), CXBbase (buff), "WSCompander buff"); WSCReset (wsc, fac); return wsc; }
CXB newCXB (int size, COMPLEX * base, char *tag) { CXB p = (CXB) safealloc (1, sizeof (CXBuffer), tag); if (base) { CXBbase (p) = base; CXBmine (p) = FALSE; } else { CXBbase (p) = newvec_COMPLEX (size, "newCXB"); CXBmine (p) = TRUE; } CXBsize (p) = CXBwant (p) = size; CXBovlp (p) = CXBhave (p) = CXBdone (p) = 0; return p; }
RLB newRLB (int size, REAL * base, char *tag) { RLB p = (RLB) safealloc (1, sizeof (RLBuffer), tag); if (base) { RLBbase (p) = base; RLBmine (p) = FALSE; } else { RLBbase (p) = newvec_REAL (size, "newRLB"); RLBmine (p) = TRUE; } RLBsize (p) = RLBwant (p) = size; RLBovlp (p) = RLBhave (p) = RLBdone (p) = 0; return p; }
BLMS new_blms (CXB signal, REAL adaptation_rate, REAL leak_rate, int filter_type, int pbits) { BLMS tmp; tmp = (BLMS) safealloc (1, sizeof (_blocklms), "block lms"); tmp->delay_line = newvec_COMPLEX (256, "block lms delay line"); tmp->y = newvec_COMPLEX (256, "block lms output signal"); tmp->Yhat = newvec_COMPLEX (256, "block lms output transform"); tmp->Errhat = newvec_COMPLEX (256, "block lms Error transform"); tmp->error = newvec_COMPLEX (256, "block lms Error signal"); tmp->Xhat = newvec_COMPLEX (256, "block lms signal transform"); tmp->What = newvec_COMPLEX (256, "block lms filter transform"); tmp->Update = newvec_COMPLEX (256, "block lms update transform"); tmp->update = newvec_COMPLEX (256, "block lms update signal"); tmp->adaptation_rate = adaptation_rate; tmp->leak_rate = 1.0f - leak_rate; tmp->signal = signal; tmp->filter_type = filter_type; tmp->Xplan = fftwf_plan_dft_1d (256, (fftwf_complex *) tmp->delay_line, (fftwf_complex *) tmp->Xhat, FFTW_FORWARD, pbits); tmp->Yplan = fftwf_plan_dft_1d (256, (fftwf_complex *) tmp->Yhat, (fftwf_complex *) tmp->y, FFTW_BACKWARD, pbits); tmp->Errhatplan = fftwf_plan_dft_1d (256, (fftwf_complex *) tmp->error, (fftwf_complex *) tmp->Errhat, FFTW_FORWARD, pbits); tmp->UPDplan = fftwf_plan_dft_1d (256, (fftwf_complex *) tmp->Errhat, (fftwf_complex *) tmp->update, FFTW_BACKWARD, pbits); tmp->Wplan = fftwf_plan_dft_1d (256, (fftwf_complex *) tmp->update, (fftwf_complex *) tmp->Update, FFTW_FORWARD, pbits); return tmp; }
char *strdup(const char *str) { # else /* don't USE_PROTOTYPES */ char *strdup(str) char *str; { # endif /* don't USE_PROTOTYPES */ char *ret; ret = (char *)safealloc(strlen(str) + 1, sizeof(char)); strcpy(ret, str); return ret; } #endif /* NEED_STRDUP */ #ifdef NEED_MEMMOVE # if USE_PROTOTYPES void *memmove(void *dest, const void *src, size_t size) # else /* don't USE_PROTOTYPES */ void *memmove(dest, src, size) void *dest; void *src; size_t size; # endif /* don't USE_PROTOTYPES */ { register char *d, *s; d = (char *)dest; s = (char *)src; if (d <= s) { for (; size > 0; size--) *d++ = *s++; } else { for (d += size, s += size; size > 0; size--) *--d = *--s; } return dest; }
AMD newAMD (REAL samprate, REAL f_initial, REAL f_lobound, REAL f_hibound, REAL f_bandwid, int size, COMPLEX * ivec, COMPLEX * ovec, AMMode mode, char *tag) { AMD am = (AMD) safealloc (1, sizeof (AMDDesc), tag); am->size = size; am->ibuf = newCXB (size, ivec, tag); am->obuf = newCXB (size, ovec, tag); am->mode = mode; init_pll (am, samprate, f_initial, f_lobound, f_hibound, f_bandwid); am->lock.curr = 0.5; am->lock.prev = 1.0; am->dc = 0.0; return am; }
LMSR new_lmsr (CXB signal, int delay, REAL adaptation_rate, REAL leakage, int adaptive_filter_size, int filter_type) { LMSR lms = (LMSR) safealloc (1, sizeof (_lmsstate), "new_lmsr state"); lms->signal = signal; lms->signal_size = CXBsize (lms->signal); lms->delay = delay; lms->size = 512; lms->mask = lms->size - 1; lms->delay_line = newvec_REAL (lms->size, "lmsr delay"); lms->adaptation_rate = adaptation_rate; lms->leakage = leakage; lms->adaptive_filter_size = adaptive_filter_size; lms->adaptive_filter = newvec_REAL (128, "lmsr filter"); lms->filter_type = filter_type; lms->delay_line_ptr = 0; return lms; }
/* ---------------------------------------------------------------------------- */ FMD newFMD(REAL samprate, REAL f_initial, REAL f_lobound, REAL f_hibound, REAL f_bandwid, int size, COMPLEX *ivec, COMPLEX *ovec, char *tag) { FMD fm = (FMD) safealloc(1, sizeof(FMDDesc), tag); fm->size = size; fm->ibuf = newCXB(size, ivec, tag); fm->obuf = newCXB(size, ovec, tag); init_pll(fm, samprate, f_initial, f_lobound, f_hibound, f_bandwid); fm->lock = 0.5; fm->afc = 0.0; fm->cvt = (REAL) (0.45 * samprate / (M_PI * f_bandwid)); return fm; }
SpotToneGen newSpotToneGen (REAL gain, // dB REAL freq, REAL rise, // ms REAL fall, // ms int size, REAL samplerate) { SpotToneGen st = (SpotToneGen) safealloc (1, sizeof (SpotToneGenDesc), "SpotToneGenDesc"); setSpotToneGenVals (st, gain, freq, rise, fall); st->size = size; st->sr = samplerate; st->osc.gen = newOSC (st->size, ComplexTone, st->osc.freq, 0.0, st->sr, "SpotTone osc"); // overload oscillator buf st->buf = newCXB (st->size, OSCCbase (st->osc.gen), "SpotToneGen buf"); return st; }
REAL * newvec_REAL (int size, char *tag) { return (REAL *) safealloc (size, sizeof (REAL), tag); }
/* Write one row of pixel values */ inline void write_one_line(pixel* line, int cols, FILE* outfile) { int i, index; unsigned int* maptable; /* No mapping tables used */ if(!(head_scan[0]->need_table)) if (bpp16==FALSE) { unsigned char* line8; line8 = (unsigned char*)safealloc(cols); for (i=0; i< cols; i++) *(line8+i)=(unsigned char)ENDIAN8(*(line+i)); fwrite(line8, sizeof(unsigned char), cols, outfile); free(line8); } else { fwrite(line, sizeof(short), cols, outfile); } /* Mapping tables used */ else { if (bpp16==FALSE) { /* Write one byte per table entry */ if (head_scan[0]->Wt == 1) { unsigned char* line8; line8 = (unsigned char*)safealloc(cols); /* If don't have 2, it mallocs over the table? */ maptable = head_scan[0]->TABLE[head_scan[0]->TID]; for (i=0; i<cols; i++) { index = *(line+i); *(line8+i) = ENDIAN8(maptable[index]); } fwrite(line8, sizeof(unsigned char), cols, outfile); free(line8); } /* Write two bytes per table entry */ else if (head_scan[0]->Wt == 2) { unsigned short* line16; line16 = (unsigned short*)safealloc(cols*2); maptable = head_scan[0]->TABLE[head_scan[0]->TID]; for (i=0; i<cols; i++) { index = *(line+i); *(line16+i) = (unsigned short) maptable[index]; } fwrite(line16, sizeof(short), cols, outfile); free(line16); } /* Write three bytes per table entry */ else if (head_scan[0]->Wt == 3) { unsigned char* line8_3; line8_3 = (unsigned char*)safealloc(cols*3); maptable = head_scan[0]->TABLE[head_scan[0]->TID]; for (i=0; i<cols; i++) { index = *(line+i); *(line8_3 + (i*3)) = (unsigned char) (maptable[index] >> 16); *(line8_3 + (i*3) + 1) = (unsigned char) (maptable[index] >> 8); *(line8_3 + (i*3) + 2) = (unsigned char) (maptable[index]); } fwrite(line8_3, sizeof(char), cols*3, outfile); free(line8_3); } /* Can't do 16 bit index values */ } else {
IMAG * newvec_IMAG (int size, char *tag) { return (IMAG *) safealloc (size, sizeof (IMAG), tag); }
COMPLEX * newvec_COMPLEX (int size, char *tag) { return (COMPLEX *) safealloc (size, sizeof (COMPLEX), tag); }
DTTSPAGC newDttSPAgc (AGCMODE mode, COMPLEX *Vec, int BufSize, // Size of the input buffer REAL target, // The target voltage REAL attack, // Attack time constant in msec REAL decay, // Decay time constant in msec REAL slope, // Rate of change of gain after agc threshold is exceeded REAL hangtime, // Hang Time in msec where NO decay is allowed in the agc REAL samprate, // Sample Rate so time can be turned into sample number REAL MaxGain, // Maximum allowable gain REAL MinGain, // Minimum gain (can be -dB / less than 1.0 as in ALC or strong signals on receive REAL CurGain, // The initial gain setting char *tag) // String to emit when error conditions occur { DTTSPAGC a; a = (DTTSPAGC) safealloc (1, sizeof (dttspagc), tag); a->mode = mode; // Attack: decrease gain when input signal will produce an output signal above the target voltage // Decay: increase gain when input signal will produce an output signal below the target voltage // Compute exponential attack rate per sample from attack time and sampler rate. a->attack = (REAL) (1.0 - exp (-1000.0 / (attack * samprate))); // Compute 1.0 - attack time. a->one_m_attack = (REAL) (1.0 - a->attack); // Compute exponential decay rate per sample from attack time and sampler rate. a->decay = (REAL) (1.0 - exp (-1000.0 / (decay * samprate))); // Compute 1.0 - decay time. a->one_m_decay = (REAL) (1.0 - a->decay); // Our system has a two track agc response. The normal one found in most receive // systems is the determined from the calculations we just made. // Ours has a fast track agc which is designed to prevent large pulse signals from pushing // us into serious attack and wait for a long decay when the signal is short duration < 3 time constants for attack // Compute exponential fast attack rate per sample from fast attack time and sampler rate. a->fastattack = (REAL) (1.0 - exp (-1000.0 / (0.2 * samprate))); // Compute 1.0 - fast attack time. a->one_m_fastattack = (REAL) (1.0 - a->fastattack); // Compute exponential fast decay rate per sample from fast attack time and sampler rate. a->fastdecay = (REAL) (1.0 - exp (-1000.0 / (3.0 * samprate))); // Compute 1.0 - fast decay time. a->one_m_fastdecay = (REAL) (1.0 - a->fastdecay); // Save the error identification message strcpy (a->tag, tag); // This computes the index max for our circular buffer a->mask = 2 * BufSize - 1; // Hangtime: This is a period of NO allowed decay even though we need to increase gain to stay at target level // hangindex is used to compute how deep into the hang interval we are. a->hangindex = a->slowindx = 0; // Change hang time to hang length in samples using time and sample rate. a->hangtime = hangtime * 0.001f; //a->hangthresh = 0.0; // not neccessary? // We BEGIN applying decreasing gain 3 time constants ahead of the signals arrival to narrow the modulation // spread arising from modulating the signal with the agc gain. The index to application of computed gain // sndx and it is computed as number of samples in 3 attack time constants a->out_indx = (int) (samprate * attack * 0.003f); // We do the same anticipation in the fast channel but we only do two time constants. a->fastindx = (int)(0.0027f*samprate); // see update.c:SetRAGC() a->gain.fix = 10000.0; // Slope: The rate at which gain is decreased as signal strength increases after it exceeds the agc threshold // that is, after the required gain to reach the desired output level is LESS THAN the maximum allowable gain. a->slope = slope; // gain.top = Maxgain which is the maximum allowable gain. This determines the agc threshold a->gain.top = MaxGain; // gain.bottom = MinGain is the minimum allowable gain. If < 0dB or 1.0, then this is an attenuation. a->hangthresh = a->gain.bottom = MinGain; // Initialize the gain state to an initial value a->gain.fastnow = a->gain.old = a->gain.now = CurGain; // Set the target voltage. a->gain.target = target; // Given the vector of input samples, make a local complex buffer (struct to handle metadata associated with // the vector or array of samples a->buff = newCXB (BufSize, Vec, "agc in buffer"); // Use a circular buffer for efficiency in dealing with the anticipatory part of the agc algorithm a->circ = newvec_COMPLEX (2 * BufSize, "circular agc buffer"); // intialize fast hang index to 0 a->fasthang = 0; // Whatever the hangtime is for the slow channel, make the fast agc channel hangtime 10% of it a->fasthangtime = 0.1f*a->hangtime; return a; }