update plists MACOSX_DEPLOYMENT_TARGET = 10.7.0
[wdl/wdl-ol.git] / WDL / scalafile.h
blob1b7a8b16a13e0965d7f29840d5b17181a59dd961
1 /*
2 WDL - scalafile.h
3 (c) Theo Niessink 2012
4 <http://www.taletn.com/>
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
14 1. The origin of this software must not be misrepresented; you must not
15 claim that you wrote the original software. If you use this software
16 in a product, an acknowledgment in the product documentation would be
17 appreciated but is not required.
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source distribution.
23 This file provides a class for read/writing Scala scale (.scl) files.
24 <http://www.huygens-fokker.org/scala/scl_format.html>
27 Example #1:
29 // Read scale file
31 #include "scalafile.h"
33 ScalaScaleFile scl;
34 scl.Open("myscale.scl");
35 scl.SkipDescr();
37 int n = scl.ReadNum();
38 for (int i = 0; i < n; ++i)
40 double pitch = scl.ReadPitch();
41 if (pitch > 0.) printf("%f\n", pitch);
44 Example #2:
46 // Write (create) scale file
48 #include "scalafile.h"
49 #include <math.h>
51 ScalaScaleFile scl;
52 char* filename = "newscale.scl";
53 scl.Create(filename);
54 scl.WriteFilename(filename);
55 scl.WriteDescr("New scale");
57 int n = 12;
58 scl.WriteNum(n);
59 for (int i = 1; i < n; ++i)
61 scl.WriteCents((double)(i * 100));
63 scl.WriteRatio(2, 1 , "octave");
68 #ifndef _WDL_SCALA_FILE_H_
69 #define _WDL_SCALA_FILE_H_
72 #include <math.h>
73 #include <stdio.h>
74 #include <stdlib.h>
75 #include <string.h>
78 class ScalaScaleFile
80 public:
81 ScalaScaleFile(): m_fp(NULL) {}
83 ~ScalaScaleFile()
85 if (m_fp) fclose(m_fp);
88 bool Open(const char* filename)
90 m_fp = fopen(filename, "rb");
91 m_buf = EOF;
92 return (bool)m_fp;
95 int ReadDescr(char* buf, int size)
97 int c = SkipComments();
98 if (c == EOF) return 0;
100 int n = 0;
101 while (c != '\n' && c != EOF)
103 if (++n < size) *buf++ = c;
104 c = GetChar();
107 if (size) *buf = '\0';
108 return ++n;
111 inline int SkipDescr()
113 return ReadDescr(NULL, 0);
116 int ReadNum()
118 const int err = -1;
120 char buf[16];
121 if (!ReadVal(buf, sizeof(buf))) return err;
123 return atoi(buf);
126 double ReadPitch()
128 const double err = 0.;
130 char buf[32];
131 if (!ReadVal(buf, sizeof(buf))) return err;
133 double pitch;
134 if (strchr(buf, '.'))
136 double cents = atof(buf);
137 pitch = pow(2., cents / 1200.);
139 else
141 int num = atoi(buf);
142 if (num <= 0) return err;
143 char* slash = strchr(buf, '/');
144 if (slash)
146 int denom = atoi(slash + 1);
147 if (denom <= 0) return err;
148 pitch = (double)num / (double)denom;
150 else
152 pitch = (double)num;
156 return pitch;
159 bool Create(const char* filename)
161 if (m_fp) fclose(m_fp);
162 m_fp = fopen(filename, "w");
163 return (bool)m_fp;
166 inline int WriteComment(const char* buf)
168 return m_fp ? WriteLine(buf) : -1;
171 int WriteFilename(const char* filename)
173 if (!m_fp) return -1;
175 int ret = fputs("! ", m_fp);
177 if (ret >= 0)
179 const char* p = filename + strlen(filename);
180 while (--p >= filename && *p != '\\' && *p != '/');
181 ret = fputs(++p, m_fp);
184 if (ret >= 0) ret = fputs("\n", m_fp);
185 return ret;
188 inline int WriteDescr(const char* buf)
190 return m_fp ? WriteLine(buf) : -1;
193 int WriteNum(int num)
195 if (!m_fp) return -1;
196 return fprintf(m_fp, "%d\n", num);
199 int WriteCents(double cents, const char* comment = NULL)
201 if (!m_fp) return -1;
202 return WritePitchComment(fprintf(m_fp, "%0.5f", cents), comment);
205 int WriteRatio(int num, int denom, const char* comment = NULL)
207 if (!m_fp) return -1;
208 return WritePitchComment(fprintf(m_fp, "%d/%d", num, denom), comment);
211 int WritePitch(double pitch, const char* comment = NULL)
213 if (!m_fp) return -1;
215 double i;
216 int ret;
217 if (modf(pitch, &i) == 0.)
218 ret = fprintf(m_fp, "%0.0f/1", i);
219 else
220 ret = fprintf(m_fp, "%0.5f", log(pitch) / log(2.) * 1200.);
222 return WritePitchComment(ret, comment);
225 int Close()
227 if (m_fp)
229 if (fclose(m_fp)) return EOF;
230 m_fp = NULL;
232 return 0;
235 protected:
236 int GetChar()
238 int c = m_buf;
239 if (c != EOF)
241 m_buf = EOF;
242 return c;
245 c = m_fp ? fgetc(m_fp) : EOF;
246 if (c == EOF) return c;
248 switch (c)
250 case '\r':
251 m_buf = fgetc(m_fp);
252 if (m_buf == '\n') m_buf = EOF;
253 c = '\n';
254 break;
255 case '\n':
256 m_buf = fgetc(m_fp);
257 if (m_buf == '\r') m_buf = EOF;
258 break;
261 return c;
264 int SkipComments()
266 int c = GetChar();
267 while (c == '!')
271 c = GetChar();
272 if (c == EOF) return c;
273 } while (c != '\n');
274 c = GetChar();
276 return c;
279 int ReadVal(char* buf, int size)
281 int c = SkipComments();
282 if (c == EOF) return 0;
284 int n = 0;
285 bool ignore = false;
286 while (c != '\n' && c != EOF)
288 if (!ignore)
290 if (c != ' ' && c != '\t')
292 if (++n < size) *buf++ = c;
294 else if (n)
296 ignore = true;
299 c = GetChar();
301 if (n >= size) return 0;
303 *buf = '\0';
304 return ++n;
307 int WriteLine(const char* buf)
309 // if (!m_fp) return -1;
311 if (buf)
313 int ret = fputs(buf, m_fp);
314 if (ret < 0) return ret;
317 return fputs("\n", m_fp);
320 int WritePitchComment(int ret, const char* comment)
322 // if (!m_fp) return -1;
324 if (comment && ret >= 0)
326 ret = fputs(" ", m_fp);
327 if (ret >= 0) ret = fputs(comment, m_fp);
330 if (ret >= 0) ret = fputs("\n", m_fp);
331 return ret;
334 FILE* m_fp;
335 int m_buf;
339 #endif // _WDL_SCALA_FILE_H_