/* http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9 */
const GstAudioChannelPosition gst_vorbis_channel_positions[][8] = {
{ /* Mono */
- GST_AUDIO_CHANNEL_POSITION_FRONT_MONO},
+ GST_AUDIO_CHANNEL_POSITION_MONO},
{ /* Stereo */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_LFE,
+ GST_AUDIO_CHANNEL_POSITION_LFE1,
},
{ /* 6.1 Surround, in Vorbis spec since 2010-01-13 */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
- GST_AUDIO_CHANNEL_POSITION_LFE},
+ GST_AUDIO_CHANNEL_POSITION_LFE1},
{ /* 7.1 Surround, in Vorbis spec since 2010-01-13 */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
- GST_AUDIO_CHANNEL_POSITION_LFE},
+ GST_AUDIO_CHANNEL_POSITION_LFE1},
};
+
+const GstAudioChannelPosition gst_vorbis_default_channel_positions[][8] = {
+ { /* Mono */
+ GST_AUDIO_CHANNEL_POSITION_MONO},
+ { /* Stereo */
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
+ { /* Stereo + Centre */
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER},
+ { /* Quadraphonic */
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
+ },
+ { /* Stereo + Centre + rear stereo */
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
+ },
+ { /* Full 5.1 Surround */
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_LFE1,
+ GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
+ },
+ { /* 6.1 Surround, in Vorbis spec since 2010-01-13 */
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_LFE1,
+ GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
+ },
+ { /* 7.1 Surround, in Vorbis spec since 2010-01-13 */
+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
+ GST_AUDIO_CHANNEL_POSITION_LFE1,
+ GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
+ GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
+ GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
+ },
+};
+
+#ifndef USE_TREMOLO
+/* gst[i] = vorbis[reorder_map[i]] */
+const gint gst_vorbis_reorder_map[][8] = {
+ {0},
+ {0, 1},
+ {0, 2, 1},
+ {0, 1, 2, 3},
+ {0, 2, 1, 3, 4},
+ {0, 2, 1, 4, 5, 3},
+ {0, 2, 1, 5, 6, 4, 3},
+ {0, 2, 1, 6, 7, 4, 5, 3}
+};
+#endif
#define __GST_VORBIS_COMMON_H__
#include <gst/gst.h>
-#include <gst/audio/multichannel.h>
+#include <gst/audio/audio.h>
extern const GstAudioChannelPosition gst_vorbis_channel_positions[][8];
+extern const GstAudioChannelPosition gst_vorbis_default_channel_positions[][8];
+
+#ifndef USE_TREMOLO
+extern const gint gst_vorbis_reorder_map[][8];
+#endif
#endif /* __GST_VORBIS_COMMON_H__ */
#include <string.h>
#include <gst/audio/audio.h>
#include <gst/tag/tag.h>
-#include <gst/audio/multichannel.h>
#include "gstvorbiscommon.h"
GstCaps *caps;
GstAudioInfo info;
- gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate,
- vd->vi.channels);
-
switch (info.channels) {
case 1:
case 2:
- /* nothing */
- break;
case 3:
case 4:
case 5:
case 8:
{
const GstAudioChannelPosition *pos;
- gint i;
- pos = gst_vorbis_channel_positions[info.channels - 1];
- for (i = 0; i < info.channels; i++)
- info.position[i] = pos[i];
+ pos = gst_vorbis_default_channel_positions[info.channels - 1];
+ gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate,
+ vd->vi.channels, pos);
break;
}
default:{
+ GstAudioChannelPosition position[64];
gint i, max_pos = MAX (info.channels, 64);
GST_ELEMENT_WARNING (vd, STREAM, DECODE,
(NULL), ("Using NONE channel layout for more than 8 channels"));
for (i = 0; i < max_pos; i++)
- info.position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
+ position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
+ gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate,
+ vd->vi.channels, position);
break;
}
}
#endif
goto wrong_samples;
-#ifndef USE_TREMOLO
+#ifdef USE_TREMOLO
+ if (vd->info.channels < 9)
+ gst_audio_reorder_channels (data, size, GST_VORBIS_AUDIO_FORMAT,
+ vd->info.channels, gst_vorbis_channel_positions[vd->info.channels - 1],
+ gst_vorbis_default_channel_positions[vd->info.channels - 1]);
+#else
/* copy samples in buffer */
vd->copy_samples ((vorbis_sample_t *) data, pcm,
sample_count, vd->info.channels);
#include <string.h>
#include "gstvorbisdeclib.h"
+#include "gstvorbiscommon.h"
#ifndef TREMOR
/* These samples can be outside of the float -1.0 -- 1.0 range, this
gint i;
for (i = 0; i < channels; i++) {
- memcpy (out, in[i], samples * sizeof (float));
+ memcpy (out, in[gst_vorbis_reorder_map[channels - 1][i]],
+ samples * sizeof (float));
out += samples;
}
#else
for (j = 0; j < samples; j++) {
for (i = 0; i < channels; i++) {
- *out++ = in[i][j];
+ *out++ = in[gst_vorbis_reorder_map[channels - 1][i]][j];
}
}
#endif
for (j = 0; j < samples; j++) {
for (i = 0; i < channels; i++) {
- *out++ = CLIP_TO_15 (in[i][j] >> 9);
+ *out++ = CLIP_TO_15 (in[gst_vorbis_reorder_map[channels - 1][i]][j] >> 9);
}
}
}
#include <gst/gsttagsetter.h>
#include <gst/tag/tag.h>
-#include <gst/audio/multichannel.h>
#include <gst/audio/audio.h>
#include "gstvorbisenc.h"
"rate", GST_TYPE_INT_RANGE, 1, 200000,
"channels", G_TYPE_INT, 1, NULL));
- gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
- "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
- "rate", GST_TYPE_INT_RANGE, 1, 200000,
- "channels", G_TYPE_INT, 2, NULL));
-
- for (i = 3; i <= 8; i++) {
- GValue chanpos = { 0 };
- GValue pos = { 0 };
+ for (i = 2; i <= 8; i++) {
GstStructure *structure;
-
- g_value_init (&chanpos, GST_TYPE_ARRAY);
- g_value_init (&pos, GST_TYPE_AUDIO_CHANNEL_POSITION);
+ guint64 channel_mask = 0;
+ const GstAudioChannelPosition *pos = gst_vorbis_channel_positions[i - 1];
for (c = 0; c < i; c++) {
- g_value_set_enum (&pos, gst_vorbis_channel_positions[i - 1][c]);
- gst_value_array_append_value (&chanpos, &pos);
+ channel_mask |= pos[i];
}
- g_value_unset (&pos);
structure = gst_structure_new ("audio/x-raw",
"format", G_TYPE_STRING, GST_AUDIO_NE (F32),
- "rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i, NULL);
- gst_structure_set_value (structure, "channel-positions", &chanpos);
- g_value_unset (&chanpos);
+ "rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i,
+ "channel-mask", GST_TYPE_BITMASK, channel_mask, NULL);
gst_caps_append_structure (caps, structure);
}
gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
"format", G_TYPE_STRING, GST_AUDIO_NE (F32),
"rate", GST_TYPE_INT_RANGE, 1, 200000,
- "channels", GST_TYPE_INT_RANGE, 9, 255, NULL));
+ "channels", GST_TYPE_INT_RANGE, 9, 255,
+ "channel-mask", GST_TYPE_BITMASK, G_GUINT64_CONSTANT (0), NULL));
return caps;
}
vorbis_buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
/* deinterleave samples, write the buffer data */
- for (i = 0; i < size; i++) {
- for (j = 0; j < vorbisenc->channels; j++) {
- vorbis_buffer[j][i] = *ptr++;
+ if (vorbisenc->channels < 2 || vorbisenc->channels > 8) {
+ for (i = 0; i < size; i++) {
+ for (j = 0; j < vorbisenc->channels; j++) {
+ vorbis_buffer[j][i] = *ptr++;
+ }
+ }
+ } else {
+ gint i, j;
+
+ /* Reorder */
+ for (i = 0; i < size; i++) {
+ for (j = 0; j < vorbisenc->channels; j++) {
+ vorbis_buffer[gst_vorbis_reorder_map[vorbisenc->channels - 1][j]][i] =
+ ptr[j];
+ }
+ ptr += vorbisenc->channels;
}
}