audioconvert.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of Libav.
5  *
6  * Libav 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  * Libav 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  * You should have received a copy of the GNU Lesser General Public
17  * License along with Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
26 #include "avstring.h"
27 #include "avutil.h"
28 #include "audioconvert.h"
29 
30 static const char * const channel_names[] = {
31  [0] = "FL", /* front left */
32  [1] = "FR", /* front right */
33  [2] = "FC", /* front center */
34  [3] = "LFE", /* low frequency */
35  [4] = "BL", /* back left */
36  [5] = "BR", /* back right */
37  [6] = "FLC", /* front left-of-center */
38  [7] = "FRC", /* front right-of-center */
39  [8] = "BC", /* back-center */
40  [9] = "SL", /* side left */
41  [10] = "SR", /* side right */
42  [11] = "TC", /* top center */
43  [12] = "TFL", /* top front left */
44  [13] = "TFC", /* top front center */
45  [14] = "TFR", /* top front right */
46  [15] = "TBL", /* top back left */
47  [16] = "TBC", /* top back center */
48  [17] = "TBR", /* top back right */
49  [29] = "DL", /* downmix left */
50  [30] = "DR", /* downmix right */
51 };
52 
53 static const char *get_channel_name(int channel_id)
54 {
55  if (channel_id < 0 || channel_id >= FF_ARRAY_ELEMS(channel_names))
56  return NULL;
57  return channel_names[channel_id];
58 }
59 
60 static const struct {
61  const char *name;
63  uint64_t layout;
64 } channel_layout_map[] = {
65  { "mono", 1, AV_CH_LAYOUT_MONO },
66  { "stereo", 2, AV_CH_LAYOUT_STEREO },
67  { "4.0", 4, AV_CH_LAYOUT_4POINT0 },
68  { "quad", 4, AV_CH_LAYOUT_QUAD },
69  { "5.0", 5, AV_CH_LAYOUT_5POINT0 },
70  { "5.0", 5, AV_CH_LAYOUT_5POINT0_BACK },
71  { "5.1", 6, AV_CH_LAYOUT_5POINT1 },
72  { "5.1", 6, AV_CH_LAYOUT_5POINT1_BACK },
74  { "7.1", 8, AV_CH_LAYOUT_7POINT1 },
75  { "7.1(wide)", 8, AV_CH_LAYOUT_7POINT1_WIDE },
76  { "7.1+downmix", 10, AV_CH_LAYOUT_7POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX, },
77  { 0 }
78 };
79 
80 uint64_t av_get_channel_layout(const char *name)
81 {
82  int i = 0;
83  do {
84  if (!strcmp(channel_layout_map[i].name, name))
85  return channel_layout_map[i].layout;
86  i++;
87  } while (channel_layout_map[i].name);
88 
89  return 0;
90 }
91 
92 void av_get_channel_layout_string(char *buf, int buf_size,
93  int nb_channels, uint64_t channel_layout)
94 {
95  int i;
96 
97  if (nb_channels <= 0)
98  nb_channels = av_get_channel_layout_nb_channels(channel_layout);
99 
100  for (i = 0; channel_layout_map[i].name; i++)
101  if (nb_channels == channel_layout_map[i].nb_channels &&
102  channel_layout == channel_layout_map[i].layout) {
103  av_strlcpy(buf, channel_layout_map[i].name, buf_size);
104  return;
105  }
106 
107  snprintf(buf, buf_size, "%d channels", nb_channels);
108  if (channel_layout) {
109  int i, ch;
110  av_strlcat(buf, " (", buf_size);
111  for (i = 0, ch = 0; i < 64; i++) {
112  if ((channel_layout & (UINT64_C(1) << i))) {
113  const char *name = get_channel_name(i);
114  if (name) {
115  if (ch > 0)
116  av_strlcat(buf, "|", buf_size);
117  av_strlcat(buf, name, buf_size);
118  }
119  ch++;
120  }
121  }
122  av_strlcat(buf, ")", buf_size);
123  }
124 }
125 
126 int av_get_channel_layout_nb_channels(uint64_t channel_layout)
127 {
128  int count;
129  uint64_t x = channel_layout;
130  for (count = 0; x; count++)
131  x &= x-1; // unset lowest set bit
132  return count;
133 }