Remove unnecessary 0 checks before delete; see http://www.parashift.com/c++-faq-lite...
[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 <map>
21 #include <vector>
22
23 #include <pbd/convert.h>
24
25 #include <sndfile.h>
26 #include <ardour/sndfile_helpers.h>
27
28 #include "i18n.h"
29
30 using std::map;
31 using namespace std;
32
33 const char * const sndfile_header_formats_strings[SNDFILE_HEADER_FORMATS+1] = {
34         N_("WAV"),
35         N_("AIFF"),
36         N_("CAF"),
37         N_("W64 (64 bit WAV)"),
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_(".raw"),
48         0
49 };
50
51 int sndfile_header_formats[SNDFILE_HEADER_FORMATS] = {
52         SF_FORMAT_WAV,
53         SF_FORMAT_AIFF,
54         SF_FORMAT_CAF,
55         SF_FORMAT_W64,
56         SF_FORMAT_RAW
57 };
58
59 const char * const sndfile_bitdepth_formats_strings[SNDFILE_BITDEPTH_FORMATS+1] = {
60         N_("Signed 16 bit PCM"),
61         N_("Signed 24 bit PCM"),
62         N_("Signed 32 bit PCM"),
63         N_("Signed 8 bit PCM"),
64         N_("32 bit float"),
65         0
66 };
67
68 int sndfile_bitdepth_formats[SNDFILE_BITDEPTH_FORMATS] = {
69         SF_FORMAT_PCM_16,
70         SF_FORMAT_PCM_24,
71         SF_FORMAT_PCM_32,
72         SF_FORMAT_PCM_S8,
73         SF_FORMAT_FLOAT
74 };
75
76 const char * const sndfile_endian_formats_strings[SNDFILE_ENDIAN_FORMATS+1] = {
77         N_("Little-endian (Intel)"),
78         N_("Big-endian (Mac)"),
79         0
80 };
81
82 int sndfile_endian_formats[SNDFILE_ENDIAN_FORMATS] = {
83         SF_ENDIAN_LITTLE,
84         SF_ENDIAN_BIG
85 };
86
87 int
88 sndfile_header_format_from_string (string str)
89 {
90         for (int n = 0; sndfile_header_formats_strings[n]; ++n) {
91                 if (str == sndfile_header_formats_strings[n]) {
92                         return sndfile_header_formats[n];
93                 }
94         }
95         return -1;
96 }
97
98 int
99 sndfile_bitdepth_format_from_string (string str)
100 {
101         for (int n = 0; sndfile_bitdepth_formats_strings[n]; ++n) {
102                 if (str == sndfile_bitdepth_formats_strings[n]) {
103                         return sndfile_bitdepth_formats[n];
104                 }
105         }
106         return -1;
107 }
108
109 int
110 sndfile_endian_format_from_string (string str)
111 {
112         for (int n = 0; sndfile_endian_formats_strings[n]; ++n) {
113                 if (str == sndfile_endian_formats_strings[n]) {
114                         return sndfile_endian_formats[n];
115                 }
116         }
117         return -1;
118 }
119
120 string
121 sndfile_file_ending_from_string (string str)
122 {       
123         static vector<string> file_endings;
124
125         if (file_endings.empty()) {
126                 file_endings = I18N((const char **) sndfile_file_endings_strings);
127         }
128
129         for (int n = 0; sndfile_header_formats_strings[n]; ++n) {
130                 if (str == sndfile_header_formats_strings[n]) {
131                         return file_endings[n];
132                 }
133         }
134         return 0;
135 }
136
137 int
138 sndfile_data_width (int format)
139 {
140         int tval = format & 0xf;
141
142         switch (tval) {
143           case SF_FORMAT_PCM_S8:
144           case SF_FORMAT_PCM_U8:
145                 return 8;
146           case SF_FORMAT_PCM_16:
147                 return 16;
148           case SF_FORMAT_PCM_24:
149                 return 24;
150           case SF_FORMAT_PCM_32:
151                 return 32;
152           case SF_FORMAT_FLOAT:
153                 return 1; // heh, heh
154           default:
155             // we don't handle anything else within ardour
156                 return 0;
157         }
158 }
159
160 string 
161 sndfile_major_format(int format)
162 {
163         static map<int, string> m;
164
165         if(m.empty()){
166                 SF_FORMAT_INFO format_info;
167                 int count;
168                 sf_command(0, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof (int));
169                 for (int i = 0; i < count; ++i){
170                         format_info.format = i;
171                         sf_command (0, SFC_GET_FORMAT_MAJOR, 
172                                         &format_info, sizeof (format_info));
173                         m[format_info.format & SF_FORMAT_TYPEMASK] = format_info.name;
174                 }
175         }
176         
177         map<int, string>::iterator p = m.find(format & SF_FORMAT_TYPEMASK);
178         if(p != m.end()){
179                 return m[format & SF_FORMAT_TYPEMASK];
180         } else {
181                 return "-Unknown-";
182         }
183 }
184
185 string
186 sndfile_minor_format(int format)
187 {
188         static map<int, string> m;
189
190         if(m.empty()){
191                 SF_FORMAT_INFO format_info;
192                 int count;
193                 sf_command(0, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof (int));
194                 for (int i = 0; i < count; ++i){
195                         format_info.format = i;
196                         sf_command (0, SFC_GET_FORMAT_SUBTYPE, 
197                                         &format_info, sizeof (format_info));
198                         m[format_info.format & SF_FORMAT_SUBMASK] = format_info.name;
199                 }
200         }
201         
202         map<int, string>::iterator p = m.find(format & SF_FORMAT_SUBMASK);
203         if(p != m.end()){
204                 return m[format & SF_FORMAT_SUBMASK];
205         } else {
206                 return "-Unknown-";
207         }
208 }
209