00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <glib.h>
00018
00019 #include "xmmspriv/xmms_xform.h"
00020 #include "xmmspriv/xmms_streamtype.h"
00021 #include "xmmspriv/xmms_sample.h"
00022 #include "xmmspriv/xmms_xform.h"
00023 #include "xmms/xmms_medialib.h"
00024
00025 #include <string.h>
00026
00027 typedef struct xmms_conv_xform_data_St {
00028 xmms_sample_converter_t *conv;
00029 void *outbuf;
00030 guint outlen;
00031 } xmms_conv_xform_data_t;
00032
00033 static xmms_xform_plugin_t *converter_plugin;
00034
00035 static gboolean
00036 xmms_converter_plugin_init (xmms_xform_t *xform)
00037 {
00038 xmms_conv_xform_data_t *data;
00039 xmms_sample_converter_t *conv;
00040 xmms_stream_type_t *intype;
00041 xmms_stream_type_t *to;
00042 const GList *goal_hints;
00043
00044 intype = xmms_xform_intype_get (xform);
00045 goal_hints = xmms_xform_goal_hints_get (xform);
00046
00047 conv = xmms_sample_audioformats_coerce (intype, goal_hints);
00048 if (!conv) {
00049 return FALSE;
00050 }
00051
00052 to = xmms_sample_converter_get_to (conv);
00053 xmms_xform_outdata_type_set (xform, to);
00054
00055 data = g_new0 (xmms_conv_xform_data_t, 1);
00056 data->conv = conv;
00057
00058 xmms_xform_private_data_set (xform, data);
00059
00060 return TRUE;
00061 }
00062
00063 static void
00064 xmms_converter_plugin_destroy (xmms_xform_t *xform)
00065 {
00066 xmms_conv_xform_data_t *data;
00067
00068 data = xmms_xform_private_data_get (xform);
00069
00070 if (data) {
00071 if (data->conv) {
00072 xmms_object_unref (data->conv);
00073 }
00074
00075 g_free (data);
00076 }
00077 }
00078
00079 static gint
00080 xmms_converter_plugin_read (xmms_xform_t *xform, void *buffer, gint len, xmms_error_t *error)
00081 {
00082 xmms_conv_xform_data_t *data;
00083 char buf[1024];
00084
00085 data = xmms_xform_private_data_get (xform);
00086
00087 if (!data->outlen) {
00088 int r = xmms_xform_read (xform, buf, sizeof (buf), error);
00089 if (r <= 0) {
00090 return r;
00091 }
00092 xmms_sample_convert (data->conv, buf, r, &data->outbuf, &data->outlen);
00093 }
00094
00095 len = MIN (len, data->outlen);
00096 memcpy (buffer, data->outbuf, len);
00097 data->outlen -= len;
00098 data->outbuf += len;
00099
00100 return len;
00101 }
00102
00103 static gint64
00104 xmms_converter_plugin_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *err)
00105 {
00106 xmms_conv_xform_data_t *data;
00107 gint64 res;
00108 gint64 scaled_samples;
00109
00110 g_return_val_if_fail (whence == XMMS_XFORM_SEEK_SET, -1);
00111 g_return_val_if_fail (xform, -1);
00112
00113 data = xmms_xform_private_data_get (xform);
00114 g_return_val_if_fail (data, -1);
00115
00116 scaled_samples = xmms_sample_convert_scale (data->conv, samples);
00117
00118 res = xmms_xform_seek (xform, scaled_samples, XMMS_XFORM_SEEK_SET, err);
00119 if (res == -1) {
00120 return -1;
00121 }
00122
00123 scaled_samples = xmms_sample_convert_rev_scale (data->conv, res);
00124
00125 xmms_sample_convert_reset (data->conv);
00126
00127 return scaled_samples;
00128 }
00129
00130 static gboolean
00131 xmms_converter_plugin_setup (xmms_xform_plugin_t *xform_plugin)
00132 {
00133 xmms_xform_methods_t methods;
00134
00135 XMMS_XFORM_METHODS_INIT (methods);
00136 methods.init = xmms_converter_plugin_init;
00137 methods.destroy = xmms_converter_plugin_destroy;
00138 methods.read = xmms_converter_plugin_read;
00139 methods.seek = xmms_converter_plugin_seek;
00140
00141 xmms_xform_plugin_methods_set (xform_plugin, &methods);
00142
00143
00144
00145
00146
00147 xmms_xform_plugin_indata_add (xform_plugin,
00148 XMMS_STREAM_TYPE_MIMETYPE,
00149 "audio/pcm",
00150 XMMS_STREAM_TYPE_PRIORITY,
00151 100,
00152 XMMS_STREAM_TYPE_NAME,
00153 "generic-pcmdata",
00154 XMMS_STREAM_TYPE_END);
00155
00156 converter_plugin = xform_plugin;
00157 return TRUE;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 XMMS_XFORM_BUILTIN (converter,
00173 "Sample format converter",
00174 XMMS_VERSION,
00175 "Sample format converter",
00176 xmms_converter_plugin_setup);