Planeshift
|
00001 /* 00002 * scoreelements.h, Author: Andrea Rizzi <[email protected]> 00003 * 00004 * Copyright (C) 2001-2013 Atomic Blue ([email protected], http://www.atomicblue.org) 00005 * 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU General Public License 00009 * as published by the Free Software Foundation (version 2 of the License) 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 * 00018 */ 00019 00020 #ifndef SCORE_ELEMENTS_H 00021 #define SCORE_ELEMENTS_H 00022 00023 00024 //==================================================================================== 00025 // Crystal Space Includes 00026 //==================================================================================== 00027 #include <cssysdef.h> 00028 #include <csutil/hash.h> 00029 00030 //==================================================================================== 00031 // Project Includes 00032 //==================================================================================== 00033 00034 //==================================================================================== 00035 // Local Includes 00036 //==================================================================================== 00037 #include "musicutil.h" 00038 00039 //------------------------------------------------------------------------------------ 00040 // Forward Declarations 00041 //------------------------------------------------------------------------------------ 00042 // A chord rarely have more than 6 notes 00043 #define MEAS_ELEM_NOTES_CAPACITY_GROWTH 4 00044 #define UNDEFINED_MEASURE_ATTRIBUTE -100 00045 00046 class ScoreContext; 00047 class MeasureElement; 00048 00056 class Note 00057 { 00058 public: 00064 class NoteContext 00065 { 00066 public: 00070 NoteContext(); 00071 00080 psMusic::Accidental GetPreviousAccidental(const Note ¬e) const; 00081 00085 void ResetContext(); 00086 00093 void UpdateContext(const MeasureElement &element); 00094 00100 void UpdateContext(const Note ¬e); 00101 00102 private: 00107 csHash<csHash<psMusic::Accidental, char>, int> prevAccidentals; 00108 }; 00109 00113 Note(); 00114 00126 Note(char name, int octave, psMusic::Accidental writtenAccidental); 00127 00133 char GetName() const { return name; } 00134 00141 int GetOctave() const { return octave; } 00142 00152 psMusic::Accidental GetPlayedAccidental(const ScoreContext &context) const; 00153 00159 psMusic::Accidental GetWrittenAccidental() const { return writtenAccidental; } 00160 00167 bool operator==(const Note ¬e) const; 00168 00174 void SetName(char name); 00175 00182 void SetOctave(int octave); 00183 00189 void SetWrittenAccidental(psMusic::Accidental accidental); 00190 00191 private: 00192 char name; 00193 int octave; 00194 00200 psMusic::Accidental writtenAccidental; 00201 }; 00202 00203 //-------------------------------------------------- 00204 00209 class MeasureElement 00210 { 00211 public: 00217 MeasureElement(psMusic::Duration duration); 00218 00229 bool AddNote(char name, int octave, psMusic::Accidental writtenAccidental); 00230 00236 psMusic::Duration GetDuration() { return duration; } 00237 00243 size_t GetNNotes() const { return notes.GetSize(); } 00244 00251 Note &GetNote(size_t n) { return notes[n]; } 00252 00256 const Note &GetNote(size_t n) const { return notes[n]; } 00257 00263 bool IsRest() const { return notes.GetSize() == 0; } 00264 00271 bool RemoveNote(char name, int octave); 00272 00278 void SetDuration(psMusic::Duration duration) { this->duration = duration; } 00279 00283 void SetRest() { notes.Empty(); } 00284 00285 private: 00286 psMusic::Duration duration; 00287 00288 typedef csArrayCapacityFixedGrow<MEAS_ELEM_NOTES_CAPACITY_GROWTH> NotesArrayCapacity; 00289 csArray<Note, csArrayElementHandler<Note>, CS::Container::ArrayAllocDefault, 00290 NotesArrayCapacity> notes; 00291 }; 00292 00293 //-------------------------------------------------- 00294 00298 template<typename MeasureElementType> 00299 class Measure 00300 { 00301 public: 00302 00309 class MeasureAttributes 00310 { 00311 public: 00315 MeasureAttributes(); 00316 00322 int GetBeats() const { return beats; } 00323 00329 int GetBeatType() const { return beatType; } 00330 00337 int GetFifths() const { return fifths; } 00338 00344 int GetTempo() const { return tempo; } 00345 00351 bool IsUndefined() const; 00352 00358 void SetBeats(int beats) { this->beats = beats; } 00359 00365 void SetBeatType(int beatType) { this->beatType = beatType; } 00366 00373 void SetFifths(int fifths) { this->fifths = fifths; } 00374 00380 void SetTempo(int tempo) { this->tempo = tempo; } 00381 00388 void UpdateAttributes(const MeasureAttributes &attributes); 00389 00390 private: 00391 int tempo; 00392 int beats; 00393 int beatType; 00394 00399 int fifths; 00400 }; 00401 00405 Measure(); 00406 00410 ~Measure(); 00411 00417 void DeleteElement(size_t n) { elements.DeleteIndex(n); } 00418 00422 void DeleteAllElements() { elements.Empty(); } 00423 00435 void Fit(const MeasureAttributes* const attributes); 00436 00442 MeasureAttributes GetAttributes() const; 00443 00450 MeasureElementType &GetElement(size_t n) { return elements[n]; } 00451 00455 const MeasureElementType &GetElement(size_t n) const { return elements[n]; } 00456 00462 size_t GetNElements() const { return elements.GetSize(); } 00463 00470 int GetNEndRepeat() const { return nEndRepeat; } 00471 00479 void InsertElement(size_t n, const MeasureElementType &element); 00480 00486 bool IsEmpty() const { return elements.GetSize() == 0; } 00487 00493 bool IsEnding() const { return isEnding; } 00494 00500 bool IsEndRepeat() const { return nEndRepeat > 0; } 00501 00507 bool IsStartRepeat() const { return isStartRepeat; } 00508 00515 size_t PushElement(const MeasureElementType &element) 00516 { 00517 return elements.Push(element); 00518 } 00519 00527 void SetBeat(int beats, int beatType); 00528 00534 void SetEnding(bool isEnding); 00535 00539 void SetFifths(int fifths); 00540 00547 void SetNEndRepeat(int nEndRepeat); 00548 00554 void SetStartRepeat(bool isStartRepeat); 00555 00559 void SetTempo(int tempo); 00560 00561 private: 00562 bool isEnding; 00563 bool isStartRepeat; 00564 int nEndRepeat; 00565 csArray<MeasureElementType> elements; 00566 00571 MeasureAttributes* attributes; 00572 00576 void CreateAttributes(); 00577 00581 void DeleteAttributes(); 00582 00586 void UpdateAttributes(); 00587 }; 00588 00589 //-------------------------------------------------- 00590 00596 class ScoreContext 00597 { 00598 public: 00602 Note::NoteContext noteContext; 00603 00607 Measure<MeasureElement>::MeasureAttributes measureAttributes; 00608 00612 ScoreContext(); 00613 00621 int GetNPerformedRepeats(int measureID) const; 00622 00630 int RestoreLastStartRepeat(); 00631 00640 void Update(int measureID, const Measure<MeasureElement> &measure); 00641 00647 void Update(const MeasureElement &element); 00648 00649 private: 00650 int lastStartRepeatID; 00651 00656 Measure<MeasureElement>::MeasureAttributes lastStartRepeatAttributes; 00657 00662 csHash<int, int> repeatsDone; 00663 }; 00664 00665 #include "scoreelements.hpp" 00666 00669 #endif // SCORE_ELEMENTS_H