1 /** 2 * This file is part of the Web Enabled Audio and Sound Enhancement Library (aka the Weasel audio library) Copyright 2011 - 2013 Warren Willmey. It is covered by the GNU General Public License version 3 as published by the Free Software Foundation, you should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. 3 */ 4 5 if( undefined == window.weasel ) window.weasel = {}; 6 7 // --------------------------------------------------------------------------- 8 /** Create a Mahoney & Kaktus's Noisetracker 2.0 module out of the provided data (which has already passed the module sniffer test). 9 * 10 * @constructor 11 * @extends weasel.NoiseTracker11 12 * 13 * @param {Array|Uint8Array} aModuleData = The Mahoney & Kaktus Noisetracker 2.0 module as a byte array that MUST have passed the module sniffer test. 14 * @param {int} iPlaybackFrequency = The playback frequency in hertz to use (e.g. 44100 ). 15 * @param {weasel.Sample.prototype.SampleScannerMode} iSampleScannerMode = Scan for IFF Header corruption residue?. 16 * 17 * @author Warren Willmey 2013 18 */ 19 weasel.NoiseTracker20 = function( aModuleData, iPlaybackFrequency, iSampleScannerMode ) 20 { 21 this.parent = weasel.NoiseTracker11; 22 23 // Needed for prototype Inheritance. 24 // 25 if( aModuleData === undefined || !(( aModuleData instanceof Array ) || ( window.Uint8Array && aModuleData instanceof Uint8Array )) ) 26 return; 27 28 29 this.parent( aModuleData, iPlaybackFrequency, iSampleScannerMode ); 30 31 // Set Noisetracker 2.0 Vibrato mode. 32 // 33 this.setVibratoMode( true ); 34 this.sModuleType = weasel.ModuleSniffer.prototype.SupportedModules.NoiseTracker20; 35 36 }; 37 38 weasel.NoiseTracker20.prototype = new weasel.NoiseTracker11; 39 40 // --------------------------------------------------------------------------- 41 /** Sequence table tick speed reader, reads tick speed from pattern during . 42 * 43 * @param {int} iEffectData = The effect data of the pattern cell. 44 * 45 * @return {int} The Tick Speed. 46 * 47 * @protected 48 * @override 49 */ 50 weasel.NoiseTracker20.prototype._sequenceTableTickSpeedReader = function( iEffectData ) 51 { 52 if( iEffectData > 31 ) 53 return 31; 54 else if( iEffectData <= 0 ) 55 return 1; 56 else 57 return iEffectData; 58 }; 59 60 // --------------------------------------------------------------------------- 61 /** Set the row tick speed. 62 * 63 * @param {int} iTickSpeed = The new row tick speed to use (0-31), a value of 0 is converted into a value of 1. 64 * 65 * @override 66 */ 67 weasel.NoiseTracker20.prototype.setTickSpeed = function( iTickSpeed ) 68 { 69 this.iTickSpeed = this._sequenceTableTickSpeedReader( iTickSpeed ); 70 }; 71 72 // --------------------------------------------------------------------------- 73 /** Some Soundtrackers have effects that need processing out of the normal order, 74 * such as the Note Portamento command in Noisetracker. 75 * 76 * @param {weasel.Channel} oChannel = The Channel to process for effects. 77 * @param {int} iNotePeriod = The note period yet to be set for this oChannel object. 78 * 79 * @return {bool} = false : the fetch row process should continue for this oChannel object, 80 * true : stop the fetch row process for this oChannel object but continue for the other channels.. 81 * 82 * @protected 83 * @override 84 */ 85 weasel.NoiseTracker20.prototype._exceptionPreprocessEffects = function( oChannel, iNotePeriod ) 86 { 87 var iEffectNumber = oChannel.getEffectNumber(); 88 89 switch( iEffectNumber ) 90 { 91 case weasel.FormatNoiseTracker11.Effects.TonePortamento : 92 // Command Fall through! 93 // 94 case weasel.FormatNoiseTracker20.Effects.TonePortamentoAndVolumeSlide : 95 oChannel.setNotePortamentoTarget( iNotePeriod ); 96 return true; 97 98 default: 99 break; 100 } 101 102 return false; 103 }; 104 105 // --------------------------------------------------------------------------- 106 /** Process a channel's effects. 107 * 108 * @param {weasel.Channel} oChannel = The Channel to process for effects. 109 * 110 * @protected 111 * @override 112 */ 113 weasel.NoiseTracker20.prototype._processChannelEffect = function( oChannel ) 114 { 115 switch( oChannel.getEffectNumber() ) 116 { 117 case weasel.FormatDOCSoundTracker9.Effects.Arpeggio : 118 119 if( oChannel.getEffectParameter() == 0 ) 120 { 121 // Restore the (shadow) note period when no effect occurs. 122 // 123 oChannel.setNotePeriod( oChannel.getShadowNotePeriod() ); 124 break; 125 } 126 127 oChannel.arpeggio( this.iCurrentTick, weasel.Channel.prototype.ArpeggioMode.Noisetracker ); 128 129 break; 130 131 case weasel.FormatDOCSoundTracker9.Effects.PitchbendUp : 132 133 oChannel.pitchBend( this.iCurrentTick, 0, oChannel.getEffectParameter() ); 134 oChannel.setShadowNotePeriod( this._clampNotePeriod( oChannel.getShadowNotePeriod() ) ); 135 oChannel.setNotePeriod( oChannel.getShadowNotePeriod() ); 136 137 break; 138 139 case weasel.FormatDOCSoundTracker9.Effects.PitchbendDown : 140 141 oChannel.pitchBend( this.iCurrentTick, oChannel.getEffectParameter(), 0 ); 142 oChannel.setShadowNotePeriod( this._clampNotePeriod( oChannel.getShadowNotePeriod() ) ); 143 oChannel.setNotePeriod( oChannel.getShadowNotePeriod() ); 144 145 break; 146 147 case weasel.FormatNoiseTracker11.Effects.TonePortamento : 148 149 oChannel.setNotePortamentoSpeed( oChannel.getEffectParameter() ); 150 oChannel.notePortamento( this.iCurrentTick ); 151 oChannel.setNotePeriod( this._clampNotePeriod( oChannel.getNotePeriod() ) ); 152 break; 153 154 case weasel.FormatNoiseTracker11.Effects.Vibrato : 155 156 oChannel.vibrato( this.iCurrentTick, true, this.getVibratoMode() ); 157 break; 158 159 160 case weasel.FormatNoiseTracker20.Effects.TonePortamentoAndVolumeSlide : 161 162 oChannel.notePortamento( this.iCurrentTick ); 163 oChannel.setNotePeriod( this._clampNotePeriod( oChannel.getNotePeriod() ) ); 164 oChannel.volumeSlide( this.iCurrentTick ); 165 break; 166 167 case weasel.FormatNoiseTracker20.Effects.VibratoAndVolumeSlide : 168 169 oChannel.vibrato( this.iCurrentTick, false, this.getVibratoMode() ); 170 oChannel.volumeSlide( this.iCurrentTick ); 171 break; 172 173 case weasel.FormatSpreadpointSoundTracker23.Effects.VolumeSlide : 174 175 // Restore (shadow) note period when a Effect Command 10 occurs. 176 // 177 oChannel.setNotePeriod( oChannel.getShadowNotePeriod() ); 178 179 oChannel.volumeSlide( this.iCurrentTick ); 180 181 break; 182 183 default : 184 // Restore the note period when a Effect Command 185 // that is not processed on a non tick 0 occurs. Such as 186 // Set Volume Command. 187 // Commands 7, 8, 9, 10, 11, 12, 13, 14, 15 restore the 188 // period value. This value is taken from the Shadow Note Period 189 // as the pitch bend/Portamento period value is maintained. 190 // 191 oChannel.setNotePeriod( oChannel.getShadowNotePeriod() ); 192 193 break; 194 } 195 };