private void swapEnvelope(JEnvelope env) { ticks = 0; var rqVec = env.vectorList[0]; if (rqVec.time == 0) { envCurrentVec = rqVec; // This could be wrong, some envelopes might not have an initializer value. envValue = envCurrentVec.value; // i hope envValueLast = envCurrentVec.value; } else // the latter case, here, should never happen. But in case it does, here's a failsafe. { envCurrentVec = new JEnvelopeVector() { mode = rqVec.mode, next = rqVec, time = 0, value = 32700 }; } //*/ }
/* * SAME AS JAIV1 * JAIV2 Oscillator Vector Structure * These are weird. so i'll just do it like this * short mode * short time * short value * * when you read anything over 8 for the mode, read the last two shorts then stop reading -- so the last value in the array would be * * 0x000F, 0x0000, 0x0000 */ public JEnvelope readEnvelope(BeBinaryReader binStream, int Base) { var len = 0; // This function cheats a little bit :) // We dive in not knowing the length of the table -- the table is stopped whenever one of the MODE bytes is more than 0xB. var seekBase = binStream.BaseStream.Position; for (int i = 0; i < 10; i++) { var mode = binStream.ReadInt16(); // reads the first 2 bytes of the table len++; // The reason we do this, is because we still need to read the loop flag, or stop flag. if (mode < 0xB) // This determines the mode, the mode will always be less than 0xB -- unless its telling the table to end. { // If it is, then we definitely want to read this entry, so we increment the counter binStream.ReadInt32(); // Then skip the actual entry data } else // The value was over 10 { break; // So we need to stop the loop } } binStream.BaseStream.Position = seekBase; // After we have an idea how big the table is -- we want to seek back to the beginning of it. JEnvelopeVector[] OscVecs = new JEnvelopeVector[len]; // And create an array the size of our length. for (int i = 0; i < len - 1; i++) // we read - 1 because we don't want to read the end value yet { var vector = new JEnvelopeVector { mode = (JEnvelopeVectorMode)binStream.ReadInt16(), // Read the values of each into their places time = binStream.ReadInt16(), // read time value = binStream.ReadInt16() // read value }; OscVecs[i] = vector; } // Go down below for the last vector, after sorting // todo: Figure out why this doesn't sort right? // -1 is so we don't sort the last object in the array, because its null. We're sorting from the bottom up. for (int i = 0; i < len - 1; i++) // a third __fucking iteration__ on these stupid vectors. { for (int j = 0; j < len - 1; j++) { var current = OscVecs[i]; // Grab current oscillator vector, notice the for loop starts at 1 var cmp = OscVecs[j]; // Grab the previous object if (cmp.time > current.time) // if its time is greater than ours { OscVecs[j] = current; // shift us down OscVecs[i] = cmp; // shift it up } } } //*/ // Now that we've sorted the vectors because nintendo packs them out of f*****g order. // We can add the hold / stop vector :D // We havent advanced any more bytes by the way, so we're still at the end of that vector array from before. var lastVector = OscVecs[OscVecs.Length - 2]; // -2 gets the last indexed object. // This is disgusting, i know. OscVecs[OscVecs.Length - 1] = new JEnvelopeVector { mode = (JEnvelopeVectorMode)binStream.ReadInt16(), // Read the values of each into their places time = (short)(lastVector.time), // read time value = lastVector.value // read value }; // Setting up references. // can only be done after sorting :v... for (int idx = 0; idx < OscVecs.Length - 1; idx++) { OscVecs[idx].next = OscVecs[idx + 1]; // current vector objects next is the one after it. } var ret = new JEnvelope(); ret.vectorList = OscVecs; return(ret); // finally, return. }
public byte updateVoice() { oscTicks++; // noooooooooooooooooooooooooooooooooooooooooooo if (doDestroy == true) { return(3); } float pv = 1f; for (int i = 0; i < pitchMatrix.Length; i++) { pv *= pitchMatrix[i]; } Bass.BASS_ChannelSetAttribute(voiceHandle, BASSAttribute.BASS_ATTRIB_FREQ, rootBuffer.format.sampleRate * pv); float vv = 1f; for (int i = 0; i < gain0Matrix.Length; i++) { vv *= gain0Matrix[i]; } //Console.WriteLine("Final Gain {0}", vv); Bass.BASS_ChannelSetAttribute(voiceHandle, BASSAttribute.BASS_ATTRIB_VOL, vv); if (envCurrentVec == null) { return(3); } if (envCurrentVec.mode == JEnvelopeVectorMode.Stop) { destroy(); doDestroy = true; return(3); // reeEEE EEE } else if (envCurrentVec.mode == JEnvelopeVectorMode.Hold) // hold keeps the current value { return(1); } if (envCurrentVec.next != null && envCurrentVec.next.time <= ticks) { envValueLast = envCurrentVec.value; // Console.WriteLine("SWAP ENV Last Value {3}\nNext Mode {0}\nCurrent Ticks {1}\nNext time {2}\nNext Value {4}", envCurrentVec.next.mode, ticks, envCurrentVec.next.time, envValueLast, envCurrentVec.next.value); envCurrentVec = envCurrentVec.next; // swap return(updateVoice()); } if (envCurrentVec.next == null) { if (crashed == false) { crashed = true; // envelope progression crashed } return(3); // tell interpreter to deallocate envelope. } //Console.WriteLine(envCurrentVec.value); var tickDist = envCurrentVec.next.time - envCurrentVec.time; var currentBaseTicks = envCurrentVec.time; // Currently linear only implemented var mult = ((float)(ticks - currentBaseTicks) / (float)tickDist); envValue = (float)envValueLast + (float)(envCurrentVec.value - envValueLast) * mult; //Console.WriteLine(envValue); gain0Matrix[1] = envValue / 32758f; //Console.WriteLine(instOsc.rate); ticks += tickAdvanceValue; return(1); // */ }