On 04/03/11 10:50, Graham Percival wrote:
> PATCH 2:
My apologies; that patch does not compile. Please consider this one
instead.
PATCH 2:
+ src/sound/Tunings .h .cpp
+ data/pitches/tunings
=== src/base/NotationTypes .h .cpp
// no other files modified
The change to the existing src/base/NotationTypes just adds stuff like
ThreeQuartersFlat.
Cheers,
- Graham
Index: src/sound/Tuning.cpp
===================================================================
--- src/sound/Tuning.cpp (revision 0)
+++ src/sound/Tuning.cpp (revision 0)
@@ -0,0 +1,601 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+
+/*
+ Rosegarden
+ A MIDI and audio sequencer and musical notation editor.
+ Copyright 2000-2009 the Rosegarden development team.
+
+ Other copyrights also apply to some parts of this work. Please
+ see the AUTHORS file and individual file headers for details.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. See the file
+ COPYING included with this distribution for more information.
+*/
+
+#include "Tuning.h"
+
+#include "base/NotationTypes.h"
+#include "gui/general/ResourceFinder.h"
+
+#include <QtDebug>
+
+#include <stdlib.h>
+#include <qfile.h>
+#include <qstring.h>
+#include <iostream>
+#include <qtextstream.h>
+#include <math.h>
+#include <string>
+
+// Set the debug level to:
+//
+// 1: summary printout of tunings after they've been read (default)
+// 2: detail while parsing tunings file (verbose)
+#define TUNING_DEBUG 1
+
+/* What follows is a good example of why one should use lex+yacc etc
+ to parse files!! NJB, 2010 */
+
+using namespace Rosegarden::Accidentals;
+
+// Map accidental number to accidental string
+const Tuning::AccMap::value_type Tuning::accMapData[] = {
+ AccMap::value_type(-4, &DoubleFlat),
+ AccMap::value_type(-3, &ThreeQuarterFlat),
+ AccMap::value_type(-2, &Flat),
+ AccMap::value_type(-1, &QuarterFlat),
+ AccMap::value_type(0, &NoAccidental),
+ AccMap::value_type(1, &QuarterSharp),
+ AccMap::value_type(2, &Sharp),
+ AccMap::value_type(3, &ThreeQuarterSharp),
+ AccMap::value_type(4, &DoubleSharp)
+};
+const unsigned int Tuning::accMapSize =
+ sizeof(Tuning::accMapData) / sizeof(Tuning::accMapData[0]);
+Tuning::AccMap Tuning::accMap(Tuning::accMapData,
+ Tuning::accMapData + Tuning::accMapSize);
+
+std::vector<Tuning*> Tuning::m_tunings;
+
+std::vector<Tuning*> *Tuning::getTunings() {
+
+ // if already have tunings, return them
+ // TODO: It would be polite to check the mtime on the tunings file
+ // and to re-read it if it's been changed. For now, you need
+ // to restart Rosegarden.
+ if (m_tunings.size())
+ return &m_tunings;
+
+ QString tuningsPath = ResourceFinder().getResourcePath("pitches", "tunings");
+ # if (TUNING_DEBUG > 1)
+ qDebug() << "Path to tunings file:" << tuningsPath;
+ # endif
+ QFile fin(tuningsPath);
+
+ IntervalList *intervals = new IntervalList;
+ SpellingList *spellings = new SpellingList;
+
+ if (fin.open(IO_ReadOnly) ) {
+ bool inTuningDefinition = false;
+ int lineNumber = 0;
+ QString line = QString::null;
+ QTextStream stream( &fin );
+ QString tuningName;
+
+ while(!stream.atEnd()) {
+ line = stream.readLine();
+ lineNumber++;
+ line = line.stripWhiteSpace();
+# if (TUNING_DEBUG > 1)
+ qDebug()<<lineNumber<<line;
+# endif
+
+ // ignore comments or blanks
+ if (line.isEmpty() || line.at(0) == '#' || line.at(0) == '!')
+ continue;
+
+ // Tuning declaration
+ else if (line.startsWith(QString("Tuning"), false)) {
+ if (inTuningDefinition) {
+# if (TUNING_DEBUG > 1)
+ qDebug() << "End of tuning" << tuningName;
+# endif
+ std::string name = tuningName.ascii();
+ Tuning *newTuning = new Tuning(name, intervals, spellings);
+ m_tunings.push_back(newTuning);
+# if (TUNING_DEBUG)
+ newTuning->printTuning();
+# endif
+ intervals = new IntervalList;
+ spellings = new SpellingList;
+ }
+
+ // Remove tuning keyword and get name from remainder of line
+ line.remove( 0, 6 );
+ line = line.stripWhiteSpace();
+
+ tuningName = line;
+ inTuningDefinition = true;
+
+# if (TUNING_DEBUG > 1)
+ qDebug() << "\nNew Tuning: " << tuningName;
+# endif
+ }
+
+ // Must be a note line
+ else {
+ bool ok;
+ int commaPos;
+
+ // is cents or ratio
+
+ // get cents
+ double cents;
+ commaPos = line.find(QChar(','));
+ QString intervalString = line;
+ intervalString.remove(commaPos, intervalString.length() - commaPos);
+ intervalString = intervalString.stripWhiteSpace();
+ int dotPos = intervalString.find(QChar('.'));
+ if (dotPos == -1) { // interval is a ratio
+# if (TUNING_DEBUG > 1)
+ qDebug() << "Interval is a ratio";
+# endif
+ int slashPos = intervalString.find(QChar('/'));
+ double ratio=1;
+ if (slashPos == -1) { // interval is integer ratio
+# if (TUNING_DEBUG > 1)
+ qDebug() << "Ratio is an integer";
+# endif
+ ratio = intervalString.toInt( &ok );
+ if (!ok) {
+ std::cerr << "Syntax Error in tunings file, line "
+ << lineNumber << std::endl;
+ continue;
+ } else {
+ //convert ratio to cents
+ QString numeratorString = intervalString;
+ numeratorString.remove(slashPos,
+ numeratorString.length()
+ - slashPos);
+# if (TUNING_DEBUG > 1)
+ qDebug() << "numerator" << numeratorString;
+# endif
+ int numerator = numeratorString.toInt( &ok );
+ if (!ok) {
+ std::cerr << "Syntax Error in tunings file, "
+ "line " << lineNumber << std::endl;
+ continue;
+ }
+ QString denominatorString = intervalString;
+ denominatorString.remove( 0, slashPos+1 );
+# if (TUNING_DEBUG > 1)
+ qDebug() << "d" << denominatorString;
+# endif
+ int denominator = denominatorString.toInt( &ok );
+ if (!ok) {
+ std::cerr << "Syntax Error in tunings file, "
+ "line " << lineNumber << std::endl;
+ continue;
+ }
+
+# if (TUNING_DEBUG > 1)
+ qDebug() << "Ratio:" << numeratorString
+ << "/" << denominatorString;
+# endif
+
+ ratio = (double)numerator / (double)denominator;
+
+
+ //calculate cents
+ cents = 1200.0 * log( ratio )/log(2.0);
+# if (TUNING_DEBUG > 1)
+ qDebug() << "cents" << cents;
+# endif
+ }
+ }
+ } else { // interval is in cents
+# if (TUNING_DEBUG > 1)
+ qDebug() << "Interval is in cents";
+# endif
+ cents = intervalString.toDouble(&ok);
+ if (!ok) {
+ std::cerr << "Syntax Error in tunings file, line "
+ << lineNumber << std::endl;
+ continue;
+ }
+# if (TUNING_DEBUG > 1)
+ qDebug() << "Cents: " << cents;
+# endif
+ }
+
+ //add intervals to interval list
+ intervals->push_back(cents);
+
+ //remove interval
+ line.remove(0, commaPos+1);
+
+
+ // get various spellings
+ while (!line.isEmpty()) {
+ line = line.stripWhiteSpace();
+ commaPos = line.find(QChar(','));
+ // Maybe there isn't alternate spelling, or
+ // maybe there's a naughty trailing comma
+ if (commaPos == -1 || commaPos == line.length()-1){
+# if (TUNING_DEBUG > 1)
+ qDebug() << "var:" << line;
+# endif
+ QString note = line;
+ QString acc = note;
+ acc.remove(0, 1);
+ note.remove(1, note.length()-1);
+# if (TUNING_DEBUG > 1)
+ qDebug() << "Acc " << acc << "\nPitch Class " << note;
+# endif
+ if (acc.toInt() != 0) {
+ const int acc_i = atoi(acc.latin1());
+ note.append(accMap[acc_i]->c_str());
+ }
+ //insert into spelling list
+ spellings->insert(Spelling(note.ascii(),
+ intervals->size()-1));
+
+ line = QString::null;
+# if (TUNING_DEBUG > 1)
+ qDebug() << "Translated variation:" << note << "\n";
+# endif
+ } else {
+ QString note = line;
+ note.remove(commaPos, note.length()-commaPos);
+ QString acc = note;
+ acc.remove(0, 1);
+ note.remove(1, note.length()-1);
+# if (TUNING_DEBUG > 1)
+ qDebug() << "Acc" << acc << "\nPitch Class " << note;
+# endif
+ if (acc.toInt() != 0) {
+ const int acc_i = atoi(acc.latin1());
+ note.append(accMap[acc_i]->c_str());
+ }
+ line.remove( 0, commaPos+1 );
+
+ //insert into spelling list
+ spellings->insert(Spelling(note.ascii(),
+ intervals->size()-1));
+
+# if (TUNING_DEBUG > 1)
+ qDebug() << "Translated variation" << note;
+# endif
+ }
+ }
+# if (TUNING_DEBUG > 1)
+ qDebug("\n");
+# endif
+ }
+
+ }
+ fin.close();
+ if (inTuningDefinition) {
+# if (TUNING_DEBUG > 1)
+ qDebug() << "End of tuning" << tuningName;
+# endif
+ Tuning *new_tuning = new Tuning(tuningName.ascii(), intervals, spellings);
+ m_tunings.push_back(new_tuning);
+# if (TUNING_DEBUG)
+ new_tuning->printTuning();
+# endif
+ }
+ return &m_tunings;
+ }
+
+ std::cerr << "Fatal: Cannot find tunings file!" << std::endl;
+ return NULL;
+}
+
+
+Tuning::Tuning(std::string name, IntervalList *intervals,
+ SpellingList *spellings) :
+ m_rootPitch(9, 3),
+ m_refPitch(9, 3),
+ m_intervals(intervals),
+ m_spellings(spellings)
+{
+ m_name = name;
+
+# if (TUNING_DEBUG > 1)
+ qDebug() << "Given name:" << name.c_str() << &name;
+ qDebug() << "Stored name:" << m_name.c_str() << &m_name;
+# endif
+
+ m_size = intervals->size();
+
+ //check interval & spelling list sizes match
+ for (SpellingListIterator it = spellings->begin();
+ it != spellings->end();
+ it++) {
+ if (it->second > m_size) {
+ std::cerr << "Spelling list does not match "
+ "number of intervals!"
+ << std::endl;
+ spellings->erase( it );
+ }
+ }
+
+
+ Rosegarden::Pitch p(9, 3);
+
+
+ //default A3 = 440;
+ setRootPitch(p);
+ setRefNote(p, 440);
+}
+
+Tuning::Tuning(const Tuning *tuning) :
+ m_rootPitch(tuning->getRootPitch()),
+ m_refPitch(tuning->getRefPitch()),
+ m_intervals(tuning->getIntervalList()),
+ m_spellings(tuning->getSpellingList())
+{
+ m_size = m_intervals->size();
+ m_name = tuning->getName();
+# if (TUNING_DEBUG > 1)
+ qDebug() << "Given name:" << tuning->getName().c_str();
+ qDebug() << "Stored name: " << m_name.c_str() << &m_name;
+# endif
+
+ //default A3 = 440;
+ Rosegarden::Pitch p=tuning->getRefPitch();
+ Rosegarden::Pitch p2=tuning->getRootPitch();
+
+ setRootPitch(tuning->getRootPitch());
+ setRefNote(p, tuning->getRefFreq());
+
+ Rosegarden::Key keyofc; // use key of C to obtain unbiased accidental
+
+ std::cout << "Ref note " << p.getNoteName(keyofc)
+ << p.getDisplayAccidental( keyofc )
+ << " " << m_refFreq << std::endl;
+
+ std::cout << "Ref note " << m_refPitch.getNoteName(keyofc)
+ << m_refPitch.getDisplayAccidental( keyofc )
+ << " " << m_refFreq << std::endl;
+
+ std::cout << "Ref freq for C " << m_cRefFreq << std::endl;
+
+ std::cout << "Root note " << p2.getNoteName(keyofc)
+ << p2.getDisplayAccidental(keyofc)
+ << std::endl;
+ std::cout << "Root note " << m_rootPitch.getNoteName(keyofc)
+ << m_rootPitch.getDisplayAccidental(keyofc)
+ << std::endl;
+}
+
+
+
+
+void Tuning::setRootPitch(Rosegarden::Pitch pitch){
+
+ m_rootPitch = pitch;
+
+ std::string spelling = getSpelling( pitch );;
+ const SpellingListIterator sit = m_spellings->find(spelling);
+ if (sit == m_spellings->end()){
+ std::cerr << "\nFatal: Tuning::setRootPitch root pitch "
+ "not found in tuning!!" << std::endl;
+ return;
+ }
+# if (TUNING_DEBUG > 1)
+ qDebug() << "Root position" << m_rootPosition;
+# endif
+ m_rootPosition = sit->second;
+}
+
+
+std::string Tuning::getSpelling(Rosegarden::Pitch &pitch) const {
+
+
+ const Rosegarden::Key key;
+
+ QChar qc(pitch.getNoteName(key));
+ QString spelling(qc);
+
+ Rosegarden::Accidental acc = pitch.getDisplayAccidental(key);
+ if (acc != Rosegarden::Accidentals::NoAccidental &&
+ acc != Rosegarden::Accidentals::Natural) {
+ spelling.append(acc.c_str());
+ }
+
+ return spelling.ascii();
+}
+
+
+void Tuning::setRefNote(Rosegarden::Pitch pitch, double freq) {
+
+ m_refPitch = pitch;
+ m_refFreq = freq;
+ m_refOctave = pitch.getOctave();
+ std::string spelling = getSpelling(pitch);
+
+ // position in chromatic scale
+ SpellingListIterator it = m_spellings->find(spelling);
+ if (it == m_spellings->end()) {
+ std::cerr << "Tuning::setRefNote Spelling " << spelling
+ << " not found in " << m_name
+ << " tuning!" << std::endl;
+ return;
+ }
+ int refPosition = it->second;
+
+ // calculate frequency for C in reference octave
+ // this makes calculation of frequencies easier
+
+ it = m_spellings->find("C");
+ if (it == m_spellings->end()){
+ std::cerr << "Tuning::setRefNote 'C' not found in "
+ << m_name << " tuning!\n";
+ return;
+ }
+
+ m_cPosition = it->second;
+
+ // find position of C relative to root note
+ int cInterval = m_cPosition - m_rootPosition;
+ if (cInterval < 0) cInterval += m_size;
+
+ // cents above root note for C
+ double cents = (*m_intervals)[cInterval];
+
+ // cents above root note for reference note
+ int refInterval = refPosition - m_rootPosition;
+ if( refInterval < 0 ) refInterval += m_size;
+
+ double refCents = (*m_intervals)[refInterval];
+
+ // relative cents from reference note to target note
+ double relativeCents = cents - refCents;
+ if (relativeCents > 0) relativeCents -= 1200;
+
+ //frequency ratio between reference and target notes
+ double ratio = pow( 2, relativeCents/1200 );
+
+ m_cRefFreq = m_refFreq * ratio;
+
+# if (TUNING_DEBUG)
+ qDebug() << "c Position" << m_cPosition
+ << "\nc interval" << cInterval
+ << "\nc Cents" << cents
+ << "\nref position" << refPosition
+ << "\nref interval" << refInterval
+ << "\nref Cents" << refCents
+ << "\nc freq" << m_cRefFreq
+ << "\nref octave" << m_refOctave;
+# endif
+}
+
+/**
+* Returns the frequency of the given pitch in the current tuning.
+*/
+double Tuning::getFrequency(Rosegarden::Pitch p) const {
+
+ // make note spelling
+ std::string spelling = getSpelling(p);
+
+ int octave = p.getOctave();
+
+ // position in chromatic scale
+ const SpellingListIterator it = m_spellings->find(spelling);
+ if (it == m_spellings->end()) {
+ std::cerr << "Tuning::getFreq Spelling '" << spelling
+ << "' not found in " << m_name << " tuning!\n";
+ return 0;
+ }
+ int position = it->second;
+
+ // find position relative to root note
+ int relativePosition = position - m_rootPosition;
+ if (relativePosition < 0) relativePosition += m_size;
+
+ // cents above root note for target note
+ double cents = (*m_intervals)[relativePosition];
+
+ // cents above root note for reference note ( C )
+ int refInterval = m_cPosition - m_rootPosition;
+ if (refInterval < 0) refInterval += m_size;
+ double refCents = (*m_intervals)[refInterval];
+
+ // relative cents from reference note to target note
+ double relativeCents = cents - refCents;
+ if (relativeCents < 0) relativeCents += 1200;
+
+ //frequency ratio between reference and target notes
+ double ratio = pow(2, relativeCents/1200);
+
+ /*
+ B# occurs in the same octave as the C immediatley above them.
+ In 12ET this is true, but not in all tunings.
+ Solution: When B# and C are not equivalent spellings,
+ decrement the octave of every B#.
+ */
+ if (spelling == "Bsharp" && position != m_cPosition) {
+ octave--;
+ }
+
+ int octaveDifference = octave - m_refOctave;
+
+ int octaveRatio = pow( 2, octaveDifference );
+
+ ratio *= octaveRatio;
+
+ double freq = m_cRefFreq * ratio;
+
+# if (TUNING_DEBUG)
+ qDebug() << "Spelling " << spelling.c_str()
+ << "\ntarget position " << position
+ << "\nroot position " << m_rootPosition
+ << "\ntarget interval " << relativePosition
+ << "\ncents above root note " << cents
+ << "\ninterval for C " << refInterval
+ << "\ncents from reference note " << refCents
+ << "\ncents from reference to target" << relativeCents
+ << "\nrefOctave " << m_refOctave
+ << "\noctave " << octave
+ << "\noctave ratio " << octaveRatio
+ << "\nratio " << ratio
+ << "\nref freq " << m_refFreq
+ << "\nfreq " << freq;
+# endif
+
+ return freq;
+}
+
+/**
+* Prints to std out for debugging
+*/
+void Tuning::printTuning() const {
+
+ std::cout << "Print Tuning\n";
+ std::cout << "Name: '" << m_name << "'\n";
+
+ Rosegarden::Key keyofc; // use key of C to obtain unbiased accidental
+
+ std::cout << "Ref note " << m_refPitch.getNoteName(keyofc)
+ << m_refPitch.getDisplayAccidental( keyofc )
+ << " " << m_refFreq << std::endl;
+
+ std::cout << "Ref freq for C " << m_cRefFreq << std::endl;
+
+ std::cout << "Root note " << m_rootPitch.getNoteName(keyofc)
+ << m_rootPitch.getDisplayAccidental( keyofc )
+ << std::endl;
+
+ for (SpellingListIterator sit = m_spellings->begin();
+ sit != m_spellings->end();
+ sit++) {
+
+ std::cout << "Spelling '" << sit->first
+ << "'\tinterval " << sit->second
+ << std::endl;
+
+ }
+
+ for(unsigned int i=0; i < m_intervals->size(); i++) {
+ std::cout << "Interval '" << i
+ << "'\tinterval " << m_intervals->at(i)
+ << std::endl;
+ }
+
+ std::cout << "Done." << std::endl;
+
+}
+
+
+Rosegarden::Pitch Tuning::getRootPitch() const { return m_rootPitch; }
+Rosegarden::Pitch Tuning::getRefPitch() const { return m_refPitch; }
+double Tuning::getRefFreq() const{ return m_refFreq; }
+const std::string Tuning::getName() const { return m_name; }
+SpellingList *Tuning::getSpellingList() const{ return m_spellings; }
+IntervalList *Tuning::getIntervalList() const{ return m_intervals; }
+
Index: src/sound/Tuning.h
===================================================================
--- src/sound/Tuning.h (revision 0)
+++ src/sound/Tuning.h (revision 0)
@@ -0,0 +1,119 @@
+
+#ifndef TUNING_H_
+#define TUNING_H_
+
+
+#include <vector>
+#include <string>
+#include <map>
+
+#include "base/NotationTypes.h"
+
+//!!! Q: Should this class be using QString and QVector also?
+//!!! A: A definite "probably". We use the Qt classes in the
+//!!! PitchDetector, but that is RG specific. This code is
+//!!! more use in other n-ism projects, and is easier to
+//!!! break (more head-scratching, less boiler-plate) so
+//!!! for now it's implemented with the std:: classes. - njb
+
+typedef std::pair< std::string, int > Spelling;
+typedef std::map< std::string, int > SpellingList;
+typedef SpellingList::iterator SpellingListIterator;
+typedef std::vector< double > IntervalList;
+typedef std::vector< double >::iterator IntervalListIterator;
+
+namespace Rosegarden {
+namespace Accidentals {
+
+/**
+ * \addtogroup Codicil
+ * \@{
+ * \brief Read the Codicil's tunings file and create a tunings database
+ *
+ * This is part of the Glasgow Center for Music Technology's
+ * "Rosegarden Codicil" project.
+ * http://www.n-ism.org/Projects/microtonalism.php
+ *
+ * \author Dougie McGilvray, Nick Bailey
+ * \date 2010
+ */
+class Tuning {
+
+ public:
+
+ /**
+ * \brief Construct a tuning from its name, and interval and spellings.
+ *
+ * \param name Name of the new tuning
+ * \param intervals List of intervals in cents from the root pitch
+ * \param spellings List of spellings (enharmonic equivalents) for each pitch
+ */
+ Tuning(std::string name, IntervalList *intervals,
+ SpellingList *spellings);
+ Tuning(const Tuning *tuning);
+
+ /**
+ * \brief Access the vector of tunings known to the system
+ */
+ static std::vector<Tuning*>* getTunings();
+
+ /**
+ * \brief Set the frequency associated with the reference pitch
+ *
+ * \param pitch The reference pitch
+ * \param freq Associated frequency (in Hz)
+ */
+ void setRefNote(Rosegarden::Pitch pitch, double freq);
+
+ /**
+ * \brief Nominate the root pitch for this tuning
+ *
+ * \param pitch The root pitch
+ */
+ void setRootPitch(Rosegarden::Pitch pitch);
+
+ /**
+ * \brief Calculate a frequency
+ *
+ * \param pitch The pitch for which a frequency is required
+ * \return Frequency in Hz.
+ */
+ double getFrequency(Rosegarden::Pitch pitch) const;
+
+ const std::string getName() const; /**< Get the Tuning's name */
+ SpellingList *getSpellingList() const; /**< Get the enharmonic spellings */
+ IntervalList *getIntervalList() const; /**< Get the intervals in cents*/
+ Rosegarden::Pitch getRootPitch() const; /**< Get the root pitch */
+ Rosegarden::Pitch getRefPitch() const; /**< Get the reference pitch */
+ double getRefFreq() const; /**< Get the reference frequency */
+ void printTuning() const; /**< Print the Tuning (debugging) */
+
+ protected:
+
+ /** Converts pitch to string */
+ std::string getSpelling(Rosegarden::Pitch &pitch) const;
+ std::string m_name;
+ Rosegarden::Pitch m_rootPitch;
+ int m_rootPosition;
+ Rosegarden::Pitch m_refPitch;
+ int m_refOctave;
+ int m_cPosition;
+ double m_refFreq;
+ double m_cRefFreq;
+ int m_size;
+ IntervalList *m_intervals;
+ SpellingList *m_spellings;
+
+ typedef std::map<const int, const Accidental *> AccMap;
+ static AccMap accMap;
+ static const unsigned int accMapSize;
+ static const AccMap::value_type accMapData[];
+ static std::vector<Tuning*> m_tunings;
+};
+
+} // end of namespace Accidentals
+} // end of namespace Rosegarden
+
+/**\@}*/
+
+#endif
Index: src/base/NotationTypes.h
===================================================================
--- src/base/NotationTypes.h (revision 12260)
+++ src/base/NotationTypes.h (working copy)
@@ -83,6 +83,10 @@
extern const Accidental Natural;
extern const Accidental DoubleSharp;
extern const Accidental DoubleFlat;
+ extern const Accidental QuarterFlat;
+ extern const Accidental ThreeQuarterFlat;
+ extern const Accidental QuarterSharp;
+ extern const Accidental ThreeQuarterSharp;
typedef std::vector<Accidental> AccidentalList;
Index: src/base/NotationTypes.cpp
===================================================================
--- src/base/NotationTypes.cpp (revision 12260)
+++ src/base/NotationTypes.cpp (working copy)
@@ -56,7 +56,13 @@
const Accidental Natural = "natural";
const Accidental DoubleSharp = "double-sharp";
const Accidental DoubleFlat = "double-flat";
-
+
+ // Additional Accidentals for demi- and sesqui- sharps and flats
+ const Accidental QuarterFlat = "demiflat";
+ const Accidental ThreeQuarterFlat = "sesqiflat";
+ const Accidental QuarterSharp = "demisharp";
+ const Accidental ThreeQuarterSharp = "sesquisharp";
+
AccidentalList getStandardAccidentals() {
static Accidental a[] = {
Index: data/pitches/tunings
===================================================================
--- data/pitches/tunings (revision 0)
+++ data/pitches/tunings (revision 0)
@@ -0,0 +1,61 @@
+
+# Define tunings for the Rosegarden Pitch Tracker here.
+
+#System
+#(name of system)
+#Tuning (tuning of system)
+#
+#(chromatic note number), (note spelling), (spelling variation)
+#(chromatic note number), (note spelling), (spelling variation)
+#
+# etc..
+#
+#endSystem
+
+# Note Spelling
+# Rosegarden denotes microtonal accidentals by changing the value of controller 127.
+# The values are:
+# -4 double flat, -3 triplesemiflat, -2 flat, -1 semiflat
+# 4 double sharp, 3 triplesemisharp, 2 sharp, 1 semisharp
+# Therefore a B semisharp is B1.
+#
+
+
+Tuning 12ET
+# cents spelling
+0.0, A, B-4, G4
+100.0, A2, B-2, C-4
+200.0, B, A4, C-2
+300.0, C, D-4, B2
+400.0, C2, D-2
+500.0, D, E-4, C4
+600.0, D2, E-2
+700.0, E, F-2, D4
+800.0, F, G-4. E2
+900.0, F2, G-2
+1000.0, G, A-4, F4
+1100.0, G2, A-2
+
+Tuning 19 ET
+# cents, spelling
+0.0, A
+63.158, A2, B-4
+126.316, B-2, A4
+189.474, B
+252.632, B2, C-2
+315.789, C
+378.947, C2, D-4
+442.105, D-2, C4
+505.263, D
+568.421, D2, E-4
+631.579, E-2, D4
+694.737, E
+757.895, E2, F-2
+821.053, F
+884.211, F2, G-4
+947.368, G-2, F4
+1010.526, G
+1073.684, G2, A-4
+1136.842, A-2, G4
+
+
------------------------------------------------------------------------------
What You Don't Know About Data Connectivity CAN Hurt You
This paper provides an overview of data connectivity, details
its effect on application quality, and explores various alternative
solutions. http://p.sf.net/sfu/progress-d2d
_______________________________________________
Rosegarden-devel mailing list
[email protected] - use the link below to unsubscribe
https://lists.sourceforge.net/lists/listinfo/rosegarden-devel