[xiph-commits] r7455 - in icecast/trunk/ices0: . doc src

brendan at motherfish-iii.xiph.org brendan
Thu Aug 5 19:07:18 PDT 2004


Author: brendan
Date: Thu Aug  5 19:07:18 2004
New Revision: 7455

Modified:
icecast/trunk/ices0/BUGS
icecast/trunk/ices0/doc/icesmanual.html
icecast/trunk/ices0/src/crossfade.c
Log:
Resample crossfade buffer if sample rate changes.

Modified: icecast/trunk/ices0/BUGS
===================================================================
--- icecast/trunk/ices0/BUGS	2004-08-02 19:01:38 UTC (rev 7454)
+++ icecast/trunk/ices0/BUGS	2004-08-03 00:42:04 UTC (rev 7455)
@@ -1,4 +1,3 @@
* Handles error conditions poorly.
-* Crossfader mishandles sample rate change. Maybe I need a resampler?

$Id$

Modified: icecast/trunk/ices0/doc/icesmanual.html
===================================================================
--- icecast/trunk/ices0/doc/icesmanual.html	2004-08-02 19:01:38 UTC (rev 7454)
+++ icecast/trunk/ices0/doc/icesmanual.html	2004-08-03 00:42:04 UTC (rev 7455)
@@ -138,10 +138,7 @@
configuration file. Both of these take an integer argument,
which is the number of seconds to crossfade.
Songs less than twice the length of the crossfade requested will not
-be faded. This is handy for eg station IDs. <b>NOTE</b>: The
-crossfader doesn't know how to resample, so if you activate this
-feature you should make sure that all your source tracks have the
-same sampling rate.
+be faded. This is handy for eg station IDs.
</p>
</li>


Modified: icecast/trunk/ices0/src/crossfade.c
===================================================================
--- icecast/trunk/ices0/src/crossfade.c	2004-08-02 19:01:38 UTC (rev 7454)
+++ icecast/trunk/ices0/src/crossfade.c	2004-08-03 00:42:04 UTC (rev 7455)
@@ -26,6 +26,8 @@
static int cf_process(int ilen, int16_t* il, int16_t* ir);
static void cf_shutdown(void);

+static int resample(unsigned int oldrate, unsigned int newrate);
+
static ices_plugin_t Crossfader = {
"crossfade",

@@ -37,6 +39,7 @@
NULL
};

+static int Fadelen;
static int FadeSamples;
static int16_t* FL = NULL;
static int16_t* FR = NULL;
@@ -48,6 +51,7 @@

/* public functions */
ices_plugin_t *crossfade_plugin(int secs) {
+  Fadelen = secs;
FadeSamples = secs * 44100;

return &Crossfader;
@@ -62,7 +66,7 @@
if (!(Swap = malloc(FadeSamples * 2)))
goto err;

-  ices_log_debug("Crossfading %d seconds between tracks", FadeSamples / 44100);
+  ices_log_debug("Crossfading %d seconds between tracks", Fadelen);
return 0;

err:
@@ -76,8 +80,10 @@
static input_stream_t lasttrack;
int filesecs;

-  if (lasttrack.samplerate && lasttrack.samplerate != source->samplerate)
-    skipnext = 1;
+  if (lasttrack.samplerate && lasttrack.samplerate != source->samplerate) {
+    if (resample(lasttrack.samplerate, source->samplerate) < 0)
+      skipnext = 1;
+  }

memcpy(&lasttrack, source, sizeof(lasttrack));

@@ -89,7 +95,7 @@

if (source->filesize && source->bitrate) {
filesecs = source->filesize / (source->bitrate * 128);
-    if (filesecs < 10 || filesecs <= FadeSamples * 2 / 44100) {
+    if (filesecs < 10 || filesecs <= Fadelen * 2) {
ices_log_debug("crossfade: not fading short track of %d secs", filesecs);
skipnext = 1;
return;
@@ -97,11 +103,6 @@
}

NewTrack = FadeSamples;
-  if (source->samplerate != 44100) {
-    NewTrack *= source->samplerate/44100.0;
-    if (NewTrack > FadeSamples)
-      NewTrack = FadeSamples;
-  }
}

static int cf_process(int ilen, int16_t* il, int16_t* ir)
@@ -172,3 +173,55 @@

ices_log_debug("Crossfader shutting down");
}
+
+static int resample(unsigned int oldrate, unsigned int newrate) {
+  int16_t* left;
+  int16_t* right;
+  int16_t* newswap;
+  unsigned int newsize = Fadelen * newrate;
+  unsigned int newlen;
+  int i;
+  int off;
+  int eps;
+
+  if (!(left = malloc(newsize * sizeof(int16_t))))
+    return -1;
+
+  if (!(right = malloc(newsize * sizeof(int16_t)))) {
+    free(left);
+    return -1;
+  }
+  if (!(newswap = malloc(newsize * sizeof(int16_t)))) {
+    free(left);
+    free(right);
+    return -1;
+  }
+
+  i = 0;
+  eps = 0;
+  off = (fpos + FadeSamples - flen) % FadeSamples;
+  newlen = flen * (float)newrate / oldrate;
+  /* the trusty Bresenham algorithm */
+  while (i < newlen) {
+    left[i] = FL[off];
+    right[i] = FR[off];
+    eps += oldrate;
+    while (eps * 2 >= (int)newrate) {
+      off = (off + 1) % FadeSamples;
+      eps -= newrate;
+    }
+    i++;
+  }
+
+  free(FL);
+  free(FR);
+  free(Swap);
+  FL = left;
+  FR = right;
+  Swap = newswap;
+  FadeSamples = newsize;
+  flen = newlen;
+  fpos = i % FadeSamples;
+
+  return 0;
+}



More information about the commits mailing list