move last template doc snippets to source code and delete them
[platform/upstream/gstreamer.git] / gst-libs / gst / audio / audio.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include "audio.h"
25 #include "multichannel-enumtypes.h"
26
27 #include <gst/gststructure.h>
28
29 /**
30  * SECTION:gstaudio
31  * @short_description: Support library for audio elements
32  */
33
34 int
35 gst_audio_frame_byte_size (GstPad * pad)
36 {
37 /* calculate byte size of an audio frame
38  * this should be moved closer to the gstreamer core
39  * and be implemented for every mime type IMO
40  * returns -1 if there's an error (to avoid division by zero),
41  * or the byte size if everything's ok
42  */
43
44   int width = 0;
45   int channels = 0;
46   const GstCaps *caps = NULL;
47   GstStructure *structure;
48
49   /* get caps of pad */
50   caps = GST_PAD_CAPS (pad);
51
52   if (caps == NULL) {
53     /* ERROR: could not get caps of pad */
54     g_warning ("gstaudio: could not get caps of pad %s:%s\n",
55         GST_DEBUG_PAD_NAME (pad));
56     return 0;
57   }
58
59   structure = gst_caps_get_structure (caps, 0);
60
61   gst_structure_get_int (structure, "width", &width);
62   gst_structure_get_int (structure, "channels", &channels);
63   return (width / 8) * channels;
64 }
65
66 long
67 gst_audio_frame_length (GstPad * pad, GstBuffer * buf)
68 /* calculate length of buffer in frames
69  * this should be moved closer to the gstreamer core
70  * and be implemented for every mime type IMO
71  * returns 0 if there's an error, or the number of frames if everything's ok
72  */
73 {
74   int frame_byte_size = 0;
75
76   frame_byte_size = gst_audio_frame_byte_size (pad);
77   if (frame_byte_size == 0)
78     /* error */
79     return 0;
80   /* FIXME: this function assumes the buffer size to be a whole multiple
81    *        of the frame byte size
82    */
83   return GST_BUFFER_SIZE (buf) / frame_byte_size;
84 }
85
86 GstClockTime
87 gst_audio_duration_from_pad_buffer (GstPad * pad, GstBuffer * buf)
88 {
89 /* calculate length in nanoseconds
90  * of audio buffer buf
91  * based on capabilities of pad
92  */
93
94   long bytes = 0;
95   int width = 0;
96   int channels = 0;
97   int rate = 0;
98
99   GstClockTime length;
100
101   const GstCaps *caps = NULL;
102   GstStructure *structure;
103
104   g_assert (GST_IS_BUFFER (buf));
105   /* get caps of pad */
106   caps = GST_PAD_CAPS (pad);
107   if (caps == NULL) {
108     /* ERROR: could not get caps of pad */
109     g_warning ("gstaudio: could not get caps of pad %s:%s\n",
110         GST_DEBUG_PAD_NAME (pad));
111     length = GST_CLOCK_TIME_NONE;
112   } else {
113     structure = gst_caps_get_structure (caps, 0);
114     bytes = GST_BUFFER_SIZE (buf);
115     gst_structure_get_int (structure, "width", &width);
116     gst_structure_get_int (structure, "channels", &channels);
117     gst_structure_get_int (structure, "rate", &rate);
118
119     g_assert (bytes != 0);
120     g_assert (width != 0);
121     g_assert (channels != 0);
122     g_assert (rate != 0);
123     length = (bytes * 8 * GST_SECOND) / (rate * channels * width);
124   }
125   return length;
126 }
127
128 gboolean
129 gst_audio_is_buffer_framed (GstPad * pad, GstBuffer * buf)
130 /* check if the buffer size is a whole multiple of the frame size */
131 {
132   if (GST_BUFFER_SIZE (buf) % gst_audio_frame_byte_size (pad) == 0)
133     return TRUE;
134   else
135     return FALSE;
136 }
137
138 /* _getcaps helper functions
139  * sets structure fields to default for audio type
140  * flag determines which structure fields to set to default
141  * keep these functions in sync with the templates in audio.h
142  */
143
144 /* private helper function
145  * sets a list on the structure
146  * pass in structure, fieldname for the list, type of the list values,
147  * number of list values, and each of the values, terminating with NULL
148  */
149 static void
150 _gst_audio_structure_set_list (GstStructure * structure,
151     const gchar * fieldname, GType type, int number, ...)
152 {
153   va_list varargs;
154   GValue value = { 0 };
155   GArray *array;
156   int j;
157
158   g_return_if_fail (structure != NULL);
159
160   g_value_init (&value, GST_TYPE_LIST);
161   array = g_value_peek_pointer (&value);
162
163   va_start (varargs, number);
164
165   for (j = 0; j < number; ++j) {
166     int i;
167     gboolean b;
168
169     GValue list_value = { 0 };
170
171     switch (type) {
172       case G_TYPE_INT:
173         i = va_arg (varargs, int);
174
175         g_value_init (&list_value, G_TYPE_INT);
176         g_value_set_int (&list_value, i);
177         break;
178       case G_TYPE_BOOLEAN:
179         b = va_arg (varargs, gboolean);
180         g_value_init (&list_value, G_TYPE_BOOLEAN);
181         g_value_set_boolean (&list_value, b);
182         break;
183       default:
184         g_warning
185             ("_gst_audio_structure_set_list: LIST of given type not implemented.");
186     }
187     g_array_append_val (array, list_value);
188
189   }
190   gst_structure_set_value (structure, fieldname, &value);
191   va_end (varargs);
192 }
193
194 void
195 gst_audio_structure_set_int (GstStructure * structure, GstAudioFieldFlag flag)
196 {
197   if (flag & GST_AUDIO_FIELD_RATE)
198     gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT,
199         NULL);
200   if (flag & GST_AUDIO_FIELD_CHANNELS)
201     gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT,
202         NULL);
203   if (flag & GST_AUDIO_FIELD_ENDIANNESS)
204     _gst_audio_structure_set_list (structure, "endianness", G_TYPE_INT, 2,
205         G_LITTLE_ENDIAN, G_BIG_ENDIAN, NULL);
206   if (flag & GST_AUDIO_FIELD_WIDTH)
207     _gst_audio_structure_set_list (structure, "width", G_TYPE_INT, 3, 8, 16, 32,
208         NULL);
209   if (flag & GST_AUDIO_FIELD_DEPTH)
210     gst_structure_set (structure, "depth", GST_TYPE_INT_RANGE, 1, 32, NULL);
211   if (flag & GST_AUDIO_FIELD_SIGNED)
212     _gst_audio_structure_set_list (structure, "signed", G_TYPE_BOOLEAN, 2, TRUE,
213         FALSE, NULL);
214 }