aboutsummaryrefslogtreecommitdiff
path: root/src/input
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2011-10-10 09:53:38 +0200
committerMax Kellermann <max@duempel.org>2011-10-10 10:13:43 +0200
commit52b77f6e311c415279cff75a9af92ee9e62e5316 (patch)
tree60354708e932569b5e4fcec698664d3c47685fea /src/input
parent4c9782ee2897e8491e4a3590f3eb8db7de9d12b9 (diff)
input/cdio_paranoia: pass byte order swapping to the PCM "decoder"
Send another "magic" MIME type when the byte order must be reversed. This also fixes byte order issues when big-endian was involved (input data or host byte order) - that was completely broken.
Diffstat (limited to 'src/input')
-rw-r--r--src/input/cdio_paranoia_input_plugin.c43
1 files changed, 11 insertions, 32 deletions
diff --git a/src/input/cdio_paranoia_input_plugin.c b/src/input/cdio_paranoia_input_plugin.c
index 1a1c8d2c..09e1c61f 100644
--- a/src/input/cdio_paranoia_input_plugin.c
+++ b/src/input/cdio_paranoia_input_plugin.c
@@ -26,7 +26,6 @@
#include "input_internal.h"
#include "input_plugin.h"
#include "refcount.h"
-#include "pcm_buffer.h"
#include <stdio.h>
#include <stdint.h>
@@ -46,8 +45,6 @@ struct input_cdio_paranoia {
CdIo_t *cdio;
cdrom_paranoia_t *para;
- int endian;
-
lsn_t lsn_from, lsn_to;
int lsn_relofs;
@@ -55,8 +52,6 @@ struct input_cdio_paranoia {
char buffer[CDIO_CD_FRAMESIZE_RAW];
int buffer_lsn;
-
- struct pcm_buffer conv_buffer;
};
static inline GQuark
@@ -70,8 +65,6 @@ input_cdio_close(struct input_stream *is)
{
struct input_cdio_paranoia *i = (struct input_cdio_paranoia *)is;
- pcm_buffer_deinit(&i->conv_buffer);
-
if (i->para)
cdio_paranoia_free(i->para);
if (i->drv)
@@ -168,7 +161,6 @@ input_cdio_open(const char *uri,
i->cdio = NULL;
i->para = NULL;
i->trackno = parsed_uri.track;
- pcm_buffer_init(&i->conv_buffer);
/* get list of CD's supporting CD-DA */
char *device = parsed_uri.device[0] != 0
@@ -202,21 +194,24 @@ input_cdio_open(const char *uri,
return NULL;
}
- i->endian = data_bigendianp(i->drv);
- switch (i->endian) {
+ bool reverse_endian;
+ switch (data_bigendianp(i->drv)) {
case -1:
- g_debug("cdda: drive returns unknown audio data, assuming Little Endian");
- i->endian = 0;
+ g_debug("cdda: drive returns unknown audio data");
+ reverse_endian = false;
break;
case 0:
g_debug("cdda: drive returns audio data Little Endian.");
+ reverse_endian = G_BYTE_ORDER == G_BIG_ENDIAN;
break;
case 1:
g_debug("cdda: drive returns audio data Big Endian.");
+ reverse_endian = G_BYTE_ORDER == G_LITTLE_ENDIAN;
break;
default:
g_set_error(error_r, cdio_quark(), 0,
- "Drive returns unknown data type %d", i->endian);
+ "Drive returns unknown data type %d",
+ data_bigendianp(i->drv));
input_cdio_close(&i->base);
return NULL;
}
@@ -244,7 +239,9 @@ input_cdio_open(const char *uri,
i->base.size = (i->lsn_to - i->lsn_from + 1) * CDIO_CD_FRAMESIZE_RAW;
/* hack to make MPD select the "pcm" decoder plugin */
- i->base.mime = g_strdup("audio/x-mpd-cdda-pcm");
+ i->base.mime = g_strdup(reverse_endian
+ ? "audio/x-mpd-cdda-pcm-reverse"
+ : "audio/x-mpd-cdda-pcm");
return &i->base;
}
@@ -287,17 +284,6 @@ input_cdio_seek(struct input_stream *is,
return true;
}
-static inline size_t
-pcm16_to_wave(uint16_t *dst16, const uint16_t *src16, size_t length)
-{
- size_t cnt = length >> 1;
- while (cnt > 0) {
- *dst16++ = GUINT16_TO_LE(*src16++);
- cnt--;
- }
- return length;
-}
-
static size_t
input_cdio_read(struct input_stream *is, void *ptr, size_t length,
GError **error_r)
@@ -335,13 +321,6 @@ input_cdio_read(struct input_stream *is, void *ptr, size_t length,
"paranoia read error. Stopping.");
return 0;
}
- //do the swapping if nessesary
- if (cis->endian != 0) {
- uint16_t *conv_buffer = pcm_buffer_get(&cis->conv_buffer, CDIO_CD_FRAMESIZE_RAW );
- /* do endian conversion ! */
- pcm16_to_wave( conv_buffer, (uint16_t*) rbuf, CDIO_CD_FRAMESIZE_RAW);
- rbuf = (int16_t *)conv_buffer;
- }
//store current buffer
memcpy(cis->buffer, rbuf, CDIO_CD_FRAMESIZE_RAW);
cis->buffer_lsn = cis->lsn_relofs;