/* * note.cpp - implementation of class note * * Copyright (c) 2004-2009 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program (see COPYING); if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * */ #include #include #include "note.h" #include "DetuningHelper.h" #include "templates.h" note::note( const midiTime & _length, const midiTime & _pos, int _key, volume_t _volume, panning_t _panning, DetuningHelper * _detuning ) : m_selected( false ), m_oldKey( tLimit( _key, 0, NumKeys ) ), m_oldPos( _pos ), m_oldLength( _length ), m_isPlaying( false ), m_key( tLimit( _key, 0, NumKeys ) ), m_volume( tLimit( _volume, MinVolume, MaxVolume ) ), m_panning( tLimit( _panning, PanningLeft, PanningRight ) ), m_length( _length ), m_pos( _pos ), m_detuning( NULL ) { //saveJournallingState( false ); // setJournalling( false ); if( _detuning ) { m_detuning = sharedObject::ref( _detuning ); } else { createDetuning(); } //restoreJournallingState(); } note::note( const note & _note ) : SerializingObject( _note ), m_selected( _note.m_selected ), m_oldKey( _note.m_oldKey ), m_oldPos( _note.m_oldPos ), m_oldLength( _note.m_oldLength ), m_isPlaying( _note.m_isPlaying ), m_key( _note.m_key), m_volume( _note.m_volume ), m_panning( _note.m_panning ), m_length( _note.m_length ), m_pos( _note.m_pos ), m_detuning( NULL ) { if( _note.m_detuning ) { m_detuning = sharedObject::ref( _note.m_detuning ); } else { createDetuning(); } } note::~note() { if( m_detuning ) { sharedObject::unref( m_detuning ); } } void note::setLength( const midiTime & _length ) { // addJournalEntry( journalEntry( ChangeLength, m_length - _length ) ); m_length = _length; } void note::setPos( const midiTime & _pos ) { // addJournalEntry( journalEntry( ChangePosition, m_pos - _pos ) ); m_pos = _pos; } void note::setKey( const int _key ) { const int k = tLimit( _key, 0, NumKeys ); // addJournalEntry( journalEntry( ChangeKey, m_key - k ) ); m_key = k; } void note::setVolume( const volume_t _volume ) { const volume_t v = tLimit( _volume, MinVolume, MaxVolume ); // addJournalEntry( journalEntry( ChangeVolume, (int) m_volume - v ) ); m_volume = v; } void note::setPanning( const panning_t _panning ) { const panning_t p = tLimit( _panning, PanningLeft, PanningRight ); // addJournalEntry( journalEntry( ChangePanning, (int) m_panning - p ) ); m_panning = p; } midiTime note::quantized( const midiTime & _m, const int _q_grid ) { float p = ( (float) _m / _q_grid ); if( p - floorf( p ) < 0.5f ) { return( static_cast( p ) * _q_grid ); } return( static_cast( p + 1 ) * _q_grid ); } void note::quantizeLength( const int _q_grid ) { setLength( quantized( length(), _q_grid ) ); if( length() == 0 ) { setLength( _q_grid ); } } void note::quantizePos( const int _q_grid ) { setPos( quantized( pos(), _q_grid ) ); } void note::saveSettings( QDomDocument & _doc, QDomElement & _this ) { _this.setAttribute( "key", m_key ); _this.setAttribute( "vol", m_volume ); _this.setAttribute( "pan", m_panning ); _this.setAttribute( "len", m_length ); _this.setAttribute( "pos", m_pos ); if( m_length > 0 ) { m_detuning->saveSettings( _doc, _this ); } } void note::loadSettings( const QDomElement & _this ) { const int old_key = _this.attribute( "tone" ).toInt() + _this.attribute( "oct" ).toInt() * KeysPerOctave; m_key = qMax( old_key, _this.attribute( "key" ).toInt() ); m_volume = _this.attribute( "vol" ).toInt(); m_panning = _this.attribute( "pan" ).toInt(); m_length = _this.attribute( "len" ).toInt(); m_pos = _this.attribute( "pos" ).toInt(); if( _this.hasChildNodes() ) { m_detuning->loadSettings( _this ); } } /*void note::undoStep( journalEntry & _je ) { saveJournallingState( false ); switch( static_cast( _je.actionID() ) ) { case ChangeKey: setKey( key() - _je.data().toInt() ); break; case ChangeVolume: setVolume( getVolume() - _je.data().toInt() ); break; case ChangePanning: setPanning( getPanning() - _je.data().toInt() ); break; case ChangeLength: setLength( length() - _je.data().toInt() ); break; case ChangePosition: setPos( pos() - _je.data().toInt() ); break; } restoreJournallingState(); } void note::redoStep( journalEntry & _je ) { journalEntry je( _je.actionID(), -_je.data().toInt() ); undoStep( je ); }*/ void note::editDetuningPattern() { m_detuning->automationPattern()->openInAutomationEditor(); } void note::createDetuning() { m_detuning = new DetuningHelper; (void) m_detuning->automationPattern(); m_detuning->setRange( -MaxDetuning, MaxDetuning, 0.1f ); } bool note::hasDetuningInfo() const { return m_detuning && m_detuning->hasAutomation(); }