Mercurial > audlegacy-plugins
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); |