add oversampler
This commit is contained in:
339
oversampling/WDL/scalafile.h
Normal file
339
oversampling/WDL/scalafile.h
Normal file
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
WDL - scalafile.h
|
||||
(c) Theo Niessink 2012
|
||||
<http://www.taletn.com/>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
This file provides a class for read/writing Scala scale (.scl) files.
|
||||
<http://www.huygens-fokker.org/scala/scl_format.html>
|
||||
|
||||
|
||||
Example #1:
|
||||
|
||||
// Read scale file
|
||||
|
||||
#include "scalafile.h"
|
||||
|
||||
ScalaScaleFile scl;
|
||||
scl.Open("myscale.scl");
|
||||
scl.SkipDescr();
|
||||
|
||||
int n = scl.ReadNum();
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
double pitch = scl.ReadPitch();
|
||||
if (pitch > 0.) printf("%f\n", pitch);
|
||||
}
|
||||
|
||||
Example #2:
|
||||
|
||||
// Write (create) scale file
|
||||
|
||||
#include "scalafile.h"
|
||||
#include <math.h>
|
||||
|
||||
ScalaScaleFile scl;
|
||||
char* filename = "newscale.scl";
|
||||
scl.Create(filename);
|
||||
scl.WriteFilename(filename);
|
||||
scl.WriteDescr("New scale");
|
||||
|
||||
int n = 12;
|
||||
scl.WriteNum(n);
|
||||
for (int i = 1; i < n; ++i)
|
||||
{
|
||||
scl.WriteCents((double)(i * 100));
|
||||
}
|
||||
scl.WriteRatio(2, 1 , "octave");
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _WDL_SCALA_FILE_H_
|
||||
#define _WDL_SCALA_FILE_H_
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
class ScalaScaleFile
|
||||
{
|
||||
public:
|
||||
ScalaScaleFile(): m_fp(NULL) {}
|
||||
|
||||
~ScalaScaleFile()
|
||||
{
|
||||
if (m_fp) fclose(m_fp);
|
||||
}
|
||||
|
||||
bool Open(const char* filename)
|
||||
{
|
||||
m_fp = fopen(filename, "rb");
|
||||
m_buf = EOF;
|
||||
return (bool)m_fp;
|
||||
}
|
||||
|
||||
int ReadDescr(char* buf, int size)
|
||||
{
|
||||
int c = SkipComments();
|
||||
if (c == EOF) return 0;
|
||||
|
||||
int n = 0;
|
||||
while (c != '\n' && c != EOF)
|
||||
{
|
||||
if (++n < size) *buf++ = c;
|
||||
c = GetChar();
|
||||
}
|
||||
|
||||
if (size) *buf = '\0';
|
||||
return ++n;
|
||||
}
|
||||
|
||||
inline int SkipDescr()
|
||||
{
|
||||
return ReadDescr(NULL, 0);
|
||||
}
|
||||
|
||||
int ReadNum()
|
||||
{
|
||||
const int err = -1;
|
||||
|
||||
char buf[16];
|
||||
if (!ReadVal(buf, sizeof(buf))) return err;
|
||||
|
||||
return atoi(buf);
|
||||
}
|
||||
|
||||
double ReadPitch()
|
||||
{
|
||||
const double err = 0.;
|
||||
|
||||
char buf[32];
|
||||
if (!ReadVal(buf, sizeof(buf))) return err;
|
||||
|
||||
double pitch;
|
||||
if (strchr(buf, '.'))
|
||||
{
|
||||
double cents = atof(buf);
|
||||
pitch = pow(2., cents / 1200.);
|
||||
}
|
||||
else
|
||||
{
|
||||
int num = atoi(buf);
|
||||
if (num <= 0) return err;
|
||||
char* slash = strchr(buf, '/');
|
||||
if (slash)
|
||||
{
|
||||
int denom = atoi(slash + 1);
|
||||
if (denom <= 0) return err;
|
||||
pitch = (double)num / (double)denom;
|
||||
}
|
||||
else
|
||||
{
|
||||
pitch = (double)num;
|
||||
}
|
||||
}
|
||||
|
||||
return pitch;
|
||||
}
|
||||
|
||||
bool Create(const char* filename)
|
||||
{
|
||||
if (m_fp) fclose(m_fp);
|
||||
m_fp = fopen(filename, "w");
|
||||
return (bool)m_fp;
|
||||
}
|
||||
|
||||
inline int WriteComment(const char* buf)
|
||||
{
|
||||
return m_fp ? WriteLine(buf) : -1;
|
||||
}
|
||||
|
||||
int WriteFilename(const char* filename)
|
||||
{
|
||||
if (!m_fp) return -1;
|
||||
|
||||
int ret = fputs("! ", m_fp);
|
||||
|
||||
if (ret >= 0)
|
||||
{
|
||||
const char* p = filename + strlen(filename);
|
||||
while (--p >= filename && *p != '\\' && *p != '/');
|
||||
ret = fputs(++p, m_fp);
|
||||
}
|
||||
|
||||
if (ret >= 0) ret = fputs("\n", m_fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline int WriteDescr(const char* buf)
|
||||
{
|
||||
return m_fp ? WriteLine(buf) : -1;
|
||||
}
|
||||
|
||||
int WriteNum(int num)
|
||||
{
|
||||
if (!m_fp) return -1;
|
||||
return fprintf(m_fp, "%d\n", num);
|
||||
}
|
||||
|
||||
int WriteCents(double cents, const char* comment = NULL)
|
||||
{
|
||||
if (!m_fp) return -1;
|
||||
return WritePitchComment(fprintf(m_fp, "%0.5f", cents), comment);
|
||||
}
|
||||
|
||||
int WriteRatio(int num, int denom, const char* comment = NULL)
|
||||
{
|
||||
if (!m_fp) return -1;
|
||||
return WritePitchComment(fprintf(m_fp, "%d/%d", num, denom), comment);
|
||||
}
|
||||
|
||||
int WritePitch(double pitch, const char* comment = NULL)
|
||||
{
|
||||
if (!m_fp) return -1;
|
||||
|
||||
double i;
|
||||
int ret;
|
||||
if (modf(pitch, &i) == 0.)
|
||||
ret = fprintf(m_fp, "%0.0f/1", i);
|
||||
else
|
||||
ret = fprintf(m_fp, "%0.5f", log(pitch) / log(2.) * 1200.);
|
||||
|
||||
return WritePitchComment(ret, comment);
|
||||
}
|
||||
|
||||
int Close()
|
||||
{
|
||||
if (m_fp)
|
||||
{
|
||||
if (fclose(m_fp)) return EOF;
|
||||
m_fp = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
int GetChar()
|
||||
{
|
||||
int c = m_buf;
|
||||
if (c != EOF)
|
||||
{
|
||||
m_buf = EOF;
|
||||
return c;
|
||||
}
|
||||
|
||||
c = m_fp ? fgetc(m_fp) : EOF;
|
||||
if (c == EOF) return c;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\r':
|
||||
m_buf = fgetc(m_fp);
|
||||
if (m_buf == '\n') m_buf = EOF;
|
||||
c = '\n';
|
||||
break;
|
||||
case '\n':
|
||||
m_buf = fgetc(m_fp);
|
||||
if (m_buf == '\r') m_buf = EOF;
|
||||
break;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
int SkipComments()
|
||||
{
|
||||
int c = GetChar();
|
||||
while (c == '!')
|
||||
{
|
||||
do
|
||||
{
|
||||
c = GetChar();
|
||||
if (c == EOF) return c;
|
||||
} while (c != '\n');
|
||||
c = GetChar();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
int ReadVal(char* buf, int size)
|
||||
{
|
||||
int c = SkipComments();
|
||||
if (c == EOF) return 0;
|
||||
|
||||
int n = 0;
|
||||
bool ignore = false;
|
||||
while (c != '\n' && c != EOF)
|
||||
{
|
||||
if (!ignore)
|
||||
{
|
||||
if (c != ' ' && c != '\t')
|
||||
{
|
||||
if (++n < size) *buf++ = c;
|
||||
}
|
||||
else if (n)
|
||||
{
|
||||
ignore = true;
|
||||
}
|
||||
}
|
||||
c = GetChar();
|
||||
}
|
||||
if (n >= size) return 0;
|
||||
|
||||
*buf = '\0';
|
||||
return ++n;
|
||||
}
|
||||
|
||||
int WriteLine(const char* buf)
|
||||
{
|
||||
// if (!m_fp) return -1;
|
||||
|
||||
if (buf)
|
||||
{
|
||||
int ret = fputs(buf, m_fp);
|
||||
if (ret < 0) return ret;
|
||||
}
|
||||
|
||||
return fputs("\n", m_fp);
|
||||
}
|
||||
|
||||
int WritePitchComment(int ret, const char* comment)
|
||||
{
|
||||
// if (!m_fp) return -1;
|
||||
|
||||
if (comment && ret >= 0)
|
||||
{
|
||||
ret = fputs(" ", m_fp);
|
||||
if (ret >= 0) ret = fputs(comment, m_fp);
|
||||
}
|
||||
|
||||
if (ret >= 0) ret = fputs("\n", m_fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
FILE* m_fp;
|
||||
int m_buf;
|
||||
};
|
||||
|
||||
|
||||
#endif // _WDL_SCALA_FILE_H_
|
||||
Reference in New Issue
Block a user