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 to = xmms_stream_type_coerce (intype, goal_hints);
00048 if (!to) {
00049 return FALSE;
00050 }
00051
00052 conv = xmms_sample_converter_init (intype, to);
00053 if (!conv) {
00054 return FALSE;
00055 }
00056
00057 xmms_xform_outdata_type_set (xform, to);
00058 xmms_object_unref (to);
00059
00060 data = g_new0 (xmms_conv_xform_data_t, 1);
00061 data->conv = conv;
00062
00063 xmms_xform_private_data_set (xform, data);
00064
00065 return TRUE;
00066 }
00067
00068 static void
00069 xmms_converter_plugin_destroy (xmms_xform_t *xform)
00070 {
00071 xmms_conv_xform_data_t *data;
00072
00073 data = xmms_xform_private_data_get (xform);
00074
00075 if (data) {
00076 if (data->conv) {
00077 xmms_object_unref (data->conv);
00078 }
00079
00080 g_free (data);
00081 }
00082 }
00083
00084 static gint
00085 xmms_converter_plugin_read (xmms_xform_t *xform, void *buffer, gint len, xmms_error_t *error)
00086 {
00087 xmms_conv_xform_data_t *data;
00088 char buf[1024];
00089
00090 data = xmms_xform_private_data_get (xform);
00091
00092 if (!data->outlen) {
00093 int r = xmms_xform_read (xform, buf, sizeof (buf), error);
00094 if (r <= 0) {
00095 return r;
00096 }
00097 xmms_sample_convert (data->conv, buf, r, &data->outbuf, &data->outlen);
00098 }
00099
00100 len = MIN (len, data->outlen);
00101 memcpy (buffer, data->outbuf, len);
00102 data->outlen -= len;
00103 data->outbuf += len;
00104
00105 return len;
00106 }
00107
00108 static gint64
00109 xmms_converter_plugin_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *err)
00110 {
00111 xmms_conv_xform_data_t *data;
00112 gint64 res;
00113 gint64 scaled_samples;
00114
00115 g_return_val_if_fail (whence == XMMS_XFORM_SEEK_SET, -1);
00116 g_return_val_if_fail (xform, -1);
00117
00118 data = xmms_xform_private_data_get (xform);
00119 g_return_val_if_fail (data, -1);
00120
00121 scaled_samples = xmms_sample_convert_scale (data->conv, samples);
00122
00123 res = xmms_xform_seek (xform, scaled_samples, XMMS_XFORM_SEEK_SET, err);
00124 if (res == -1) {
00125 return -1;
00126 }
00127
00128 scaled_samples = xmms_sample_convert_rev_scale (data->conv, res);
00129
00130 xmms_sample_convert_reset (data->conv);
00131
00132 return scaled_samples;
00133 }
00134
00135 static gboolean
00136 xmms_converter_plugin_setup (xmms_xform_plugin_t *xform_plugin)
00137 {
00138 xmms_xform_methods_t methods;
00139
00140 XMMS_XFORM_METHODS_INIT (methods);
00141 methods.init = xmms_converter_plugin_init;
00142 methods.destroy = xmms_converter_plugin_destroy;
00143 methods.read = xmms_converter_plugin_read;
00144 methods.seek = xmms_converter_plugin_seek;
00145
00146 xmms_xform_plugin_methods_set (xform_plugin, &methods);
00147
00148
00149
00150
00151
00152 xmms_xform_plugin_indata_add (xform_plugin,
00153 XMMS_STREAM_TYPE_MIMETYPE,
00154 "audio/pcm",
00155 XMMS_STREAM_TYPE_PRIORITY,
00156 100,
00157 XMMS_STREAM_TYPE_NAME,
00158 "generic-pcmdata",
00159 XMMS_STREAM_TYPE_END);
00160
00161 converter_plugin = xform_plugin;
00162 return TRUE;
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 XMMS_XFORM_BUILTIN (converter,
00178 "Sample format converter",
00179 XMMS_VERSION,
00180 "Sample format converter",
00181 xmms_converter_plugin_setup);