XMMS2
|
00001 /* XMMS2 - X Music Multiplexer System 00002 * Copyright (C) 2003-2009 XMMS2 Team 00003 * 00004 * PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!! 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 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 * Handle any pcm data... 00150 * Well, we don't really.. 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 xmms_xform_t * 00167 xmms_converter_new (xmms_xform_t *prev, xmms_medialib_entry_t entry, GList *gt) 00168 { 00169 xmms_xform_t *xform; 00170 00171 xform = xmms_xform_new (converter_plugin, prev, entry, gt); 00172 00173 return xform; 00174 } 00175 */ 00176 00177 XMMS_XFORM_BUILTIN (converter, 00178 "Sample format converter", 00179 XMMS_VERSION, 00180 "Sample format converter", 00181 xmms_converter_plugin_setup);