doc: Remove superfluous comment already described in footnotes.
[mpd-mk.git] / src / crossfade.c
blob01552bf65f8dce60c06259c21845037745aa614a
1 /*
2 * Copyright (C) 2003-2009 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "crossfade.h"
21 #include "pcm_mix.h"
22 #include "chunk.h"
23 #include "audio_format.h"
24 #include "tag.h"
26 #include <assert.h>
27 #include <string.h>
29 unsigned cross_fade_calc(float duration, float total_time,
30 const struct audio_format *af,
31 const struct audio_format *old_format,
32 unsigned max_chunks)
34 unsigned int chunks;
36 if (duration <= 0 || duration >= total_time ||
37 /* we can't crossfade when the audio formats are different */
38 !audio_format_equals(af, old_format))
39 return 0;
41 assert(duration > 0);
42 assert(af->bits > 0);
43 assert(af->channels > 0);
44 assert(af->sample_rate > 0);
46 chunks = audio_format_time_to_size(af) / CHUNK_SIZE;
47 chunks = (chunks * duration + 0.5);
49 if (chunks > max_chunks)
50 chunks = max_chunks;
52 return chunks;
55 void cross_fade_apply(struct music_chunk *a, const struct music_chunk *b,
56 const struct audio_format *format,
57 unsigned int current_chunk, unsigned int num_chunks)
59 size_t size;
61 assert(a != NULL);
62 assert(b != NULL);
63 assert(a->length == 0 || b->length == 0 ||
64 audio_format_equals(&a->audio_format, &b->audio_format));
65 assert(current_chunk <= num_chunks);
67 if (a->tag == NULL && b->tag != NULL)
68 /* merge the tag into the destination chunk */
69 a->tag = tag_dup(b->tag);
71 size = b->length > a->length
72 ? a->length
73 : b->length;
75 pcm_mix(a->data,
76 b->data,
77 size,
78 format,
79 ((float)current_chunk) / num_chunks);
81 if (b->length > a->length) {
82 /* the second buffer is larger than the first one:
83 there is unmixed rest at the end. Copy it over.
84 The output buffer API guarantees that there is
85 enough room in a->data. */
87 #ifndef NDEBUG
88 if (a->length == 0)
89 a->audio_format = b->audio_format;
90 #endif
92 memcpy(a->data + a->length,
93 b->data + a->length,
94 b->length - a->length);
95 a->length = b->length;