comparison src/flacng/plugin.c @ 2360:ead24454f4b7

native 24bit output for FLAC
author Eugene Zagidullin <e.asphyx@gmail.com>
date Tue, 05 Feb 2008 07:37:00 +0300
parents 5395c85a8724
children 0427c5d07a66
comparison
equal deleted inserted replaced
2359:b3475063c000 2360:ead24454f4b7
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */ 18 */
19 /* #define FLACNG_DEBUG */
19 20
20 #include "flacng.h" 21 #include "flacng.h"
21 #include <audacious/util.h> 22 #include <audacious/util.h>
22 #include <audacious/output.h> 23 #include <audacious/output.h>
23 #include <audacious/i18n.h> 24 #include <audacious/i18n.h>
214 test_info->stream.channels); 215 test_info->stream.channels);
215 INFO_UNLOCK(test_info); 216 INFO_UNLOCK(test_info);
216 _LEAVE FALSE; 217 _LEAVE FALSE;
217 } 218 }
218 219
219 if ((16 != test_info->stream.bits_per_sample) && 220 if ((8 != test_info->stream.bits_per_sample) &&
221 (16 != test_info->stream.bits_per_sample) &&
220 (24 != test_info->stream.bits_per_sample) && 222 (24 != test_info->stream.bits_per_sample) &&
221 (8 != test_info->stream.bits_per_sample)) { 223 (32 != test_info->stream.bits_per_sample)) {
222 _ERROR("This number of bits (%d) is currently not supported, stream not handled by this plugin", 224 _ERROR("This number of bits (%d) is currently not supported, stream not handled by this plugin",
223 test_info->stream.bits_per_sample); 225 test_info->stream.bits_per_sample);
224 INFO_UNLOCK(test_info); 226 INFO_UNLOCK(test_info);
225 _LEAVE FALSE; 227 _LEAVE FALSE;
226 } 228 }
262 _LEAVE ret; 264 _LEAVE ret;
263 } 265 }
264 266
265 /* --- */ 267 /* --- */
266 268
267 void squeeze_audio(gint32* src, void* dst, guint count, guint src_res, guint dst_res) { 269 void squeeze_audio(gint32* src, void* dst, guint count, guint res) {
268
269 /*
270 * Changes the sample width of count samples in src from
271 * src_res to dst_res and places the result in dst
272 */
273 270
274 gint i; 271 gint i;
275 gint32* rp = src; 272 gint32* rp = src;
276 gint8* wp = dst; 273 gint8* wp = dst;
277 gint16* wp2 = dst; 274 gint16* wp2 = dst;
278 gint32* wp4 = dst; 275 gint32* wp4 = dst;
279 276
280 _ENTER; 277 _ENTER;
281 278
282 _DEBUG("Converting %d samples %d->%d", count, src_res, dst_res); 279 _DEBUG("Converting %d samples to %d bit", count, res);
283 280
284 if ((src_res % 8 != 0) || (dst_res % 8 != 0)) { 281 if (res % 8 != 0) {
285 _ERROR("Can not convert from %d bps to %d bps: not a multiple of 8", 282 _ERROR("Can not convert to %d bps: not a multiple of 8", res);
286 src_res, dst_res); 283 _LEAVE;
287 _LEAVE; 284 }
288 } 285
289 286 if (res == 8) {
290 if (16 == dst_res) { 287 for (i=0; i<count; i++, wp++, rp++) {
291 if (8 == src_res) { 288 *wp = *rp & 0xff;
292 for (i=0; i<count; i++, wp2++, rp++) { 289 }
293 *wp2 = (*rp << 8) & 0xffff; 290 } else if (res == 16) {
294 } 291 for (i=0; i<count; i++, wp2++, rp++) {
295 } else if (16 == src_res) { 292 *wp2 = *rp & 0xffff;
296 for (i=0; i<count; i++, wp2++, rp++) { 293 }
297 *wp2 = *rp & 0xffff; 294 } else if (res == 24 || res == 32) { /* 24bit value stored in lowest 3 bytes */
298 } 295 for (i=0; i<count; i++, wp4++, rp++) {
299 } else if (24 == src_res) { 296 *wp4 = *rp;
300 for (i=0; i<count; i++, wp2++, rp++) { 297 }
301 *wp2 = (*rp >> 8) & 0xffff;
302 }
303 } else if (32 == src_res) {
304 for (i=0; i<count; i++, wp2++, rp++) {
305 *wp2 = (*rp >> 16) & 0xffff;
306 }
307 }
308 } else if (8 == dst_res) {
309 if (8 == src_res) {
310 for (i=0; i<count; i++, wp++, rp++) {
311 *wp = *rp & 0xff;
312 }
313 } else if (16 == src_res) {
314 for (i=0; i<count; i++, wp++, rp++) {
315 *wp = (*rp >> 8) & 0xff;
316 }
317 } else if (24 == src_res) {
318 for (i=0; i<count; i++, wp++, rp++) {
319 *wp = (*rp >> 16) & 0xff;
320 }
321 } else if (32 == src_res) {
322 for (i=0; i<count; i++, wp++, rp++) {
323 *wp = (*rp >> 24) & 0xff;
324 }
325 }
326 } else if (32 == dst_res) {
327 if (8 == src_res) {
328 for (i=0; i<count; i++, wp4++, rp++) {
329 *wp4 = (*rp << 24) & 0xffffffff;
330 }
331 } else if (16 == src_res) {
332 for (i=0; i<count; i++, wp4++, rp++) {
333 *wp4 = (*rp << 16) & 0xffffffff;
334 }
335 } else if (24 == src_res) {
336 for (i=0; i<count; i++, wp4++, rp++) {
337 *wp4 = (*rp << 8) & 0xffffffff;
338 }
339 } else if (32 == src_res) {
340 for (i=0; i<count; i++, wp4++, rp++) {
341 *wp4 = *rp;
342 }
343 }
344 } 298 }
345 299
346 _LEAVE; 300 _LEAVE;
347 } 301 }
348 302
375 329
376 stream_info.samplerate = main_info->stream.samplerate; 330 stream_info.samplerate = main_info->stream.samplerate;
377 stream_info.channels = main_info->stream.channels; 331 stream_info.channels = main_info->stream.channels;
378 main_info->metadata_changed = FALSE; 332 main_info->metadata_changed = FALSE;
379 333
380 if (!playback->output->open_audio(FMT_S16_NE, 334 if (!playback->output->open_audio(SAMPLE_FMT(main_info->stream.bits_per_sample),
381 main_info->stream.samplerate, 335 main_info->stream.samplerate,
382 main_info->stream.channels)) { 336 main_info->stream.channels)) {
383 playback->playing = FALSE; 337 playback->playing = FALSE;
384 _ERROR("Could not open output plugin!"); 338 _ERROR("Could not open output plugin!");
385 _LEAVE NULL; 339 _LEAVE NULL;
386 } 340 }
387 341
452 406
453 while ((TRUE == playback->playing) && (0 != elements_left)) { 407 while ((TRUE == playback->playing) && (0 != elements_left)) {
454 408
455 sample_count = MIN(OUTPUT_BLOCK_SIZE, elements_left); 409 sample_count = MIN(OUTPUT_BLOCK_SIZE, elements_left);
456 410
457 /* 411 squeeze_audio(read_pointer, play_buffer, sample_count, main_info->stream.bits_per_sample);
458 * Convert the audio.
459 * Currently this is hardcoded to 16 bit.
460 * 8 and 24 bit are sampled up/down linear.
461 */
462 _DEBUG("Converting %d samples to FMT_S16_NE", sample_count);
463 squeeze_audio(read_pointer, play_buffer, sample_count, main_info->frame.bits_per_sample, 16);
464 412
465 _DEBUG("Copying %d samples to output plugin", sample_count); 413 _DEBUG("Copying %d samples to output plugin", sample_count);
466 414
467 playback->pass_audio(playback, FMT_S16_NE, main_info->frame.channels, sample_count * sizeof(gint16), play_buffer, NULL); 415 playback->pass_audio(playback,
416 SAMPLE_FMT(main_info->stream.bits_per_sample),
417 main_info->stream.channels,
418 sample_count * SAMPLE_SIZE(main_info->stream.bits_per_sample),
419 play_buffer,
420 NULL);
468 421
469 read_pointer += sample_count; 422 read_pointer += sample_count;
470 elements_left -= sample_count; 423 elements_left -= sample_count;
471 424
472 _DEBUG("%d elements left to be output", elements_left); 425 _DEBUG("%d elements left to be output", elements_left);