XMMS2

src/xmms/converter_plugin.c

Go to the documentation of this file.
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);