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
Rosegarden-devel@lists.sourceforge.net - use the link below to unsubscribe
https://lists.sourceforge.net/lists/listinfo/rosegarden-devel

Reply via email to