static int process_callback(jack_nframes_t nframes, void *arg) { /* Warning: this function runs in realtime. One mustn't allocate memory here * or do any other thing that could block. */ int i, j; JackData *self = arg; float * buffer; jack_nframes_t latency, cycle_delay; AVPacket pkt; float *pkt_data; double cycle_time; if (!self->client) return 0; /* The approximate delay since the hardware interrupt as a number of frames */ cycle_delay = jack_frames_since_cycle_start(self->client); /* Retrieve filtered cycle time */ cycle_time = ff_timefilter_update(self->timefilter, av_gettime() / 1000000.0 - (double) cycle_delay / self->sample_rate, self->buffer_size); /* Check if an empty packet is available, and if there's enough space to send it back once filled */ if ((av_fifo_size(self->new_pkts) < sizeof(pkt)) || (av_fifo_space(self->filled_pkts) < sizeof(pkt))) { self->pkt_xrun = 1; return 0; } /* Retrieve empty (but allocated) packet */ av_fifo_generic_read(self->new_pkts, &pkt, sizeof(pkt), NULL); pkt_data = (float *) pkt.data; latency = 0; /* Copy and interleave audio data from the JACK buffer into the packet */ for (i = 0; i < self->nports; i++) { latency += jack_port_get_total_latency(self->client, self->ports[i]); buffer = jack_port_get_buffer(self->ports[i], self->buffer_size); for (j = 0; j < self->buffer_size; j++) pkt_data[j * self->nports + i] = buffer[j]; } /* Timestamp the packet with the cycle start time minus the average latency */ pkt.pts = (cycle_time - (double) latency / (self->nports * self->sample_rate)) * 1000000.0; /* Send the now filled packet back, and increase packet counter */ av_fifo_generic_write(self->filled_pkts, &pkt, sizeof(pkt), NULL); sem_post(&self->packet_count); return 0; }
static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) { AlsaData *s = s1->priv_data; int res; int64_t dts; snd_pcm_sframes_t delay = 0; if (av_new_packet(pkt, s->period_size * s->frame_size) < 0) { return AVERROR(EIO); } while ((res = snd_pcm_readi(s->h, pkt->data, s->period_size)) < 0) { if (res == -EAGAIN) { av_packet_unref(pkt); return AVERROR(EAGAIN); } if (ff_alsa_xrun_recover(s1, res) < 0) { av_log(s1, AV_LOG_ERROR, "ALSA read error: %s\n", snd_strerror(res)); av_packet_unref(pkt); return AVERROR(EIO); } ff_timefilter_reset(s->timefilter); } dts = av_gettime(); snd_pcm_delay(s->h, &delay); dts -= av_rescale(delay + res, 1000000, s->sample_rate); pkt->pts = ff_timefilter_update(s->timefilter, dts, s->last_period); s->last_period = res; pkt->size = res * s->frame_size; return 0; }
int main(void) { AVLFG prng; double n0,n1; #define SAMPLES 1000 double ideal[SAMPLES]; double samples[SAMPLES]; #if 1 for(n0= 0; n0<40; n0=2*n0+1){ for(n1= 0; n1<10; n1=2*n1+1){ #else {{ n0=7; n1=1; #endif double best_error= 1000000000; double bestpar0=1; double bestpar1=0.001; int better, i; av_lfg_init(&prng, 123); for(i=0; i<SAMPLES; i++){ ideal[i] = 10 + i + n1*i/(1000); samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2) / (LFG_MAX * 10LL); } do{ double par0, par1; better=0; for(par0= bestpar0*0.8; par0<=bestpar0*1.21; par0+=bestpar0*0.05){ for(par1= bestpar1*0.8; par1<=bestpar1*1.21; par1+=bestpar1*0.05){ double error=0; TimeFilter *tf= ff_timefilter_new(1, par0, par1); for(i=0; i<SAMPLES; i++){ double filtered; filtered= ff_timefilter_update(tf, samples[i], 1); error += (filtered - ideal[i]) * (filtered - ideal[i]); } ff_timefilter_destroy(tf); if(error < best_error){ best_error= error; bestpar0= par0; bestpar1= par1; better=1; } } } }while(better); #if 0 double lastfil=9; TimeFilter *tf= ff_timefilter_new(1, bestpar0, bestpar1); for(i=0; i<SAMPLES; i++){ double filtered; filtered= ff_timefilter_update(tf, samples[i], 1); printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i], samples[FFMAX(i, 1)] - samples[FFMAX(i-1, 0)], filtered - lastfil); lastfil= filtered; } ff_timefilter_destroy(tf); #else printf(" [%f %f %9f]", bestpar0, bestpar1, best_error); #endif } printf("\n"); } return 0; }