beim heutigen Updaten auf die neuere Version von resample_soxr (mit "--precision" Option) bin ich wieder über meine lokalen Änderungen an playhrt gestolpert. Das patch regelt die Variable extra_bps nach, um eine schwankende Clock auszugleichen. In meinen Setup funktioniert playhrt ansonsten nicht (siehe auch meine vorherigen Beiträge hier im Thread). Ich poste den Code hier unaufgeräumt und ohne Garantie. Vielleicht hat jemand ähnliche Probleme.
Code: Alles auswählen
diff frank_l-frankl_stereo-5321f33866ac/src/playhrt.c frankl_stereo_0.8.2/src/playhrt.c
34a35
> fprintf(stderr, ", with PD control for clock deviation");
263c264
< " lopps occur their number will become smaller with lower verbosity level\n"
---
> " loops occur their number will become smaller with lower verbosity level\n"
272a274,275
> //AB int sfd, s, moreinput, err, verbose, nrchannels, startcount, sumavg,
> //AB stripped, innetbufsize, dobufstats, countdelay, maxbad;
274,276c277,281
< stripped, innetbufsize, dobufstats, countdelay, maxbad;
< long blen, hlen, ilen, olen, extra, loopspersec, nrdelays, sleep,
< nsec, count, wnext, badloops, badreads, readmissing, avgav, checkav;
---
> stripped, innetbufsize, dobufstats;
> //AB long blen, hlen, ilen, olen, extra, loopspersec, nrdelays, sleep,
> //AB nsec, count, wnext, badloops, badreads, readmissing, avgav, checkav;
> long blen, hlen, ilen, olen, extra, loopspersec, nrdelays, sleep,
> nsec, count, wnext, badloops, badreads, readmissing, avgav;
281c286,287
< double looperr, off, extraerr, extrabps, morebps;
---
> //AB double looperr, off, extraerr, extrabps, morebps;
> double looperr, off, extraerr, extrabps;
292,293c298,305
< double checktime;
< long corr;
---
> //AB double checktime;
> //AB long corr;
>
> /* AB */
> int ab_err = 0;
> int ab_err_d = 0;
> int ab_err_alt = 0;
> /* AB */
349c361
< maxbad = 4;
---
> //AB maxbad = 4;
352c364
< corr = 0;
---
> //AB corr = 0;
356c368
< countdelay = 1;
---
> //AB countdelay = 1;
421c433,434
< maxbad = atoi(optarg);
---
> //AB maxbad = atoi(optarg);
> fprintf(stderr, "playhrt: --max-bad-reads was ignored!\n");
446c459,460
< countdelay = 0;
---
> //AB countdelay = 0;
> fprintf(stderr, "playhrt: --no-delay-stats was ignored!\n");
455c469
< fprintf(stderr, ")\n");
---
> fprintf(stderr, ", with PD control for clock deviation)\n");
794c808
< refreshmem(iptr, s);
---
> refreshmem(iptr, s);
829c843
< refreshmem(iptr, s);
---
> refreshmem(iptr, s);
840a855,856
> /* AB: playback will start when at least 10 ms are buffered */
> /* AB: startcount = (int)((1.0*10000000)/nsec+1.0); */
850d865
< checktime = 0;
853a869,874
> if (verbose)
> if (count == startcount) {
> clock_gettime(CLOCK_MONOTONIC, &mtimecheck);
> fprintf(stderr, "playhrt: Start playback time (%ld sec %ld nsec).\n",
> mtime.tv_sec, mtime.tv_nsec);
> }
876,902c897,910
< if (verbose > 1)
< fprintf(stderr, "playhrt: Average available buffer: %ld (%ld sec %ld nsec).\n", avgav/16, mtime.tv_sec, mtime.tv_nsec);
< if (checktime == 0.0 && count > startcount+30000) {
< checktime = 1.0*mtime.tv_sec + mtime.tv_nsec/1000000000.0;
< checkav = avgav/16;
< corr = 1;
< }
< if (corr && avgav/16 > checkav + hwbufsize*3/10) {
< extrabps += (double)((avgav/16-checkav)*bytesperframe)/(mtime.tv_sec*1.0+mtime.tv_nsec/1000000000.0-checktime);
< extraerr = 1.0*bytesperframe*rate;
< extraerr = extraerr/(extraerr+extrabps);
< nsec = (int) (1000000000*extraerr/loopspersec);
< corr = 0;
< fprintf(stderr, "playhrt: Avoiding buffer underrun! Please use option \n"
< " --extra-bytes-per-second=%d\n"
< "on next call.\n", (int)extrabps);
< }
< if (corr && avgav/16 < checkav - hwbufsize*3/10) {
< extrabps += (double)((avgav/16-checkav)*bytesperframe)/(mtime.tv_sec*1.0+mtime.tv_nsec/1000000000.0-checktime);
< extraerr = 1.0*bytesperframe*rate;
< extraerr = extraerr/(extraerr+extrabps);
< nsec = (int) (1000000000*extraerr/loopspersec);
< corr = 0;
< fprintf(stderr, "playhrt: Avoiding buffer overrun! Please use option \n"
< " --extra-bytes-per-second=%d\n"
< "on next call.\n", (int)extrabps);
< }
---
> /* implement PD-controller, target = hwbufsize/2 */
> ab_err = avgav/16 - hwbufsize/2;
> ab_err_d = ab_err - ab_err_alt;
> ab_err_alt = ab_err;
> extrabps = (double)(ab_err*0.4 + ab_err_d*0.1);
>
> /* calculated required sleep time for adapted fill-rate */
> extraerr = 1.0*bytesperframe*rate;
> extraerr = extraerr/(extraerr+extrabps);
> nsec = (int) (1000000000*extraerr/loopspersec);
>
> if (verbose > 1)
> fprintf(stderr, "playhrt: At %ld sec. avail: %5ld e: %4d ed: %4d extrabps: %4d\n",
> mtime.tv_sec, avgav/16, ab_err, ab_err_d, (int)extrabps);
919,921d926
<
<
< /* we refresh the new data before and directly after the sleep before commiting */
923,933d927
<
< /* debug: check that we really sleep to some time in the future */
< if (countdelay) {
< clock_gettime(CLOCK_MONOTONIC, &mtimecheck);
< if (mtimecheck.tv_sec > mtime.tv_sec || (mtimecheck.tv_sec == mtime.tv_sec && mtimecheck.tv_nsec > mtime.tv_nsec))
< nrdelays += 1;
< }
< if (verbose > 1 && nrdelays > 0 && count % 4096 == 0) {
< fprintf(stderr, "playhrt: Number of delayed loops: %ld (%ld sec %ld nsec).\n", nrdelays, mtime.tv_sec, mtime.tv_nsec);
< }
<
935c929
< refreshmem(iptr, s);
---
> refreshmem(iptr, s);
937,949d930
< if (s < 0) {
< fprintf(stderr, "playhrt: Read error.\n");
< exit(22);
< } else if (s < ilen) {
< badreads++;
< readmissing += (ilen-s);
< if (verbose)
< fprintf(stderr, "playhrt: Bad read, %ld bytes missing at %ld.%ld.\n", (ilen-s), mtime.tv_sec, mtime.tv_nsec);
< if (badreads >= maxbad) {
< fprintf(stderr, "playhrt: Had %d bad reads . . . exiting.\n", maxbad);
< break;
< }
< }
961,967d941
< if (corr) {
< morebps = (double)((avgav/16-checkav)*bytesperframe)/(mtime.tv_sec*1.0+mtime.tv_nsec/1000000000.0-checktime);
< if (morebps >= 1.0 || morebps <= -1.0)
< fprintf(stderr, "playhrt: Suggesting option \n"
< " --extra-bytes-per-second=%d\n"
< "on future calls.\n", (int)(extrabps+morebps));
< }
Nur in frankl_stereo_0.8.2/src: version.h.
PS: Ein anderes patch, das ich seit Jahren benutze, ist ein Fix für brutefir, um bei ALSA under-/overflow auch das richtige ALSA device anzuzeigen. Der Fix stammt ursprünglich hier aus dem Forum von Tobias (Pittiplatsch).