fix input metering:
[ardour.git] / libs / ardour / sndfile_helpers.cc
1 /*
2     Copyright (C) 2000-2007 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program 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
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <strings.h>
21 #include <map>
22
23 #include <sndfile.h>
24 #include "ardour/sndfile_helpers.h"
25
26 #include "i18n.h"
27
28 using std::map;
29 using namespace std;
30
31 const char * const sndfile_header_formats_strings[SNDFILE_HEADER_FORMATS+1] = {
32         N_("WAV"),
33         N_("AIFF"),
34         N_("CAF"),
35         N_("W64 (64 bit WAV)"),
36         N_("FLAC"),
37         N_("Ogg/Vorbis"),
38         N_("raw (no header)"),
39         0
40 };
41
42 const char* const sndfile_file_endings_strings[SNDFILE_HEADER_FORMATS+1] = {
43         N_(".wav"),
44         N_(".aiff"),
45         N_(".caf"),
46         N_(".w64"),
47         N_(".flac"),
48         N_(".ogg"),
49         N_(".raw"),
50         0
51 };
52
53 int sndfile_header_formats[SNDFILE_HEADER_FORMATS] = {
54         SF_FORMAT_WAV,
55         SF_FORMAT_AIFF,
56         SF_FORMAT_CAF,
57         SF_FORMAT_W64,
58         SF_FORMAT_FLAC,
59         SF_FORMAT_OGG,
60         SF_FORMAT_RAW
61 };
62
63 const char * const sndfile_bitdepth_formats_strings[SNDFILE_BITDEPTH_FORMATS+1] = {
64         N_("Signed 16 bit PCM"),
65         N_("Signed 24 bit PCM"),
66         N_("Signed 32 bit PCM"),
67         N_("Signed 8 bit PCM"),
68         N_("32 bit float"),
69         0
70 };
71
72 int sndfile_bitdepth_formats[SNDFILE_BITDEPTH_FORMATS] = {
73         SF_FORMAT_PCM_16,
74         SF_FORMAT_PCM_24,
75         SF_FORMAT_PCM_32,
76         SF_FORMAT_PCM_S8,
77         SF_FORMAT_FLOAT
78 };
79
80 const char * const sndfile_endian_formats_strings[SNDFILE_ENDIAN_FORMATS+1] = {
81         N_("Little-endian (Intel)"),
82         N_("Big-endian (PowerPC)"),
83         0
84 };
85
86 int sndfile_endian_formats[SNDFILE_ENDIAN_FORMATS] = {
87         SF_ENDIAN_LITTLE,
88         SF_ENDIAN_BIG
89 };
90
91 int
92 sndfile_header_format_by_index (int index)
93 {
94         if (index >= 0 && index < SNDFILE_HEADER_FORMATS) {
95                 return sndfile_header_formats[index];
96         }
97         return -1;
98 }
99
100 int
101 sndfile_bitdepth_format_by_index (int index)
102 {
103         if (index >= 0 && index < SNDFILE_BITDEPTH_FORMATS) {
104                 return sndfile_bitdepth_formats[index];
105         }
106         return -1;
107 }
108
109 int
110 sndfile_endian_format_by_index (int index)
111 {
112         if (index >= 0 && index < SNDFILE_ENDIAN_FORMATS) {
113                 return sndfile_endian_formats[index];
114         }
115         return -1;
116 }
117
118 int
119 sndfile_data_width (int format)
120 {
121         int tval = format & 0xf;
122
123         switch (tval) {
124           case SF_FORMAT_PCM_S8:
125           case SF_FORMAT_PCM_U8:
126                 return 8;
127           case SF_FORMAT_PCM_16:
128                 return 16;
129           case SF_FORMAT_PCM_24:
130                 return 24;
131           case SF_FORMAT_PCM_32:
132                 return 32;
133           case SF_FORMAT_FLOAT:
134                 return 1; // heh, heh
135           default:
136             // we don't handle anything else within ardour
137                 return 0;
138         }
139 }
140
141 string
142 sndfile_major_format(int format)
143 {
144         static map<int, string> m;
145
146         if(m.empty()){
147                 SF_FORMAT_INFO format_info;
148                 int count;
149                 sf_command(0, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof (int));
150                 for (int i = 0; i < count; ++i){
151                         format_info.format = i;
152                         sf_command (0, SFC_GET_FORMAT_MAJOR,
153                                         &format_info, sizeof (format_info));
154                         m[format_info.format & SF_FORMAT_TYPEMASK] = format_info.name;
155
156                         /* normalize a couple of names rather than use what libsndfile gives us */
157
158                         if (strncasecmp (format_info.name, "OGG", 3) == 0) {
159                                 m[format_info.format & SF_FORMAT_TYPEMASK] = "Ogg";
160                         } else if (strncasecmp (format_info.name, "WAV", 3) == 0) {
161                                 m[format_info.format & SF_FORMAT_TYPEMASK] = "WAV";
162                         } else {
163                                 m[format_info.format & SF_FORMAT_TYPEMASK] = format_info.name;
164                         }
165                 }
166         }
167
168         map<int, string>::iterator p = m.find(format & SF_FORMAT_TYPEMASK);
169         if(p != m.end()){
170                 return m[format & SF_FORMAT_TYPEMASK];
171         } else {
172                 return "-Unknown-";
173         }
174 }
175
176 string
177 sndfile_minor_format(int format)
178 {
179         static map<int, string> m;
180
181         if(m.empty()){
182                 SF_FORMAT_INFO format_info;
183                 int count;
184                 sf_command(0, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof (int));
185                 for (int i = 0; i < count; ++i){
186                         format_info.format = i;
187                         sf_command (0, SFC_GET_FORMAT_SUBTYPE,
188                                         &format_info, sizeof (format_info));
189                         m[format_info.format & SF_FORMAT_SUBMASK] = format_info.name;
190                 }
191         }
192
193         map<int, string>::iterator p = m.find(format & SF_FORMAT_SUBMASK);
194         if(p != m.end()){
195                 return m[format & SF_FORMAT_SUBMASK];
196         } else {
197                 return "-Unknown-";
198         }
199 }
200