XMMS2
converter_plugin.c
Go to the documentation of this file.
1 /* XMMS2 - X Music Multiplexer System
2  * Copyright (C) 2003-2011 XMMS2 Team
3  *
4  * PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  */
16 
17 #include <glib.h>
18 
19 #include "xmmspriv/xmms_xform.h"
21 #include "xmmspriv/xmms_sample.h"
22 #include "xmmspriv/xmms_xform.h"
23 #include "xmms/xmms_medialib.h"
24 
25 #include <string.h>
26 
27 typedef struct xmms_conv_xform_data_St {
29  void *outbuf;
30  guint outlen;
32 
33 static xmms_xform_plugin_t *converter_plugin;
34 
35 static gboolean
36 xmms_converter_plugin_init (xmms_xform_t *xform)
37 {
40  xmms_stream_type_t *intype;
42  const GList *goal_hints;
43 
44  intype = xmms_xform_intype_get (xform);
45  goal_hints = xmms_xform_goal_hints_get (xform);
46 
47  to = xmms_stream_type_coerce (intype, goal_hints);
48  if (!to) {
49  return FALSE;
50  }
51 
52  conv = xmms_sample_converter_init (intype, to);
53  if (!conv) {
54  return FALSE;
55  }
56 
57  xmms_xform_outdata_type_set (xform, to);
58  xmms_object_unref (to);
59 
60  data = g_new0 (xmms_conv_xform_data_t, 1);
61  data->conv = conv;
62 
63  xmms_xform_private_data_set (xform, data);
64 
65  return TRUE;
66 }
67 
68 static void
69 xmms_converter_plugin_destroy (xmms_xform_t *xform)
70 {
72 
73  data = xmms_xform_private_data_get (xform);
74 
75  if (data) {
76  if (data->conv) {
77  xmms_object_unref (data->conv);
78  }
79 
80  g_free (data);
81  }
82 }
83 
84 static gint
85 xmms_converter_plugin_read (xmms_xform_t *xform, void *buffer, gint len, xmms_error_t *error)
86 {
88  char buf[1024];
89 
90  data = xmms_xform_private_data_get (xform);
91 
92  if (!data->outlen) {
93  int r = xmms_xform_read (xform, buf, sizeof (buf), error);
94  if (r <= 0) {
95  return r;
96  }
97  xmms_sample_convert (data->conv, buf, r, &data->outbuf, &data->outlen);
98  }
99 
100  len = MIN (len, data->outlen);
101  memcpy (buffer, data->outbuf, len);
102  data->outlen -= len;
103  data->outbuf += len;
104 
105  return len;
106 }
107 
108 static gint64
109 xmms_converter_plugin_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *err)
110 {
112  gint64 res;
113  gint64 scaled_samples;
114 
115  g_return_val_if_fail (whence == XMMS_XFORM_SEEK_SET, -1);
116  g_return_val_if_fail (xform, -1);
117 
118  data = xmms_xform_private_data_get (xform);
119  g_return_val_if_fail (data, -1);
120 
121  scaled_samples = xmms_sample_convert_scale (data->conv, samples);
122 
123  res = xmms_xform_seek (xform, scaled_samples, XMMS_XFORM_SEEK_SET, err);
124  if (res == -1) {
125  return -1;
126  }
127 
128  scaled_samples = xmms_sample_convert_rev_scale (data->conv, res);
129 
130  xmms_sample_convert_reset (data->conv);
131 
132  return scaled_samples;
133 }
134 
135 static gboolean
136 xmms_converter_plugin_setup (xmms_xform_plugin_t *xform_plugin)
137 {
138  xmms_xform_methods_t methods;
139 
140  XMMS_XFORM_METHODS_INIT (methods);
141  methods.init = xmms_converter_plugin_init;
142  methods.destroy = xmms_converter_plugin_destroy;
143  methods.read = xmms_converter_plugin_read;
144  methods.seek = xmms_converter_plugin_seek;
145 
146  xmms_xform_plugin_methods_set (xform_plugin, &methods);
147 
148  /*
149  * Handle any pcm data...
150  * Well, we don't really..
151  */
152  xmms_xform_plugin_indata_add (xform_plugin,
154  "audio/pcm",
156  100,
158  "generic-pcmdata",
160 
161  converter_plugin = xform_plugin;
162  return TRUE;
163 }
164 
165 /*
166 xmms_xform_t *
167 xmms_converter_new (xmms_xform_t *prev, xmms_medialib_entry_t entry, GList *gt)
168 {
169  xmms_xform_t *xform;
170 
171  xform = xmms_xform_new (converter_plugin, prev, entry, gt);
172 
173  return xform;
174 }
175 */
176 
177 XMMS_XFORM_BUILTIN (converter,
178  "Sample format converter",
179  XMMS_VERSION,
180  "Sample format converter",
181  xmms_converter_plugin_setup);
struct xmms_xform_plugin_St xmms_xform_plugin_t
Xform plugin.
#define xmms_object_unref(obj)
Definition: xmms_object.h:109
struct xmms_stream_type_St xmms_stream_type_t
void xmms_xform_outdata_type_set(xmms_xform_t *xform, xmms_stream_type_t *type)
Definition: xform.c:445
void xmms_xform_plugin_indata_add(xmms_xform_plugin_t *plugin,...)
Add a valid input type to the plugin.
Definition: xform_plugin.c:79
xmms_stream_type_t * xmms_stream_type_coerce(const xmms_stream_type_t *in, const GList *goal_types)
Find the best pair of formats.
Definition: streamtype.c:240
struct xmms_xform_St xmms_xform_t
gboolean(* init)(xmms_xform_t *)
Initialisation method.
xmms_sample_converter_t * xmms_sample_converter_init(xmms_stream_type_t *from, xmms_stream_type_t *to)
Definition: sample.head.c:77
struct xmms_conv_xform_data_St xmms_conv_xform_data_t
struct xmms_sample_converter_St xmms_sample_converter_t
Definition: xmms_sample.h:38
gpointer xmms_xform_private_data_get(xmms_xform_t *xform)
Get private data for this xform.
Definition: xform.c:424
enum xmms_xform_seek_mode_E xmms_xform_seek_mode_t
Seek direction argument.
Methods provided by an xform plugin.
void xmms_xform_plugin_methods_set(xmms_xform_plugin_t *plugin, xmms_xform_methods_t *methods)
Should be called once from the plugin&#39;s setupfunc.
Definition: xform_plugin.c:53
gint64 xmms_xform_seek(xmms_xform_t *xform, gint64 offset, xmms_xform_seek_mode_t whence, xmms_error_t *err)
Change offset in stream.
Definition: xform.c:1120
void(* destroy)(xmms_xform_t *)
Destruction method.
gint64 xmms_sample_convert_scale(xmms_sample_converter_t *conv, gint64 samples)
Definition: sample.head.c:297
XMMS_XFORM_BUILTIN(converter, "Sample format converter", XMMS_VERSION, "Sample format converter", xmms_converter_plugin_setup)
void xmms_sample_convert(xmms_sample_converter_t *conv, xmms_sample_t *in, guint len, xmms_sample_t **out, guint *outlen)
do the actual converstion between two audio formats.
Definition: sample.head.c:256
gint xmms_xform_read(xmms_xform_t *xform, gpointer buf, gint siz, xmms_error_t *err)
Read data from previous xform.
Definition: xform.c:1113
#define MIN(a, b)
Definition: xmmsc_util.h:36
gint(* read)(xmms_xform_t *, gpointer, gint, xmms_error_t *)
Read method.
G_BEGIN_DECLS struct xmms_error_St xmms_error_t
#define XMMS_XFORM_METHODS_INIT(m)
gint64 xmms_sample_convert_rev_scale(xmms_sample_converter_t *conv, gint64 samples)
Definition: sample.head.c:309
void xmms_xform_private_data_set(xmms_xform_t *xform, gpointer data)
Set private data for this xform.
Definition: xform.c:430
xmms_stream_type_t * xmms_xform_intype_get(xmms_xform_t *xform)
Definition: xform.c:490
gint64(* seek)(xmms_xform_t *, gint64, xmms_xform_seek_mode_t, xmms_error_t *)
Seek method.
void xmms_sample_convert_reset(xmms_sample_converter_t *conv)
Definition: sample.head.c:317
const GList * xmms_xform_goal_hints_get(xmms_xform_t *xform)
Definition: xform.c:1223