コード例 #1
0
ファイル: af_silenceremove.c プロジェクト: markjreed/vice-emu
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
    AVFilterContext *ctx = inlink->dst;
    AVFilterLink *outlink = ctx->outputs[0];
    SilenceRemoveContext *s = ctx->priv;
    int i, j, threshold, ret = 0;
    int nbs, nb_samples_read, nb_samples_written;
    double *obuf, *ibuf = (double *)in->data[0];
    AVFrame *out;

    nb_samples_read = nb_samples_written = 0;

    switch (s->mode) {
    case SILENCE_TRIM:
silence_trim:
        nbs = in->nb_samples - nb_samples_read / inlink->channels;
        if (!nbs)
            break;

        for (i = 0; i < nbs; i++) {
            threshold = 0;
            for (j = 0; j < inlink->channels; j++) {
                threshold |= compute_rms(s, ibuf[j]) > s->start_threshold;
            }

            if (threshold) {
                for (j = 0; j < inlink->channels; j++) {
                    update_rms(s, *ibuf);
                    s->start_holdoff[s->start_holdoff_end++] = *ibuf++;
                    nb_samples_read++;
                }

                if (s->start_holdoff_end >= s->start_duration * inlink->channels) {
                    if (++s->start_found_periods >= s->start_periods) {
                        s->mode = SILENCE_TRIM_FLUSH;
                        goto silence_trim_flush;
                    }

                    s->start_holdoff_offset = 0;
                    s->start_holdoff_end = 0;
                }
            } else {
                s->start_holdoff_end = 0;

                for (j = 0; j < inlink->channels; j++)
                    update_rms(s, ibuf[j]);

                ibuf += inlink->channels;
                nb_samples_read += inlink->channels;
            }
        }
        break;

    case SILENCE_TRIM_FLUSH:
silence_trim_flush:
        nbs  = s->start_holdoff_end - s->start_holdoff_offset;
        nbs -= nbs % inlink->channels;
        if (!nbs)
            break;

        out = ff_get_audio_buffer(inlink, nbs / inlink->channels);
        if (!out) {
            av_frame_free(&in);
            return AVERROR(ENOMEM);
        }

        memcpy(out->data[0], &s->start_holdoff[s->start_holdoff_offset],
               nbs * sizeof(double));
        s->start_holdoff_offset += nbs;

        ret = ff_filter_frame(outlink, out);

        if (s->start_holdoff_offset == s->start_holdoff_end) {
            s->start_holdoff_offset = 0;
            s->start_holdoff_end = 0;
            s->mode = SILENCE_COPY;
            goto silence_copy;
        }
        break;

    case SILENCE_COPY:
silence_copy:
        nbs = in->nb_samples - nb_samples_read / inlink->channels;
        if (!nbs)
            break;

        out = ff_get_audio_buffer(inlink, nbs);
        if (!out) {
            av_frame_free(&in);
            return AVERROR(ENOMEM);
        }
        obuf = (double *)out->data[0];

        if (s->stop_periods) {
            for (i = 0; i < nbs; i++) {
                threshold = 1;
                for (j = 0; j < inlink->channels; j++)
                    threshold &= compute_rms(s, ibuf[j]) > s->stop_threshold;

                if (threshold && s->stop_holdoff_end && !s->leave_silence) {
                    s->mode = SILENCE_COPY_FLUSH;
                    flush(out, outlink, &nb_samples_written, &ret);
                    goto silence_copy_flush;
                } else if (threshold) {
                    for (j = 0; j < inlink->channels; j++) {
                        update_rms(s, *ibuf);
                        *obuf++ = *ibuf++;
                        nb_samples_read++;
                        nb_samples_written++;
                    }
                } else if (!threshold) {
                    for (j = 0; j < inlink->channels; j++) {
                        update_rms(s, *ibuf);
                        if (s->leave_silence) {
                            *obuf++ = *ibuf;
                            nb_samples_written++;
                        }

                        s->stop_holdoff[s->stop_holdoff_end++] = *ibuf++;
                        nb_samples_read++;
                    }

                    if (s->stop_holdoff_end >= s->stop_duration * inlink->channels) {
                        if (++s->stop_found_periods >= s->stop_periods) {
                            s->stop_holdoff_offset = 0;
                            s->stop_holdoff_end = 0;

                            if (!s->restart) {
                                s->mode = SILENCE_STOP;
                                flush(out, outlink, &nb_samples_written, &ret);
                                goto silence_stop;
                            } else {
                                s->stop_found_periods = 0;
                                s->start_found_periods = 0;
                                s->start_holdoff_offset = 0;
                                s->start_holdoff_end = 0;
                                clear_rms(s);
                                s->mode = SILENCE_TRIM;
                                flush(out, outlink, &nb_samples_written, &ret);
                                goto silence_trim;
                            }
                        }
                        s->mode = SILENCE_COPY_FLUSH;
                        flush(out, outlink, &nb_samples_written, &ret);
                        goto silence_copy_flush;
                    }
                }
            }
            flush(out, outlink, &nb_samples_written, &ret);
        } else {
            memcpy(obuf, ibuf, sizeof(double) * nbs * inlink->channels);
            ret = ff_filter_frame(outlink, out);
        }
        break;

    case SILENCE_COPY_FLUSH:
silence_copy_flush:
        nbs  = s->stop_holdoff_end - s->stop_holdoff_offset;
        nbs -= nbs % inlink->channels;
        if (!nbs)
            break;

        out = ff_get_audio_buffer(inlink, nbs / inlink->channels);
        if (!out) {
            av_frame_free(&in);
            return AVERROR(ENOMEM);
        }

        memcpy(out->data[0], &s->stop_holdoff[s->stop_holdoff_offset],
               nbs * sizeof(double));
        s->stop_holdoff_offset += nbs;

        ret = ff_filter_frame(outlink, out);

        if (s->stop_holdoff_offset == s->stop_holdoff_end) {
            s->stop_holdoff_offset = 0;
            s->stop_holdoff_end = 0;
            s->mode = SILENCE_COPY;
            goto silence_copy;
        }
        break;
    case SILENCE_STOP:
silence_stop:
        break;
    }

    av_frame_free(&in);

    return ret;
}
コード例 #2
0
ファイル: silence.c プロジェクト: CaptainHayashi/sox
/* Return number of samples processed in isamp and osamp. */
static int sox_silence_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sample_t *obuf,
                    size_t *isamp, size_t *osamp)
{
    priv_t * silence = (priv_t *) effp->priv;
    int threshold;
    size_t i, j;
    size_t nrOfTicks, /* sometimes wide, sometimes non-wide samples */
      nrOfInSamplesRead, nrOfOutSamplesWritten; /* non-wide samples */

    nrOfInSamplesRead = 0;
    nrOfOutSamplesWritten = 0;

    switch (silence->mode)
    {
        case SILENCE_TRIM:
            /* Reads and discards all input data until it detects a
             * sample that is above the specified threshold.  Turns on
             * copy mode when detected.
             * Need to make sure and copy input in groups of "channels" to
             * prevent getting buffers out of sync.
             * nrOfTicks counts wide samples here.
             */
silence_trim:
            nrOfTicks = min((*isamp-nrOfInSamplesRead),
                            (*osamp-nrOfOutSamplesWritten)) /
                           effp->in_signal.channels;
            for(i = 0; i < nrOfTicks; i++)
            {
                threshold = 0;
                for (j = 0; j < effp->in_signal.channels; j++)
                {
                    threshold |= aboveThreshold(effp,
                                                compute_rms(effp, ibuf[j]),
                                                silence->start_threshold,
                                                silence->start_unit);
                }

                if (threshold)
                {
                    /* Add to holdoff buffer */
                    for (j = 0; j < effp->in_signal.channels; j++)
                    {
                        update_rms(effp, *ibuf);
                        silence->start_holdoff[
                            silence->start_holdoff_end++] = *ibuf++;
                        nrOfInSamplesRead++;
                    }

                    if (silence->start_holdoff_end >=
                            silence->start_duration)
                    {
                        if (++silence->start_found_periods >=
                                silence->start_periods)
                        {
                            silence->mode = SILENCE_TRIM_FLUSH;
                            goto silence_trim_flush;
                        }
                        /* Trash holdoff buffer since its not
                         * needed.  Start looking again.
                         */
                        silence->start_holdoff_offset = 0;
                        silence->start_holdoff_end = 0;
                    }
                }
                else /* !above Threshold */
                {
                    silence->start_holdoff_end = 0;
                    for (j = 0; j < effp->in_signal.channels; j++)
                    {
                        update_rms(effp, ibuf[j]);
                    }
                    ibuf += effp->in_signal.channels;
                    nrOfInSamplesRead += effp->in_signal.channels;
                }
            } /* for nrOfTicks */
            break;

        case SILENCE_TRIM_FLUSH:
             /* nrOfTicks counts non-wide samples here. */
silence_trim_flush:
            nrOfTicks = min((silence->start_holdoff_end -
                             silence->start_holdoff_offset),
                             (*osamp-nrOfOutSamplesWritten));
            nrOfTicks -= nrOfTicks % effp->in_signal.channels;
            for(i = 0; i < nrOfTicks; i++)
            {
                *obuf++ = silence->start_holdoff[silence->start_holdoff_offset++];
                nrOfOutSamplesWritten++;
            }

            /* If fully drained holdoff then switch to copy mode */
            if (silence->start_holdoff_offset == silence->start_holdoff_end)
            {
                silence->start_holdoff_offset = 0;
                silence->start_holdoff_end = 0;
                silence->mode = SILENCE_COPY;
                goto silence_copy;
            }
            break;

        case SILENCE_COPY:
            /* Attempts to copy samples into output buffer.
             *
             * Case B:
             * If not looking for silence to terminate copy then
             * blindly copy data into output buffer.
             *
             * Case A:
             *
             * Case 1a:
             * If previous silence was detect then see if input sample is
             * above threshold.  If found then flush out hold off buffer
             * and copy over to output buffer.
             *
             * Case 1b:
             * If no previous silence detect then see if input sample
             * is above threshold.  If found then copy directly
             * to output buffer.
             *
             * Case 2:
             * If not above threshold then silence is detect so
             * store in hold off buffer and do not write to output
             * buffer.  Even though it wasn't put in output
             * buffer, inform user that input was consumed.
             *
             * If hold off buffer is full after this then stop
             * copying data and discard data in hold off buffer.
             *
             * Special leave_silence logic:
             *
             * During this mode, go ahead and copy input
             * samples to output buffer instead of holdoff buffer
             * Then also short ciruit any flushes that would occur
             * when non-silence is detect since samples were already
             * copied.  This has the effect of always leaving
             * holdoff[] amount of silence but deleting any
             * beyond that amount.
             *
             * nrOfTicks counts wide samples here.
             */
silence_copy:
            nrOfTicks = min((*isamp-nrOfInSamplesRead),
                            (*osamp-nrOfOutSamplesWritten)) /
                           effp->in_signal.channels;
            if (silence->stop)
            {
                /* Case A */
                for(i = 0; i < nrOfTicks; i++)
                {
                    threshold = 1;
                    for (j = 0; j < effp->in_signal.channels; j++)
                    {
                        threshold &= aboveThreshold(effp,
                                                    compute_rms(effp, ibuf[j]),
                                                    silence->stop_threshold,
                                                    silence->stop_unit);
                    }

                    /* Case 1a
                     * If above threshold, check to see if we where holding
                     * off previously.  If so then flush this buffer.
                     * We haven't incremented any pointers yet so nothing
                     * is lost.
                     *
                     * If user wants to leave_silence, then we
                     * were already copying the data and so no
                     * need to flush the old data.  Just resume
                     * copying as if we were not holding off.
                     */
                    if (threshold && silence->stop_holdoff_end
                        && !silence->leave_silence)
                    {
                        silence->mode = SILENCE_COPY_FLUSH;
                        goto silence_copy_flush;
                    }
                    /* Case 1b */
                    else if (threshold)
                    {
                        /* Not holding off so copy into output buffer */
                        for (j = 0; j < effp->in_signal.channels; j++)
                        {
                            update_rms(effp, *ibuf);
                            *obuf++ = *ibuf++;
                            nrOfInSamplesRead++;
                            nrOfOutSamplesWritten++;
                        }
                    }
                    /* Case 2 */
                    else if (!threshold)
                    {
                        /* Add to holdoff buffer */
                        for (j = 0; j < effp->in_signal.channels; j++)
                        {
                            update_rms(effp, *ibuf);
                            if (silence->leave_silence) {
                                *obuf++ = *ibuf;
                                nrOfOutSamplesWritten++;
                            }
                            silence->stop_holdoff[
                                silence->stop_holdoff_end++] = *ibuf++;
                            nrOfInSamplesRead++;
                        }

                        /* Check if holdoff buffer is greater than duration
                         */
                        if (silence->stop_holdoff_end >=
                                silence->stop_duration)
                        {
                            /* Increment found counter and see if this
                             * is the last period.  If so then exit.
                             */
                            if (++silence->stop_found_periods >=
                                    silence->stop_periods)
                            {
                                silence->stop_holdoff_offset = 0;
                                silence->stop_holdoff_end = 0;
                                if (!silence->restart)
                                {
                                    *isamp = nrOfInSamplesRead;
                                    *osamp = nrOfOutSamplesWritten;
                                    silence->mode = SILENCE_STOP;
                                    /* Return SOX_EOF since no more processing */
                                    return (SOX_EOF);
                                }
                                else
                                {
                                    silence->stop_found_periods = 0;
                                    silence->start_found_periods = 0;
                                    silence->start_holdoff_offset = 0;
                                    silence->start_holdoff_end = 0;
                                    clear_rms(effp);
                                    silence->mode = SILENCE_TRIM;

                                    goto silence_trim;
                                }
                            }
                            else
                            {
                                /* Flush this buffer and start
                                 * looking again.
                                 */
                                silence->mode = SILENCE_COPY_FLUSH;
                                goto silence_copy_flush;
                            }
                            break;
                        } /* Filled holdoff buffer */
                    } /* Detected silence */
                } /* For # of samples */
            } /* Trimming off backend */
            else /* !(silence->stop) */
            {
                /* Case B */
                memcpy(obuf, ibuf, sizeof(sox_sample_t)*nrOfTicks*
                                   effp->in_signal.channels);
                nrOfInSamplesRead += (nrOfTicks*effp->in_signal.channels);
                nrOfOutSamplesWritten += (nrOfTicks*effp->in_signal.channels);
            }
            break;

        case SILENCE_COPY_FLUSH:
             /* nrOfTicks counts non-wide samples here. */
silence_copy_flush:
            nrOfTicks = min((silence->stop_holdoff_end -
                                silence->stop_holdoff_offset),
                            (*osamp-nrOfOutSamplesWritten));
            nrOfTicks -= nrOfTicks % effp->in_signal.channels;

            for(i = 0; i < nrOfTicks; i++)
            {
                *obuf++ = silence->stop_holdoff[silence->stop_holdoff_offset++];
                nrOfOutSamplesWritten++;
            }

            /* If fully drained holdoff then return to copy mode */
            if (silence->stop_holdoff_offset == silence->stop_holdoff_end)
            {
                silence->stop_holdoff_offset = 0;
                silence->stop_holdoff_end = 0;
                silence->mode = SILENCE_COPY;
                goto silence_copy;
            }
            break;

        case SILENCE_STOP:
            /* This code can't be reached. */
            nrOfInSamplesRead = *isamp;
            break;
        }

        *isamp = nrOfInSamplesRead;
        *osamp = nrOfOutSamplesWritten;

        return (SOX_SUCCESS);
}
コード例 #3
0
ファイル: filters.c プロジェクト: BackupTheBerlios/semsivr
void comb_filter(
spx_sig_t *exc,          /*decoded excitation*/
spx_sig_t *new_exc,      /*enhanced excitation*/
spx_coef_t *ak,           /*LPC filter coefs*/
int p,               /*LPC order*/
int nsf,             /*sub-frame size*/
int pitch,           /*pitch period*/
spx_word16_t *pitch_gain,   /*pitch gain (3-tap)*/
spx_word16_t  comb_gain,    /*gain of comb filter*/
CombFilterMem *mem
)
{
   int i;
   spx_word16_t exc_energy=0, new_exc_energy=0;
   spx_word16_t gain;
   spx_word16_t step;
   spx_word16_t fact;

   /*Compute excitation amplitude prior to enhancement*/
   exc_energy = compute_rms(exc, nsf);
   /*for (i=0;i<nsf;i++)
     exc_energy+=((float)exc[i])*exc[i];*/

   /*Some gain adjustment if pitch is too high or if unvoiced*/
#ifdef FIXED_POINT
   {
      spx_word16_t g = gain_3tap_to_1tap(pitch_gain)+gain_3tap_to_1tap(mem->last_pitch_gain);
      if (g > 166)
         comb_gain = MULT16_16_Q15(DIV32_16(SHL(165,15),g), comb_gain);
      if (g < 64)
         comb_gain = MULT16_16_Q15(SHL(g, 9), comb_gain);
   }
#else
   {
      float g=0;
      g = GAIN_SCALING_1*.5*(gain_3tap_to_1tap(pitch_gain)+gain_3tap_to_1tap(mem->last_pitch_gain));
      if (g>1.3)
         comb_gain*=1.3/g;
      if (g<.5)
         comb_gain*=2.*g;
   }
#endif
   step = DIV32(COMB_STEP, nsf);
   fact=0;

   /*Apply pitch comb-filter (filter out noise between pitch harmonics)*/
   for (i=0;i<nsf;i++)
   {
      spx_word32_t exc1, exc2;

      fact += step;
      
      exc1 = SHL(MULT16_32_Q15(SHL(pitch_gain[0],7),exc[i-pitch+1]) +
                 MULT16_32_Q15(SHL(pitch_gain[1],7),exc[i-pitch]) +
                 MULT16_32_Q15(SHL(pitch_gain[2],7),exc[i-pitch-1]) , 2);
      exc2 = SHL(MULT16_32_Q15(SHL(mem->last_pitch_gain[0],7),exc[i-mem->last_pitch+1]) +
                 MULT16_32_Q15(SHL(mem->last_pitch_gain[1],7),exc[i-mem->last_pitch]) +
                 MULT16_32_Q15(SHL(mem->last_pitch_gain[2],7),exc[i-mem->last_pitch-1]),2);

      new_exc[i] = exc[i] + MULT16_32_Q15(comb_gain,MULT16_32_Q15(fact,exc1)  + MULT16_32_Q15(SUB16(COMB_STEP,fact), exc2));
   }

   mem->last_pitch_gain[0] = pitch_gain[0];
   mem->last_pitch_gain[1] = pitch_gain[1];
   mem->last_pitch_gain[2] = pitch_gain[2];
   mem->last_pitch = pitch;

   /*Amplitude after enhancement*/
   new_exc_energy = compute_rms(new_exc, nsf);

   if (exc_energy > new_exc_energy)
      exc_energy = new_exc_energy;
   
   gain = DIV32_16(SHL(exc_energy,15),1+new_exc_energy);

#ifdef FIXED_POINT
   if (gain < 16384)
      gain = 16384;
#else
   if (gain < .5)
      gain=.5;
#endif

#ifdef FIXED_POINT
   for (i=0;i<nsf;i++)
   {
      mem->smooth_gain = MULT16_16_Q15(31457,mem->smooth_gain) + MULT16_16_Q15(1311,gain);
      new_exc[i] = MULT16_32_Q15(mem->smooth_gain, new_exc[i]);
   }
#else
   for (i=0;i<nsf;i++)
   {
      mem->smooth_gain = .96*mem->smooth_gain + .04*gain;
      new_exc[i] *= mem->smooth_gain;
   }
#endif
}
コード例 #4
0
ファイル: Mtahspecbal.c プロジェクト: 1014511134/src
int main(int argc, char* argv[])
{
    int verbose;
    sf_file in=NULL, out=NULL;
    int n1_traces;
    int n1_headers;

    char* header_format=NULL;
    sf_datatype typehead;
    /* kls do I need to add this?  sf_datatype typein; */
    float* fheader=NULL;
    float* intrace=NULL;
    float* outtrace=NULL;
    float* bandlimittrace=NULL;
    float* rmsall=NULL;
    float* rmsband=NULL;
    float* scalars=NULL;
    float* sum_of_scalars=NULL;
    int indx_time;
    int itrace=0;
    int ntaper;
    int numxstart;
    int numtstart;
    float* taper;
    char **list_of_floats;
    float* xstart;
    float* tstart;
    int indx_of_offset;
    float offset;
    float d1;
    float o1;
    float time_start;
    int itime_start;
    int itime_stop;
    int indx_taper;
    float wagc;
    int lenagc;

    float fmin=5;
    float fmax=95;
    float finc=5;
    int num_centerfreq;
    int firstlive;
    int lastlive;
    float pnoise;

    kiss_fftr_cfg cfg,icfg;
    sf_complex *fft1;
    sf_complex *fft2;
    int nfft;
    int nf;
    float df;
    float scale;
    int ifreq;
    float cntrfreq;
    
    /*****************************/
    /* initialize verbose switch */
    /*****************************/
    sf_init (argc,argv);

    if(!sf_getint("verbose",&verbose))verbose=1;
    /* \n
       flag to control amount of print
       0 terse, 1 informative, 2 chatty, 3 debug
    */
    sf_warning("verbose=%d",verbose);
 
    /******************************************/
    /* input and output data are stdin/stdout */
    /******************************************/

    if(verbose>0)fprintf(stderr,"read in file name\n");  
    in = sf_input ("in");

    if(verbose>0)fprintf(stderr,"read out file name\n");
    out = sf_output ("out");

    if (!sf_histint(in,"n1_traces",&n1_traces))
	sf_error("input data not define n1_traces");
    if (!sf_histint(in,"n1_headers",&n1_headers)) 
	sf_error("input data does not define n1_headers");

    header_format=sf_histstring(in,"header_format");
    if(strcmp (header_format,"native_int")==0) typehead=SF_INT;
    else                                       typehead=SF_FLOAT;

    if(verbose>0)fprintf(stderr,"allocate headers.  n1_headers=%d\n",n1_headers);
    fheader = sf_floatalloc(n1_headers);
 
    /*  allocate intrace and outtrace after initialize fft and 
	make them padded */
  
    /* maybe I should add some validation that n1== n1_traces+n1_headers+2
       and the record length read in the second word is consistent with 
       n1.  */

    /**********************************************************/
    /* end code block for standard tah Trace And Header setup */
    /* continue with any sf_puthist this tah program calls to */
    /* add to the history file                                */
    /**********************************************************/

    /* put the history from the input file to the output */
    sf_fileflush(out,in);

    /********************************************************/
    /* continue initialization specific to this tah program */
    /********************************************************/





    /* segy_init gets the list header keys required by segykey function  */
    segy_init(n1_headers,in);

    if(0==1) {  
      /* infuture may want to have offset dependent agc design start time */
      /* get the mute parameters */
      if(NULL==(list_of_floats=sf_getnstring("xstart",&numxstart))){
	xstart=NULL;
	sf_error("xstart is a required parameter in sftahagc");
      } else {
	xstart=sf_floatalloc(numxstart);
	if(!sf_getfloats("xstart",xstart,numxstart))sf_error("unable to read xstart");
      }
      if(NULL==(list_of_floats=sf_getnstring("tstart",&numtstart))){
	tstart=NULL;
	sf_error("xstart is a required parameter in sftahagc");
      } else {
	tstart=sf_floatalloc(numtstart);
	if(!sf_getfloats("tstart",tstart,numtstart))sf_error("unable to read tstart");
      }
      if(numxstart!=numtstart)sf_error("bad mute parameters: numxstart!=numtstart");
      if(!sf_getint("ntaper",&ntaper))ntaper=12;
    }
    /* \n
       length of the taper on the stack mute
    */
    /* is this of use for agc?
    taper=sf_floatalloc(ntaper);
    for(indx_time=0; indx_time<ntaper; indx_time++){
	float val_sin=sin((indx_time+1)*SF_PI/(2*ntaper));
	taper[indx_time]=val_sin*val_sin;
    }
    */
    indx_of_offset=segykey("offset");
    
    if (!sf_histfloat(in,"d1",&d1))
      sf_error("input data does not define d1");
    if (!sf_histfloat(in,"o1",&o1))
      sf_error("input data does not define o1");

    /* check wagc for reasonableness.  I input 250 (not .25 and ,250) */  
    if(!sf_getfloat("wagc",&wagc))wagc=-1;
    /* \n
       length of the agc window in seconds
    */
    if(wagc<0)sf_error("wagc is a required parameter in sftahagc");

    lenagc=wagc/d1+1.5; /* length of the agc window in samples */
 
    if (!sf_getfloat("pnoise",  &pnoise)) pnoise = 0.01;
    /* relative additive noise level */
    
    if (!sf_getfloat("fmin",&fmin))fmin=5;
    /* minimum frequency band */
    if (!sf_getfloat("fmax",&fmax))fmax=95;
    /* maximum frequency band */
    if (!sf_getfloat("finc",&finc))finc=5;
    /* frequency band increment */

    /* initialize kiss_fft kls */

    nfft  = kiss_fft_next_fast_size(n1_traces+200);
    nf    = nfft/2+1;
    df    = 1./(nfft*d1);
    scale = 1./nfft;
    cfg   = kiss_fftr_alloc(nfft,0,NULL,NULL);
    icfg  = kiss_fftr_alloc(nfft,1,NULL,NULL);
    fft1  = sf_complexalloc(nf);
    fft2  = sf_complexalloc(nf);
    if(verbose>0)fprintf(stderr,"fmax=%f\n",(nf-1)*df);

    /* allocate input and output traces with enough padding for
       ffts */
    if(verbose>0)
      fprintf(stderr,"allocate padded intrace.  n1_traces=%d nfft=%d\n",
	                                        n1_traces,   nfft);
    intrace       =sf_floatalloc(nfft); /* must be padded for input to fft */
    bandlimittrace=sf_floatalloc(nfft); /* must be padded for input to fft */
    outtrace= sf_floatalloc(n1_traces);
    rmsall        =sf_floatalloc(n1_traces);
    rmsband        =sf_floatalloc(n1_traces);
    scalars       =sf_floatalloc(n1_traces);
    sum_of_scalars=sf_floatalloc(n1_traces);
    num_centerfreq=(fmax-fmin)/finc+1.95;
    if(fabs(fmax-(fmin+(num_centerfreq-1)*finc))>.01){
      fprintf(stderr,"*************************************\n");
      fprintf(stderr,"*************************************\n");
      fprintf(stderr,"*************************************\n");
      fprintf(stderr,"fmin-fmax is not a multiple of finc\n");
      fprintf(stderr,"fmin=%f, fmax=%f, finc=%f\n",fmin,fmax,finc);
      fprintf(stderr,"*************************************\n");
      fprintf(stderr,"*************************************\n");
      sf_error("illegal combination of fmin,fmax,fminc");
    }

    /***************************/
    /* start trace loop        */
    /***************************/
    if(verbose>0)fprintf(stderr,"start trace loop\n");
 
    itrace=0;
    while (!(get_tah(intrace, fheader, n1_traces, n1_headers, in))){
	if(verbose>1 || (verbose==1 && itrace<5)){
	    fprintf(stderr,"process tah %d in sftahagc\n",itrace);
	}
	/********************/
	/* process the tah. */
	/********************/

	if(typehead == SF_INT)offset=((int  *)fheader)[indx_of_offset];
	else                  offset=((float*)fheader)[indx_of_offset];
	/* maybe latter add agc design start time
	intlin(numxstart,xstart,tstart,
	       tstart[0],tstart[numxstart-1],1,
	       &offset,&time_start);
	if(time_start<o1)time_start=o1;

	itime_start=(int)(((time_start-o1)/d1)+.5);
	*/
	/* find firstlive and lastlive */
        if(verbose>2)fprintf(stderr,"find firstlive and lastlive\n");
	for (firstlive=0; firstlive<n1_traces; firstlive++){
	  if(intrace[firstlive] != 0) break;
	}
	for (lastlive=n1_traces-1;lastlive>=0; lastlive--){
	  if(intrace[lastlive] != 0) break;
	}
	/* kls need to catch a zero trace */
        if(verbose>2)
	  fprintf(stderr,"firstlive=%d, lastlive=%d\n",firstlive,lastlive);
	/* zero the padded area on the input trace */
	for (indx_time=n1_traces; indx_time<nfft; indx_time++){
	  intrace[indx_time]=0;
	}
	
	/********************************************************/
	/* apply the SPECtral BALancing:                        */
	/* 1 compute the input trace rms in agclen gates        */
	/* 2 fft to frequency domain                            */
	/* 3 for each frequency band                            */
	/*   3.1 extract (ramp) the frequency band              */
	/*   3.2 convert freqency band to time,                 */
	/*   3.3 compute the rms of the frequency band          */
	/*   3.4 agc scalars 1/(freq_band_rms + whitenoise*rms) */ 
	/*   3.3 agc the frequency band                         */
	/*   3.4 sum to output                                  */
        /*   3.5 sum scalars to sum of scalars                  */
	/* 4 divide by the sum of scalars                       */
	/********************************************************/
	compute_rms(intrace, rmsall,
		    lenagc, n1_traces,
                    firstlive, lastlive);
	/* scale rms by whitenoise factor */
	if(verbose>2)fprintf(stderr,"put_tah rmsall\n");
	if(0) put_tah(intrace, fheader, n1_traces, n1_headers, out);
        if(0) put_tah(rmsall, fheader, n1_traces, n1_headers, out);
	for (indx_time=0; indx_time<n1_traces; indx_time++){
	  rmsall[indx_time]*=(1.0/num_centerfreq);
	}

	if(verbose>2)fprintf(stderr,"fftr\n");
	kiss_fftr(cfg, intrace, (kiss_fft_cpx*) fft1);

	/* zero the output trace and the sum_of_scalars */
	for (indx_time=0; indx_time<n1_traces; indx_time++){
	  outtrace[indx_time]=0.0;
	  sum_of_scalars[indx_time]=0.0;
	}
	for (cntrfreq=fmin; cntrfreq<=fmax; cntrfreq+=finc){
	  if(verbose>2)fprintf(stderr,"cntrfreq=%f\n",cntrfreq);
          /* zero frequencies before the band */
	  for (ifreq=0; ifreq<(int)((cntrfreq-finc)/df); ifreq++){
	    fft2[ifreq]=0.0;
	  }
	  /* triangular weight the selected  frequency band */
	  for (ifreq=(int)((cntrfreq-finc)/df); 
	       ifreq<(int)((cntrfreq+finc)/df) && ifreq<nf;
	       ifreq++){
            float weight;
	    if(ifreq>0){
	      weight=(1.0-fabs(ifreq*df-cntrfreq)/finc)/nfft;
	      fft2[ifreq]=weight*fft1[ifreq];
	    }
	  }
          /* zero frequencies larger than the band */
	  for (ifreq=(int)((cntrfreq+finc)/df); ifreq<nf; ifreq++){
	    fft2[ifreq]=0.0;
	  } 
	  /* inverse fft back to time domain */
          if(verbose>2)fprintf(stderr,"fftri\n");
	  kiss_fftri(icfg,(kiss_fft_cpx*) fft2, bandlimittrace);
          /* apply agc to the bandlimittrace and sum scalars to 
             sum_of_scalars */
	  if(verbose>2)fprintf(stderr,"agc_apply\n");
	  compute_rms(bandlimittrace, rmsband,
		    lenagc, n1_traces,
                    firstlive, lastlive);
	  if(verbose>2)fprintf(stderr,"sum to ouput\n");
	  for (indx_time=0; indx_time<n1_traces; indx_time++){
	    /* old poor 
	       scalars[indx_time]=1.0/
                   (rmsband[indx_time]+pnoise*rmsall[indx_time]);
	    */
	    if(1)scalars[indx_time]=rmsband[indx_time]/
                     (rmsband[indx_time]*rmsband[indx_time]+
		      pnoise*rmsall[indx_time]*rmsall[indx_time]);
	    else scalars[indx_time]=1.0;
	  }
	  for (indx_time=0; indx_time<n1_traces; indx_time++){
	    bandlimittrace[indx_time]*=scalars[indx_time];
	    outtrace[indx_time]+=bandlimittrace[indx_time];
	  }
	  for (indx_time=0; indx_time<n1_traces; indx_time++){
	    sum_of_scalars[indx_time]+=scalars[indx_time];
	  }
          if(0)
	    put_tah(bandlimittrace, fheader, n1_traces, n1_headers, out);
	  if(0)
	    put_tah(rmsband, fheader, n1_traces, n1_headers, out);
	  if(0)
	    put_tah(scalars, fheader, n1_traces, n1_headers, out);
	}
        if(0)put_tah(sum_of_scalars, fheader, n1_traces, n1_headers, out);
        if(1){	
	   /* divide output by sum of scalars */
	  for (indx_time=0; indx_time<n1_traces; indx_time++){
	    outtrace[indx_time]/=sum_of_scalars[indx_time];
	  }
	} 
	if (1)
	  put_tah(outtrace, fheader, n1_traces, n1_headers, out);
	itrace++;
    }

    exit(0);
}
コード例 #5
0
ファイル: geomap.c プロジェクト: jhunkeler/stsci.stimage
/* DIFF: was gto_fit_rxyscale */
static int
geo_fit_linear(
        geomap_fit_t* const fit,
        surface_t* const sx1,
        surface_t* const sy1,
        const size_t ncoord,
        const coord_t* const input,
        const coord_t* const ref,
        const double* const weights,
        double* const residual_x,
        double* const residual_y,
        stimage_error_t* error) {

    bbox_t  bbox;
    double  sw      = 0.0;
    coord_t sr      = {0.0, 0.0};
    coord_t si      = {0.0, 0.0};
    coord_t r0      = {0.0, 0.0};
    coord_t i0      = {0.0, 0.0};
    double  sxrxr   = 0.0;
    double  syryr   = 0.0;
    double  syrxi   = 0.0;
    double  sxryi   = 0.0;
    double  sxrxi   = 0.0;
    double  syryi   = 0.0;
    double  num     = 0.0;
    double  denom   = 0.0;
    double  theta   = 0.0;
    double  ctheta  = 0.0;
    double  stheta  = 0.0;
    coord_t cthetac = {0.0, 0.0};
    coord_t sthetac = {0.0, 0.0};
    double  xmag    = 0.0;
    double  ymag    = 0.0;
    size_t  i       = 0;
    int     status  = 1;

    assert(fit);
    assert(sx1);
    assert(sy1);
    assert(input);
    assert(ref);
    assert(weights);
    assert(residual_x);
    assert(residual_y);

    surface_free(sx1);
    surface_free(sy1);

    bbox_copy(&fit->bbox, &bbox);
    bbox_make_nonsingular(&bbox);

    /* Compute the sums required to determine the offsets */
    compute_sums(ncoord, input, ref, weights, &sw, &si, &sr);

    if (sw < 3.0) {
        if (fit->projection == geomap_proj_none) {
            stimage_error_set_message(
                    error, "Too few data points for X and Y fits.");
        } else {
            stimage_error_set_message(
                    error, "Too few data points for XI and ETA fits.");
        }
        goto exit;
    }

    r0.x = sr.x / sw;
    r0.y = sr.y / sw;
    i0.x = si.x / sw;
    i0.y = si.y / sw;
    for (i = 0; i < ncoord; ++i) {
        sxrxr += weights[i] * (ref[i].x - r0.x) * (ref[i].x - r0.x);
        syryr += weights[i] * (ref[i].y - r0.y) * (ref[i].y - r0.y);
        syrxi += weights[i] * (ref[i].y - r0.y) * (input[i].x - i0.x);
        sxryi += weights[i] * (ref[i].x - r0.x) * (input[i].y - i0.y);
        sxrxi += weights[i] * (ref[i].x - r0.x) * (input[i].x - i0.x);
        syryi += weights[i] * (ref[i].y - r0.y) * (input[i].y - i0.y);
    }

    /* Compute the rotation angle */
    num = 2.0 * (sxrxr * syrxi * syryi - syryr * sxrxi * sxryi);
    denom = syryr * (sxrxi - sxryi) * (sxrxi + sxryi) - \
        sxrxr * (syrxi + syryi) * (syrxi - syryi);
    if (double_approx_equal(num, 0.0) && double_approx_equal(denom, 0.0)) {
        theta = 0.0;
    } else {
        theta = atan2(num, denom) / 2.0;
        if (theta < 0.0) {
            theta += M_PI * 2.0;
        }
    }

    ctheta = cos(theta);
    stheta = sin(theta);

    /* Compute the X magnification factor */
    num = sxrxi * ctheta - sxryi * stheta;
    denom = sxrxr;
    if (denom <= 0.0) {
        xmag = 1.0;
    } else {
        xmag = num / denom;
    }

    /* Compute the Y magnification factor */
    num = syrxi * stheta + syryi * ctheta;
    denom = syryr;
    if (denom <= 0.0) {
        ymag = 1.0;
    } else {
        ymag = num / denom;
    }

    /* Compute the polynomial coefficients */
    cthetac.x = xmag * ctheta;
    sthetac.x = ymag * stheta;
    sthetac.y = xmag * stheta;
    cthetac.x = ymag * ctheta;

    /* Compute the X and Y fit coefficients */
    if (compute_surface_coefficients(
                fit->function, &bbox, &i0, &r0, &cthetac, &sthetac, sx1, sy1,
                error)) goto exit;

    /* Compute the residuals */
    if (compute_residuals(
                sx1, sy1, ncoord, input, ref, residual_x, residual_y,
                error)) goto exit;

    /* Compute the number of zero-weighted points */
    fit->n_zero_weighted = count_zero_weighted(ncoord, weights);

    /* Compute the rms of the x and y fits */
    compute_rms(
            ncoord, weights, residual_x, residual_y, &fit->xrms, &fit->yrms);

    fit->ncoord = ncoord;

    status = 0;

 exit:

    return status;
}
コード例 #6
0
ファイル: geomap.c プロジェクト: jhunkeler/stsci.stimage
/* DIFF: was geo_mrejectd */
static int
geo_fit_reject(
        geomap_fit_t* const fit,
        surface_t* const sx1,
        surface_t* const sy1,
        surface_t* const sx2,
        surface_t* const sy2,
        int* const has_sx2,
        int* const has_sy2,
        const size_t ncoord,
        const coord_t* const input,
        const coord_t* const ref,
        const double* const weights,
        double* const residual_x,
        double* const residual_y,
        stimage_error_t* error) {

    double* tweights = NULL;
    size_t  nreject  = 0;
    size_t  niter    = 0;
    double  cutx     = 0.0;
    double  cuty     = 0.0;
    size_t  i        = 0;
    int     status   = 1;

    assert(fit);
    assert(sx1);
    assert(sy1);
    assert(sx2);
    assert(sy2);
    assert(input);
    assert(ref);
    assert(weights);
    assert(residual_x);
    assert(residual_y);
    assert(error);

    tweights = malloc_with_error(ncoord * sizeof(double), error);
    if (tweights == NULL) goto exit;

    if (fit->rej != NULL) {
        free(fit->rej);
    }
    fit->rej = malloc_with_error(ncoord * sizeof(int), error);
    if (fit->rej == NULL) goto exit;

    fit->nreject = 0;

    /* Initialize the temporary weights array and the number of
       rejected points */
    for (i = 0; i < ncoord; ++i) {
        tweights[i] = weights[i];
    }

    do { /* while (niter < fit->maxiter) */
        /* Compute the rejection limits */
        if (ncoord - fit->n_zero_weighted > 1) {
            cutx = fit->reject * \
                sqrt(fit->xrms / (double)(ncoord - fit->n_zero_weighted - 1));
            cuty = fit->reject * \
                sqrt(fit->yrms / (double)(ncoord - fit->n_zero_weighted - 1));
        } else {
            cutx = MAX_DOUBLE;
            cuty = MAX_DOUBLE;
        }

        /* Reject points from the fit */
        for (i = 0; i < ncoord; ++i) {
            if (tweights[i] > 0.0 &&
                ((abs(residual_x[i]) > cutx) || abs(residual_y[i]) > cuty)) {
                tweights[i] = 0.0;
                ++nreject;
                assert(nreject < ncoord);
                fit->rej[nreject] = i;
            }
        }

        if ((long)nreject - (long)fit->nreject <= 0) {
            break;
        }
        fit->nreject = nreject;

        /* Compute the number of deleted points */
        fit->n_zero_weighted = count_zero_weighted(ncoord, weights);

        /* Recompute the X and Y fit */
        switch (fit->fit_geometry) {
        case geomap_fit_rotate:
            if (geo_fit_theta(
                        fit, sx1, sy1, ncoord, input, ref, tweights,
                        residual_x, residual_y, error)) goto exit;
            break;
        case geomap_fit_rscale:
            if (geo_fit_magnify(
                        fit, sx1, sy1, ncoord, input, ref, tweights,
                        residual_x, residual_y, error)) goto exit;
            break;
        case geomap_fit_rxyscale:
            if (geo_fit_linear(
                        fit, sx1, sy1, ncoord, input, ref, tweights,
                        residual_x, residual_y, error)) goto exit;
            break;
        default:
            if (geo_fit_xy(
                        fit, sx1, sx2, ncoord, 1, input, ref, has_sx2, tweights,
                        residual_x, error) ||
                geo_fit_xy(
                        fit, sy1, sy2, ncoord, 0, input, ref, has_sy2, tweights,
                        residual_y, error)) goto exit;
            break;
        }

        /* Compute the X and Y fit rms */
        compute_rms(
                ncoord, tweights, residual_x, residual_y,
                &fit->xrms, &fit->yrms);

        ++niter;
    } while (niter < fit->maxiter);

    status = 0;

 exit:

    free(tweights);

    return status;
}