Ejemplo n.º 1
0
        /// <summary>
        /// Returns the fully mixed audio of the Flipnote, Including its Sound Effects.
        /// Returns Null if no audio exists.
        /// </summary>
        /// <param name="flip"></param>
        /// <param name="sampleRate"></param>
        /// <returns>Signed 16-bit PCM audio</returns>
        public byte[] GetWavBGM(PPMFile flip, int sampleRate = 32768)
        {
            // start decoding
            AdpcmDecoder encoder = new AdpcmDecoder(flip);
            var          decoded = encoder.getAudioMasterPcm(sampleRate);

            if (decoded.Length > 0)
            {
                byte[] output = new byte[decoded.Length];

                // thank you https://github.com/meemo
                for (int i = 0; i < decoded.Length; i += 2)
                {
                    try
                    {
                        output[i]     = (byte)(decoded[i + 1] & 0xff);
                        output[i + 1] = (byte)(decoded[i] >> 8);
                    }
                    catch (Exception)
                    {
                    }
                }
                var a = new WavePcmFormat(output, 1, (uint)(sampleRate / 2), 16);
                return(a.ToBytesArray());
            }
            return(null);
        }
Ejemplo n.º 2
0
        public static PPMFile Create(PPMAuthor author, List <PPMFrame> frames, byte[] audio, bool ignoreMetadata = false)
        {
            var file = new PPMFile();

            file.FrameCount    = (ushort)(frames.Count - 1);
            file.FormatVersion = 0x24;

            if (!ignoreMetadata)
            {
                file.RootAuthor    = author;
                file.ParentAuthor  = author;
                file.CurrentAuthor = author;

                string mac6 = string.Join("", BitConverter.GetBytes(author.Id).Take(3).Reverse().Select(t => t.ToString("X2")));
                var    asm  = Assembly.GetEntryAssembly().GetName().Version;
                var    dt   = DateTime.UtcNow;
                var    fnVM = ((byte)asm.Major).ToString("X2");
                var    fnVm = ((byte)asm.Minor).ToString("X2");
                var    fnYY = (byte)(dt.Year - 2009);
                var    fnMD = dt.Month * 32 + dt.Day;
                var    fnTi = (((dt.Hour * 3600 + dt.Minute * 60 + dt.Second) % 4096) >> 1) + (fnMD > 255 ? 1 : 0);
                fnMD = (byte)fnMD;
                var fnYMD = (fnYY << 9) + fnMD;
                var H6_9  = fnYMD.ToString("X4");
                var H89   = ((byte)fnMD).ToString("X2");
                var HABC  = fnTi.ToString("X3");

                string _13str   = $"80{fnVM}{fnVm}{H6_9}{HABC}";
                string nEdited  = 0.ToString().PadLeft(3, '0');
                var    filename = $"{mac6}_{_13str}_{nEdited}.ppm";


                var rawfn = new byte[18];
                for (int i = 0; i < 3; i++)
                {
                    rawfn[i] = byte.Parse("" + mac6[2 * i] + mac6[2 * i + 1], System.Globalization.NumberStyles.HexNumber);
                }
                for (int i = 3; i < 16; i++)
                {
                    rawfn[i] = (byte)_13str[i - 3];
                }
                rawfn[16] = rawfn[17] = 0;

                file.ParentFilename  = new PPMFilename(rawfn);
                file.CurrentFilename = new PPMFilename(rawfn);

                var ByteRootFileFragment = new byte[8];
                for (int i = 0; i < 3; i++)
                {
                    ByteRootFileFragment[i] =
                        byte.Parse("" + mac6[2 * i] + mac6[2 * i + 1], System.Globalization.NumberStyles.HexNumber);
                }
                for (int i = 3; i < 8; i++)
                {
                    ByteRootFileFragment[i] =
                        (byte)((byte.Parse("" + _13str[2 * (i - 3)], System.Globalization.NumberStyles.HexNumber) << 4)
                               + byte.Parse("" + _13str[2 * (i - 3) + 1], System.Globalization.NumberStyles.HexNumber));
                }

                file.RootFileFragment = new PPMFileFragment(ByteRootFileFragment);

                file.Timestamp           = new PPMTimestamp((uint)((dt - new DateTime(2000, 1, 1, 0, 0, 0)).TotalSeconds));
                file.Thumbnail           = new PPMThumbnail(new byte[0x600]);
                file.ThumbnailFrameIndex = 0;
            }
            // write the audio data

            uint animDataSize = (uint)(8 + 4 * frames.Count);

            file.AnimationFlags       = 0x43;
            file.FrameOffsetTableSize = (ushort)(4 * frames.Count);

            file.Frames = new PPMFrame[frames.Count];
            //SoundEffectFlags = new byte[frames.Count];

            for (int i = 0; i < frames.Count; i++)
            {
                file.Frames[i] = frames[i];


                animDataSize += (uint)file.Frames[i].ToByteArray().Length;
            }
            while ((animDataSize & 0x3) != 0)
            {
                animDataSize++;
            }
            file.AnimationDataSize = animDataSize;

            file.Audio = new PPMAudio();
            file.Audio.SoundData.RawBGM         = audio;
            file.Audio.SoundHeader.BGMTrackSize = (uint)file.Audio.SoundData.RawBGM.Length;
            file.Audio.SoundHeader.SE1TrackSize = 0;
            file.Audio.SoundHeader.SE2TrackSize = 0;
            file.Audio.SoundHeader.SE2TrackSize = 0;
            file.SoundDataSize = (uint)file.Audio.SoundData.RawBGM.Length;

            file.Audio.SoundHeader.CurrentFramespeed      = 0;
            file.Audio.SoundHeader.RecordingBGMFramespeed = 0;

            return(file);
        }