1/*
2 INTEL CONFIDENTIAL
3 Copyright 2009 Intel Corporation All Rights Reserved.
4 The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel’s prior express written permission.
5
6 No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing.
7*/
8
9/**
10 * SECTION:mixacp
11 * @short_description: MixAudio configuration parameters object.
12 * @include: mixacp.h
13 *
14 * #MixAudio configuration parameters object which is used to communicate audio specific parameters.
15 *
16 * This object is should not be instantiated as codec specific parameters are definied in individual derive classes.
17 */
18
19#include "mixacp.h"
20#include <mixlog.h>
21
22static GType _mix_acp_type = 0;
23static MixParamsClass *parent_class = NULL;
24
25#define _do_init { _mix_acp_type = g_define_type_id; }
26
27gboolean mix_acp_copy(MixParams* target, const MixParams *src);
28MixParams* mix_acp_dup(const MixParams *obj);
29gboolean mix_acp_equal(MixParams* first, MixParams *second);
30static void mix_acp_finalize(MixParams *obj);
31
32G_DEFINE_TYPE_WITH_CODE(MixAudioConfigParams, mix_acp, MIX_TYPE_PARAMS, _do_init);
33
34void
35_mix_acp_initialize (void)
36{
37  /* the MixParams types need to be class_ref'd once before it can be
38   * done from multiple threads;
39   * see http://bugzilla.gnome.org/show_bug.cgi?id=304551 */
40  g_type_class_ref (mix_acp_get_type ());
41}
42
43static void mix_acp_init (MixAudioConfigParams *self)
44{
45  self->decode_mode = MIX_DECODE_NULL;
46  self->stream_name = NULL;
47  self->audio_manager=MIX_AUDIOMANAGER_NONE;
48  self->num_channels = 0;
49  self->bit_rate = 0;
50  self->sample_freq = 0;
51  self->bits_per_sample = MIX_ACP_BPS_16;
52  self->op_align = MIX_ACP_OUTPUT_ALIGN_16;
53}
54
55static void mix_acp_class_init(MixAudioConfigParamsClass *klass)
56{
57  MixParamsClass *mixparams_class = MIX_PARAMS_CLASS(klass);
58
59  /* setup static parent class */
60  parent_class = (MixParamsClass *) g_type_class_peek_parent (klass);
61
62  mixparams_class->finalize = mix_acp_finalize;
63  mixparams_class->copy = (MixParamsCopyFunction)mix_acp_copy;
64  mixparams_class->dup = (MixParamsDupFunction)mix_acp_dup;
65  mixparams_class->equal = (MixParamsEqualFunction)mix_acp_equal;
66
67  klass->print_params = NULL;
68}
69
70MixAudioConfigParams *mix_acp_new(void)
71{
72  MixAudioConfigParams *ret = (MixAudioConfigParams *)g_type_create_instance (MIX_TYPE_AUDIOCONFIGPARAMS);
73
74  return ret;
75}
76
77void mix_acp_finalize(MixParams *obj)
78{
79  /* clean up here. */
80  MixAudioConfigParams *acp = MIX_AUDIOCONFIGPARAMS(obj);
81
82  if (acp->stream_name) {
83    g_free(acp->stream_name);
84    acp->stream_name = NULL;
85  }
86
87  /* Chain up parent */
88  if (parent_class->finalize)
89    parent_class->finalize(obj);
90}
91
92MixAudioConfigParams *mix_acp_ref(MixAudioConfigParams *mix)
93{
94  return (MixAudioConfigParams*)mix_params_ref(MIX_PARAMS(mix));
95}
96
97/**
98 * mix_acp_dup:
99 * @obj: a #MixAudioConfigParams object
100 * @returns: a newly allocated duplicate of the object.
101 *
102 * Copy duplicate of the object.
103 */
104MixParams* mix_acp_dup(const MixParams *obj)
105{
106  MixParams *ret = NULL;
107
108  if (MIX_IS_AUDIOCONFIGPARAMS(obj))
109  {
110    MixAudioConfigParams *duplicate = mix_acp_new();
111    if (mix_acp_copy(MIX_PARAMS(duplicate), MIX_PARAMS(obj)))
112    {
113      ret = MIX_PARAMS(duplicate);
114    }
115    else
116    {
117      mix_acp_unref(duplicate);
118    }
119  }
120
121  return ret;
122}
123
124/**
125 * mix_acp_copy:
126 * @target: copy to target
127 * @src: copy from src
128 * @returns: boolean indicates if copy is successful.
129 *
130 * Copy instance data from @src to @target.
131 */
132gboolean mix_acp_copy(MixParams* target, const MixParams *src)
133{
134  if (MIX_IS_AUDIOCONFIGPARAMS(target) && MIX_IS_AUDIOCONFIGPARAMS(src))
135  {
136    MixAudioConfigParams *t = MIX_AUDIOCONFIGPARAMS(target);
137    MixAudioConfigParams *s = MIX_AUDIOCONFIGPARAMS(src);
138
139    t->decode_mode = s->decode_mode;
140    t->stream_name = g_strdup(s->stream_name);
141    t->audio_manager=s->audio_manager;
142    t->num_channels = s->num_channels;
143    t->bit_rate = s->bit_rate;
144    t->sample_freq = s->sample_freq;
145    t->bits_per_sample = s->bits_per_sample;
146    t->op_align = s->op_align;
147
148    // Now chainup base class
149    if (parent_class->copy)
150    {
151      return parent_class->copy(MIX_PARAMS_CAST(target), MIX_PARAMS_CAST(src));
152    }
153    else
154      return TRUE;
155  }
156  return FALSE;
157}
158
159/**
160 * mix_acp_equal:
161 * @first: first object to compare
162 * @second: seond object to compare
163 * @returns: boolean indicates if instance are equal.
164 *
165 * Copy instance data from @src to @target.
166 */
167gboolean mix_acp_equal(MixParams* first, MixParams *second)
168{
169  gboolean ret = FALSE;
170
171  if (first && second)
172  {
173    if (first == second) return TRUE;
174  }
175  else
176  {
177    // one of them is NULL.
178    return FALSE;
179  }
180
181  // members within this scope equal. chaining up.
182  MixParamsClass *klass = MIX_PARAMS_CLASS(parent_class);
183  if (klass->equal)
184    ret = parent_class->equal(first, second);
185  else
186    ret = TRUE;
187
188  if (ret && MIX_IS_AUDIOCONFIGPARAMS(first) && MIX_IS_AUDIOCONFIGPARAMS(second))
189  {
190    MixAudioConfigParams *acp1 = MIX_AUDIOCONFIGPARAMS(first);
191    MixAudioConfigParams *acp2 = MIX_AUDIOCONFIGPARAMS(second);
192
193    ret = (acp1->decode_mode == acp2->decode_mode) &&
194            (acp1->audio_manager == acp2->audio_manager) &&
195            (acp1->num_channels == acp2->num_channels) &&
196            (acp1->bit_rate == acp2->bit_rate) &&
197            (acp1->sample_freq == acp2->sample_freq) &&
198            (acp1->bits_per_sample == acp2->bits_per_sample) &&
199            (acp1->op_align == acp2->op_align) &&
200            (!g_strcmp0(acp1->stream_name, acp2->stream_name));
201            //g_strcmp0 handles NULL gracefully
202  }
203
204  return ret;
205}
206
207
208gboolean mix_acp_is_streamname_valid(MixAudioConfigParams *obj)
209{
210  if (MIX_IS_AUDIOCONFIGPARAMS(obj))
211    if ((obj->stream_name) && (obj->stream_name[0] != 0)) return TRUE;
212
213  return FALSE;
214}
215
216gchar *mix_acp_get_streamname(MixAudioConfigParams *obj)
217{
218  gchar *ret = NULL;
219  if (G_LIKELY(MIX_IS_AUDIOCONFIGPARAMS(obj)) && obj->stream_name)
220  {
221    ret = g_strdup(obj->stream_name);
222  }
223  return ret;
224}
225
226MIX_RESULT mix_acp_set_streamname(MixAudioConfigParams *obj, const gchar *streamname)
227{
228  MIX_RESULT ret = MIX_RESULT_FAIL;
229
230  if (!obj) return MIX_RESULT_NULL_PTR;
231
232  if (G_LIKELY(MIX_IS_AUDIOCONFIGPARAMS(obj)))
233  {
234    if (obj->stream_name)
235    {
236      g_free(obj->stream_name);
237      obj->stream_name = NULL;
238    }
239
240    if (streamname) obj->stream_name = g_strdup(streamname);
241
242    ret = MIX_RESULT_SUCCESS;
243  }
244  else
245  {
246    ret = MIX_RESULT_INVALID_PARAM;
247  }
248
249  return ret;
250}
251
252MixACPBPSType mix_acp_get_bps(MixAudioConfigParams *obj)
253{
254  if (G_LIKELY(obj))
255    return obj->bits_per_sample;
256  else
257    return 0;
258}
259
260MIX_RESULT mix_acp_set_bps(MixAudioConfigParams *obj, MixACPBPSType type)
261{
262  MIX_RESULT ret = MIX_RESULT_SUCCESS;
263
264  if (!obj) return MIX_RESULT_NULL_PTR;
265
266  if (G_LIKELY(MIX_IS_AUDIOCONFIGPARAMS(obj)))
267  {
268    switch (type)
269    {
270      case MIX_ACP_BPS_UNKNOWN:
271      case MIX_ACP_BPS_16:
272      case MIX_ACP_BPS_24:
273        obj->bits_per_sample = type;
274        break;
275      default:
276        ret = MIX_RESULT_INVALID_PARAM;
277        break;
278    }
279  }
280  else
281  {
282    ret = MIX_RESULT_INVALID_PARAM;
283  }
284
285  return ret;
286}
287
288
289MixACPOpAlign mix_acp_get_op_align(MixAudioConfigParams *obj)
290{
291  return (obj->op_align);
292}
293
294MIX_RESULT mix_acp_set_op_align(MixAudioConfigParams *obj, MixACPOpAlign op_align)
295{
296  MIX_RESULT ret = MIX_RESULT_SUCCESS;
297
298  if ((op_align >= MIX_ACP_OUTPUT_ALIGN_16) && (op_align < MIX_ACP_OUTPUT_ALIGN_LAST))
299    obj->op_align = op_align;
300  else ret=MIX_RESULT_INVALID_PARAM;
301
302  return ret;
303}
304
305void mix_acp_print_params(MixAudioConfigParams *obj)
306{
307    mix_log(MIX_AUDIO_COMP, MIX_LOG_LEVEL_INFO, "decode_mode: %d\n", obj->decode_mode);
308    mix_log(MIX_AUDIO_COMP, MIX_LOG_LEVEL_INFO, "stream_name: %s\n", obj->stream_name);
309    mix_log(MIX_AUDIO_COMP, MIX_LOG_LEVEL_INFO, "audio_manager: %d\n", obj->audio_manager);
310    mix_log(MIX_AUDIO_COMP, MIX_LOG_LEVEL_INFO, "num_channels: %d\n", obj->num_channels);
311    mix_log(MIX_AUDIO_COMP, MIX_LOG_LEVEL_INFO, "bit_rate: %d\n", obj->bit_rate);
312    mix_log(MIX_AUDIO_COMP, MIX_LOG_LEVEL_INFO, "sample_freq: %d\n", obj->sample_freq);
313    mix_log(MIX_AUDIO_COMP, MIX_LOG_LEVEL_INFO, "bits_per_sample: %d\n", obj->bits_per_sample);
314    mix_log(MIX_AUDIO_COMP, MIX_LOG_LEVEL_INFO, "op_align: %d\n", obj->op_align);
315
316    MixAudioConfigParamsClass *klass = MIX_AUDIOCONFIGPARAMS_GET_CLASS(obj);
317    if (klass->print_params)
318    {
319      klass->print_params(obj);
320    }
321}
322
323