Ejemplo n.º 1
0
        /// <summary>
        /// Get decoded audio track for the BGM using a specified samplerate.
        /// could probably work with different samplerates but i don't know why you'd try
        /// </summary>
        /// <param name="dstFreq"></param>
        /// <param name="track">The type of Audio Track</param>
        /// <returns>Signed 16-Bit PCM audio</returns>
        public short[] getAudioTrackPcm(int dstFreq, PPMAudioTrack track)
        {
            var    srcPcm     = Decode(track);
            var    srcFreq    = 8192;
            double soundspeed = Flipnote.BGMRate;
            double framerate  = Flipnote.Framerate;

            if (track == PPMAudioTrack.BGM)
            {
                var bgmAdjust = (1.0 / soundspeed) / (1.0 / framerate);
                srcFreq = ((int)(srcFreq * bgmAdjust));
            }
            if ((int)srcFreq != dstFreq)
            {
                return(pcmResampleNearestNeighbour(srcPcm, srcFreq, dstFreq));
            }
            return(srcPcm);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Get decoded audio track for a given track
        /// </summary>
        /// <param name="track">Which type of Audio Track to decode</param>
        /// <returns>Signed 16-Bit PCM audio</returns>
        private short[] Decode(PPMAudioTrack track)
        {
            _SoundData sounds = Flipnote.Audio.SoundData;

            byte[] src = null;
            switch (track)
            {
            case PPMAudioTrack.BGM:
                src = sounds.RawBGM; break;

            case PPMAudioTrack.SE1:
                src = sounds.RawSE1; break;

            case PPMAudioTrack.SE2:
                src = sounds.RawSE2; break;

            case PPMAudioTrack.SE3:
                src = sounds.RawSE3; break;

            default:
                src = sounds.RawBGM; break;
            }
            var srcSize = src.Length;
            var dst     = new short[srcSize * 2];
            var srcPtr  = 0;
            var dstPtr  = 0;
            var sample  = 0;

            step_index = 0;
            var predictor = 0;
            var lowNibble = true;

            while (srcPtr < srcSize)
            {
                // switch between high and low nibble each loop iteration
                // increments srcPtr after every high nibble
                if (lowNibble)
                {
                    sample = src[srcPtr] & 0xF;
                }
                else
                {
                    sample = src[srcPtr++] >> 4;
                }
                lowNibble = !lowNibble;
                var step = ADPCM_STEP_TABLE[step_index];
                var diff = step >> 3;

                if ((sample & 1) != 0)
                {
                    diff += step >> 2;
                }
                if ((sample & 2) != 0)
                {
                    diff += step >> 1;
                }
                if ((sample & 4) != 0)
                {
                    diff += step;
                }
                if ((sample & 8) != 0)
                {
                    diff = -diff;
                }
                predictor += diff;
                predictor  = Utils.NumClamp(predictor, -32768, 32767);

                step_index   += IndexTable[sample];
                step_index    = Utils.NumClamp(step_index, 0, 88);
                dst[dstPtr++] = (short)predictor;
            }

            return(dst);
        }