Example #1
0
        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
                };
            }
            //*/
        }
Example #2
0
        /*
         * 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.
        }
Example #3
0
        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);
            // */
        }