2 * Copyright (C) 2010 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
3 * Copyright (C) 2010 Nokia Corporation. All rights reserved.
4 * Contact: Stefan Kost <stefan.kost@nokia.com>
6 * Tremor modifications <2006>:
7 * Chris Lord, OpenedHand Ltd. <chris@openedhand.com>, http://www.o-hand.com/
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
30 #include "gstvorbisdeclib.h"
33 /* These samples can be outside of the float -1.0 -- 1.0 range, this
34 * is allowed, downstream elements are supposed to clip */
36 copy_samples_m (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
37 gint channels, gint width)
39 memcpy (out, in[0], samples * sizeof (float));
43 copy_samples_s (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
44 gint channels, gint width)
46 #ifdef GST_VORBIS_DEC_SEQUENTIAL
47 memcpy (out, in[0], samples * sizeof (float));
49 memcpy (out, in[1], samples * sizeof (float));
53 for (j = 0; j < samples; j++) {
61 copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
62 gint channels, gint width)
64 #ifdef GST_VORBIS_DEC_SEQUENTIAL
67 for (i = 0; i < channels; i++) {
68 memcpy (out, in[i], samples * sizeof (float));
74 for (j = 0; j < samples; j++) {
75 for (i = 0; i < channels; i++) {
83 get_copy_sample_func (gint channels, gint width)
85 CopySampleFunc f = NULL;
87 g_assert (width == 4);
106 /* Taken from Tremor, misc.h */
108 static inline ogg_int32_t
109 CLIP_TO_15 (ogg_int32_t x)
112 asm volatile ("subs %1, %0, #32768\n\t"
113 "movpl %0, #0x7f00\n\t"
114 "orrpl %0, %0, #0xff\n"
115 "adds %1, %0, #32768\n\t"
116 "movmi %0, #0x8000":"+r" (x), "=r" (tmp)
122 static inline ogg_int32_t
123 CLIP_TO_15 (ogg_int32_t x)
127 ret -= ((x <= 32767) - 1) & (x - 32767);
128 ret -= ((x >= -32768) - 1) & (x + 32768);
134 copy_samples_32_m (vorbis_sample_t * _out, vorbis_sample_t ** _in,
135 guint samples, gint channels, gint width)
137 gint32 *out = (gint32 *) _out;
138 ogg_int32_t **in = (ogg_int32_t **) _in;
141 for (j = 0; j < samples; j++) {
142 *out++ = CLIP_TO_15 (in[0][j] >> 9);
147 copy_samples_32_s (vorbis_sample_t * _out, vorbis_sample_t ** _in,
148 guint samples, gint channels, gint width)
150 gint32 *out = (gint32 *) _out;
151 ogg_int32_t **in = (ogg_int32_t **) _in;
154 for (j = 0; j < samples; j++) {
155 *out++ = CLIP_TO_15 (in[0][j] >> 9);
156 *out++ = CLIP_TO_15 (in[1][j] >> 9);
161 copy_samples_32 (vorbis_sample_t * _out, vorbis_sample_t ** _in, guint samples,
162 gint channels, gint width)
164 gint32 *out = (gint32 *) _out;
165 ogg_int32_t **in = (ogg_int32_t **) _in;
168 for (j = 0; j < samples; j++) {
169 for (i = 0; i < channels; i++) {
170 *out++ = CLIP_TO_15 (in[i][j] >> 9);
176 copy_samples_16_m (vorbis_sample_t * _out, vorbis_sample_t ** _in,
177 guint samples, gint channels, gint width)
179 gint16 *out = (gint16 *) _out;
180 ogg_int32_t **in = (ogg_int32_t **) _in;
183 for (j = 0; j < samples; j++) {
184 *out++ = CLIP_TO_15 (in[0][j] >> 9);
189 copy_samples_16_s (vorbis_sample_t * _out, vorbis_sample_t ** _in,
190 guint samples, gint channels, gint width)
192 gint16 *out = (gint16 *) _out;
193 ogg_int32_t **in = (ogg_int32_t **) _in;
196 for (j = 0; j < samples; j++) {
197 *out++ = CLIP_TO_15 (in[0][j] >> 9);
198 *out++ = CLIP_TO_15 (in[1][j] >> 9);
203 copy_samples_16 (vorbis_sample_t * _out, vorbis_sample_t ** _in, guint samples,
204 gint channels, gint width)
206 gint16 *out = (gint16 *) _out;
207 ogg_int32_t **in = (ogg_int32_t **) _in;
210 for (j = 0; j < samples; j++) {
211 for (i = 0; i < channels; i++) {
212 *out++ = CLIP_TO_15 (in[i][j] >> 9);
218 get_copy_sample_func (gint channels, gint width)
220 CopySampleFunc f = NULL;
225 f = copy_samples_32_m;
228 f = copy_samples_32_s;
234 } else if (width == 2) {
237 f = copy_samples_16_m;
240 f = copy_samples_16_s;
247 g_assert_not_reached ();