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>
31 #include "scalafile.h"
34 scl.Open("myscale.scl");
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);
46 // Write (create) scale file
48 #include "scalafile.h"
52 char* filename = "newscale.scl";
54 scl.WriteFilename(filename);
55 scl.WriteDescr("New scale");
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_
81 ScalaScaleFile(): m_fp(NULL
) {}
85 if (m_fp
) fclose(m_fp
);
88 bool Open(const char* filename
)
90 m_fp
= fopen(filename
, "rb");
95 int ReadDescr(char* buf
, int size
)
97 int c
= SkipComments();
98 if (c
== EOF
) return 0;
101 while (c
!= '\n' && c
!= EOF
)
103 if (++n
< size
) *buf
++ = c
;
107 if (size
) *buf
= '\0';
111 inline int SkipDescr()
113 return ReadDescr(NULL
, 0);
121 if (!ReadVal(buf
, sizeof(buf
))) return err
;
128 const double err
= 0.;
131 if (!ReadVal(buf
, sizeof(buf
))) return err
;
134 if (strchr(buf
, '.'))
136 double cents
= atof(buf
);
137 pitch
= pow(2., cents
/ 1200.);
142 if (num
<= 0) return err
;
143 char* slash
= strchr(buf
, '/');
146 int denom
= atoi(slash
+ 1);
147 if (denom
<= 0) return err
;
148 pitch
= (double)num
/ (double)denom
;
159 bool Create(const char* filename
)
161 if (m_fp
) fclose(m_fp
);
162 m_fp
= fopen(filename
, "w");
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
);
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
);
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;
217 if (modf(pitch
, &i
) == 0.)
218 ret
= fprintf(m_fp
, "%0.0f/1", i
);
220 ret
= fprintf(m_fp
, "%0.5f", log(pitch
) / log(2.) * 1200.);
222 return WritePitchComment(ret
, comment
);
229 if (fclose(m_fp
)) return EOF
;
245 c
= m_fp
? fgetc(m_fp
) : EOF
;
246 if (c
== EOF
) return c
;
252 if (m_buf
== '\n') m_buf
= EOF
;
257 if (m_buf
== '\r') m_buf
= EOF
;
272 if (c
== EOF
) return c
;
279 int ReadVal(char* buf
, int size
)
281 int c
= SkipComments();
282 if (c
== EOF
) return 0;
286 while (c
!= '\n' && c
!= EOF
)
290 if (c
!= ' ' && c
!= '\t')
292 if (++n
< size
) *buf
++ = c
;
301 if (n
>= size
) return 0;
307 int WriteLine(const char* buf
)
309 // if (!m_fp) return -1;
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
);
339 #endif // _WDL_SCALA_FILE_H_