export range markers patch (revisited), change selection model, copy-drag tempo+meter...
[ardour.git] / libs / ardour / sndfile_helpers.cc
1 #include <map>
2 #include <vector>
3
4 #include <sndfile.h>
5 #include <ardour/sndfile_helpers.h>
6
7 #include "i18n.h"
8
9 using std::map;
10 using namespace std;
11
12 const char * const sndfile_header_formats_strings[SNDFILE_HEADER_FORMATS+1] = {
13         N_("WAV"),
14         N_("AIFF"),
15         N_("raw (no header)"),
16         N_("PAF (Ensoniq Paris)"),
17         N_("AU (Sun/NeXT)"),
18         N_("IRCAM"),
19         N_("W64 (64 bit WAV)"),
20         0
21 };
22
23 const char* const sndfile_file_endings_strings[SNDFILE_HEADER_FORMATS+1] = {
24         N_(".wav"),
25         N_(".aiff"),
26         N_(".raw"),
27         N_(".paf"),
28         N_(".au"),
29         N_(".ircam"),
30         N_(".w64"),
31         0
32 };
33
34 int sndfile_header_formats[SNDFILE_HEADER_FORMATS] = {
35         SF_FORMAT_WAV,
36         SF_FORMAT_AIFF,
37         SF_FORMAT_RAW,
38         SF_FORMAT_PAF,
39         SF_FORMAT_AU,
40         SF_FORMAT_IRCAM,
41         SF_FORMAT_W64
42 };
43
44 const char * const sndfile_bitdepth_formats_strings[SNDFILE_BITDEPTH_FORMATS+1] = {
45         N_("16 bit"),
46         N_("24 bit"),
47         N_("32 bit"),
48         N_("8 bit"),
49         N_("float"),
50         0
51 };
52
53 int sndfile_bitdepth_formats[SNDFILE_BITDEPTH_FORMATS] = {
54         SF_FORMAT_PCM_16,
55         SF_FORMAT_PCM_24,
56         SF_FORMAT_PCM_32,
57         SF_FORMAT_PCM_S8,
58         SF_FORMAT_FLOAT
59 };
60
61 const char * const sndfile_endian_formats_strings[SNDFILE_ENDIAN_FORMATS+1] = {
62         N_("Little-endian (Intel)"),
63         N_("Big-endian (Mac)"),
64         0
65 };
66
67 int sndfile_endian_formats[SNDFILE_ENDIAN_FORMATS] = {
68         SF_ENDIAN_LITTLE,
69         SF_ENDIAN_BIG
70 };
71
72 int
73 sndfile_header_format_from_string (string str)
74 {
75         for (int n = 0; sndfile_header_formats_strings[n]; ++n) {
76                 if (str == sndfile_header_formats_strings[n]) {
77                         return sndfile_header_formats[n];
78                 }
79         }
80         return -1;
81 }
82
83 int
84 sndfile_bitdepth_format_from_string (string str)
85 {
86         for (int n = 0; sndfile_bitdepth_formats_strings[n]; ++n) {
87                 if (str == sndfile_bitdepth_formats_strings[n]) {
88                         return sndfile_bitdepth_formats[n];
89                 }
90         }
91         return -1;
92 }
93
94 int
95 sndfile_endian_format_from_string (string str)
96 {
97         for (int n = 0; sndfile_endian_formats_strings[n]; ++n) {
98                 if (str == sndfile_endian_formats_strings[n]) {
99                         return sndfile_endian_formats[n];
100                 }
101         }
102         return -1;
103 }
104
105 string
106 sndfile_file_ending_from_string (string str)
107 {
108         static vector<string> file_endings;
109
110         if (file_endings.empty()) {
111                 file_endings = internationalize((const char **) sndfile_file_endings_strings);
112         }
113
114         for (int n = 0; sndfile_header_formats_strings[n]; ++n) {
115                 if (str == sndfile_header_formats_strings[n]) {
116                         return file_endings[n];
117                 }
118         }
119         return 0;
120 }
121
122 int
123 sndfile_data_width (int format)
124 {
125         int tval = format & 0xf;
126
127         switch (tval) {
128           case SF_FORMAT_PCM_S8:
129           case SF_FORMAT_PCM_U8:
130                 return 8;
131           case SF_FORMAT_PCM_16:
132                 return 16;
133           case SF_FORMAT_PCM_24:
134                 return 24;
135           case SF_FORMAT_PCM_32:
136                 return 32;
137           case SF_FORMAT_FLOAT:
138                 return 1; // heh, heh
139           default:
140             // we don't handle anything else within ardour
141                 return 0;
142         }
143 }
144
145 string 
146 sndfile_major_format(int format)
147 {
148         static map<int, string> m;
149
150         if(m.empty()){
151                 SF_FORMAT_INFO format_info;
152                 int count;
153                 sf_command(0, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof (int));
154                 for (int i = 0; i < count; ++i){
155                         format_info.format = i;
156                         sf_command (0, SFC_GET_FORMAT_MAJOR, 
157                                         &format_info, sizeof (format_info));
158                         m[format_info.format & SF_FORMAT_TYPEMASK] = format_info.name;
159                 }
160         }
161         
162         map<int, string>::iterator p = m.find(format & SF_FORMAT_TYPEMASK);
163         if(p != m.end()){
164                 return m[format & SF_FORMAT_TYPEMASK];
165         } else {
166                 return "-Unknown-";
167         }
168 }
169
170 string
171 sndfile_minor_format(int format)
172 {
173         static map<int, string> m;
174
175         if(m.empty()){
176                 SF_FORMAT_INFO format_info;
177                 int count;
178                 sf_command(0, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof (int));
179                 for (int i = 0; i < count; ++i){
180                         format_info.format = i;
181                         sf_command (0, SFC_GET_FORMAT_SUBTYPE, 
182                                         &format_info, sizeof (format_info));
183                         m[format_info.format & SF_FORMAT_SUBMASK] = format_info.name;
184                 }
185         }
186         
187         map<int, string>::iterator p = m.find(format & SF_FORMAT_SUBMASK);
188         if(p != m.end()){
189                 return m[format & SF_FORMAT_SUBMASK];
190         } else {
191                 return "-Unknown-";
192         }
193 }