[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