Guest User

Atacama

a guest
Apr 19th, 2008
638
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /******************************************************************************
  2.  * BNRSound.cs
  3.  * Created by Atacama
  4.  *
  5.  * uses portions of in_cube code (coverted to c#)
  6.  * -created by hcs - http://www.hcs64.com/in_cube.html
  7.  *
  8.  *****************************************************************************/
  9.  
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Text;
  13. using System.IO;
  14.  
  15. namespace bnrLoader
  16. {
  17.     class Channel
  18.     {
  19.         public short[] CoEfficients = new short[16];
  20.         public byte[] data;
  21.         public MemoryStream mspdata;
  22.         public MemoryStream msploop;
  23.         public BinaryWriter bwpdata;
  24.         public MemoryStream mscdata;
  25.         public BinaryReader brcdata;
  26.         //public byte header;
  27.         public short adpcmhistory1;
  28.         public short adpcmhistory2;
  29.         //private int loopcount = 0;
  30.         public bool loop;
  31.         public bool hasIntro = false;
  32.  
  33.         public void decodeDSP(int looppos)
  34.         {
  35.  
  36.             mspdata = new MemoryStream();
  37.             msploop = new MemoryStream();
  38.             bwpdata = new BinaryWriter(mspdata);
  39.             mscdata = new MemoryStream(data);
  40.             brcdata = new BinaryReader(mscdata);
  41.             looppos = ((looppos) /14) * 8;
  42.  
  43.             hasIntro = (looppos > 0);
  44.             while(mscdata.Position < mscdata.Length) {
  45.                 int sample;
  46.                 short[] nibbles = new short[14];
  47.                 int index1;
  48.                 int i,j;
  49.                 byte header;
  50.                 short delta;
  51.                 byte thisbyte;
  52.                 short hist=adpcmhistory1;
  53.                 short hist2=adpcmhistory2;
  54.                 // If we have loop data then we write to our looping file.
  55.                 if (mscdata.Position == looppos)
  56.                     bwpdata = new BinaryWriter(msploop);
  57.  
  58.  
  59.                 header = brcdata.ReadByte();
  60.                 i = header&0xFF;
  61.                 delta = (short) (1 << (i & 0xff & 0xf));
  62.                 index1 = (i & 0xff) >> 4;
  63.                
  64.                 for(i = 0; i < 14; i += 2) {
  65.                     thisbyte = brcdata.ReadByte();
  66.                     j = (thisbyte & 0xff) >> 4;
  67.                     nibbles[i] = (short) j;
  68.                     j = thisbyte & 0xff & 0xf;
  69.                     nibbles[i+1] = (short) j;
  70.                 }
  71.  
  72.                 for(i = 0; i < 14; i++) {
  73.                     if(nibbles[i] >= 8)
  74.                         nibbles[i] = (short)(nibbles[i] - 16);      
  75.                 }
  76.                  
  77.                 for(i = 0; i<14 ; i++) {
  78.  
  79.                     sample = (delta * nibbles[i])<<11;
  80.                     sample += CoEfficients[index1 * 2] * hist;
  81.                     sample += CoEfficients[index1 * 2 + 1] * hist2;
  82.                     sample = sample + 1024;
  83.                     sample = sample >> 11;
  84.                     if(sample > 32767)
  85.                         sample = 32767;
  86.  
  87.                     if(sample < -32768)
  88.                         sample = -32768;
  89.                     bwpdata.Write((short)sample);
  90.                     hist2 = hist;
  91.                     hist = (short)sample;
  92.                 }
  93.                 adpcmhistory1 = hist;
  94.                 adpcmhistory2 = hist2;
  95.  
  96.             }
  97.            
  98.         }
  99.  
  100.  
  101.     }
  102.     class BNRSound
  103.     {
  104.        
  105.         byte[] FileBuffer;
  106.         byte[] MD5Hash;
  107.  
  108.         public Channel[] channels;
  109.         byte codectype;
  110.         byte loop;
  111.         int loopstart;
  112.         byte channelCount = 0;
  113.         public ushort SampleRate;
  114.         uint SampleCount;
  115.         MemoryStream WholeStream;
  116.         MemoryStream InfoStream;
  117.         MemoryStream DataStream;
  118.         BinaryReader brInfoStream;
  119.         BinaryReader brDataStream;
  120.         string AudioFormat;
  121.         BinaryReader brWholeStream;
  122.         private long AudioDatastart;
  123.         //byte samplesperframe = 14;
  124.         //byte framesize = 8;
  125.  
  126.         /* For BNS We should have:
  127.          *  (GG means any hex data)
  128.          * I  M  D  5  |BNS  Size| Nothingness.......
  129.          * 49 4D 44 35 GG GG GG GG 00 00 00 00 00 00 00 00
  130.          * | ----------M D 5  H A S H -------------------|
  131.          * GG GG GG GG GG GG GG GG GG GG GG GG GG GG GG GG
  132.          * B  N  S                 |BNS  Size| Unknown
  133.          * 42 4E 53 20 FE FF 01 00 GG GG GG GG GG GG GG GG  
  134.          * Info Offset|Info Length|Data Offset|Data Length|
  135.          * 00 00 00 20 00 00 00 A0 00 00 00 C0 00 04 2B A8
  136.          * I  N  F  O |Info Length|*1|*2|*3|*4| Hz  | Unk |   *1: Codec number? Seems to be 0 (NGC-DSP)
  137.          * 49 4E 46 4F 00 00 00 A0 00 00 02 00 7D 00 00 00    *2: Loop Flag?
  138.          * |LoopStart?|            |Always 18 and 4 nulls?|   *3: Channel Count?
  139.          * 00 00 00 00 00 03 A6 25 00 00 00 18 00 00 00 00    *4: Always 00?
  140.          * |       *5 |         *6|         *7|         *8|   *5: 1C if channels = 1, 20 if channels = 2
  141.          * 00 00 00 20 00 00 00 2C 00 00 00 00 00 00 00 38    *6: 00 if channels = 1, 2C if channels = 2
  142.          *            |        *10|         *11           |   *7: 28 if channels = 1, 00 if channels = 2
  143.      *9  * 00 00 00 00 00 02 15 D0 00 00 00 68 00 00 00 00    *8: 00 if channels = 1, 38 if channels = 2
  144.          *                                                    *9: This line is only here for stereo files.
  145.      *12 * FD A6 00 05 05 84 FE 38 01 16 04 B1 0C 41 FA D7    *10: Channel 2 start pos?
  146.          *                                                    *11: Always 68 surrounded by 00s
  147.      *12 * 01 DD FE 9D 06 BF FF D1 03 D3 03 CA 09 36 FE 9D    *12: Chan 0 ADPCM CoEfficients
  148.          *                                                    *13: Chan 1 ADPCM CoEfficients
  149.          * 00 00 00 42 00 00 00 00 00 42 00 00 00 00 00 00
  150.          *
  151.      *13 * FD 74 00 C7 05 CB FD F9 01 28 03 E7 08 43 FF 00
  152.          *
  153.      *13 * 01 8D FE 48 0B 7B FB 20 03 65 04 2E 07 84 00 5A
  154.          *
  155.          * 00 00 00 21 00 00 00 00 00 21 00 00 00 00 00 00
  156.          * D  A  T  A  |Data Size|
  157.          * 44 41 54 41 00 04 2B A8 42 86 B3 E2 E1 F1 F1 F1
  158.              
  159.          */
  160.  
  161.         public BNRSound(Stream fio)
  162.         {
  163.             WholeStream = (MemoryStream) fio;
  164.             brWholeStream = new BinaryReader(WholeStream);
  165.             byte[] IMD5 = brWholeStream.ReadBytes(4);
  166.            
  167.             if (System.Text.Encoding.ASCII.GetString(IMD5) != "IMD5")
  168.             {
  169.                 return;
  170.             }
  171.             WholeStream.Seek(12, SeekOrigin.Current);
  172.             MD5Hash = brWholeStream.ReadBytes(16);
  173.             AudioDatastart = WholeStream.Position;
  174.             audiodatacheck:
  175.  
  176.             /* Now we have actually reached the audio file data */
  177.             byte[] AudioType = brWholeStream.ReadBytes(3);
  178.             byte Extra = brWholeStream.ReadByte(); // when BNS it is a non printable char so we just read first 3.
  179.             AudioFormat = System.Text.Encoding.ASCII.GetString(AudioType);
  180.  
  181.  
  182.             switch (AudioFormat){
  183.                 case "BNS":
  184.                     /* BNS Format */
  185.                     processBNS();
  186.                     break;
  187.                 case "LZ7":
  188.                     /* LZ77 something so lets decompress it and try again */
  189.                     MemoryStream lzdata = new MemoryStream();
  190.                     LZ77Stream lz7s = new LZ77Stream(lzdata, System.IO.Compression.CompressionMode.Decompress);
  191.                    
  192.                     WholeStream.Seek(0x24, SeekOrigin.Begin);
  193.                     byte[] Indata = new byte[WholeStream.Length - WholeStream.Position];
  194.                     WholeStream.Read(Indata, 0, (int)(WholeStream.Length - WholeStream.Position));
  195.                     lz7s.Write(Indata, 0, (int)Indata.Length);
  196.                     WholeStream = lzdata;
  197.                     WholeStream.Seek(0, SeekOrigin.Begin);
  198.                     brWholeStream = new BinaryReader(WholeStream);
  199.                     AudioDatastart = 0;
  200.                     goto audiodatacheck;
  201.                 case "RIF":
  202.                     /* Wav file */
  203.                     processWAV();
  204.                     return;
  205.                     //break;
  206.                 case "FOR":
  207.                     /* Aif File */
  208.                     processAIF();
  209.                     return;
  210.                     //break;
  211.             }
  212.  
  213.  
  214.         }
  215.  
  216.         private void processBNS() {
  217.             uint ChannelSplit = 0;
  218.             WholeStream.Seek(4, SeekOrigin.Current);
  219.             uint bnssize = toBEInt(brWholeStream.ReadUInt32());
  220.             WholeStream.Seek(-12, SeekOrigin.Current);
  221.             FileBuffer = brWholeStream.ReadBytes((int) bnssize);
  222.             //WholeStream.Seek(0, SeekOrigin.Begin);
  223.  
  224.             WholeStream.Seek(-(FileBuffer.Length-12), SeekOrigin.Current);
  225.             uint unknown1 = toBEInt(brWholeStream.ReadUInt32());
  226.             uint infooffset = toBEInt(brWholeStream.ReadUInt32());
  227.             uint infolength = toBEInt(brWholeStream.ReadUInt32());
  228.             uint dataoffset = toBEInt(brWholeStream.ReadUInt32());
  229.             uint datalength = toBEInt(brWholeStream.ReadUInt32());
  230.             InfoStream = new MemoryStream(FileBuffer, (int)infooffset, (int)infolength);
  231.             brInfoStream = new BinaryReader(InfoStream);
  232.             DataStream = new MemoryStream(FileBuffer, (int)dataoffset, (int)datalength);
  233.             brDataStream = new BinaryReader(DataStream);
  234.  
  235.             InfoStream.Seek(8, SeekOrigin.Begin);
  236.             codectype = brInfoStream.ReadByte();
  237.             loop = brInfoStream.ReadByte();
  238.             channelCount = brInfoStream.ReadByte();
  239.             byte unknownbyte1 = brInfoStream.ReadByte();
  240.             SampleRate = toBEInt(brInfoStream.ReadUInt16());
  241.             ushort unknown2 = brInfoStream.ReadUInt16();
  242.             loopstart = toBEInt(brInfoStream.ReadInt32());
  243.             SampleCount = toBEInt(brInfoStream.ReadUInt32());
  244.  
  245.             channels = new Channel[channelCount];
  246.             InfoStream.Seek(24, SeekOrigin.Current);
  247.             uint length;
  248.             switch (channelCount)
  249.             {
  250.                 case 1:
  251.  
  252.                     channels[0] = new Channel();
  253.                     for (int a = 0; a < 16; a++)
  254.                     {
  255.                         channels[0].CoEfficients[a] = toBEInt(brInfoStream.ReadInt16());
  256.                     }
  257.                     channels[0].loop = (this.loop == 1);
  258.                     DataStream.Seek(4,SeekOrigin.Begin);
  259.                     length = toBEInt(brDataStream.ReadUInt32());
  260.                     channels[0].data = brDataStream.ReadBytes((int)length - 4);
  261.                     channels[0].decodeDSP(this.loopstart);
  262.                     FileStream fsmono = new FileStream(Path.GetTempPath() + "mono" + this.SampleRate.ToString() + ".raw", FileMode.Create, FileAccess.Write);
  263.  
  264.                     channels[0].mspdata.WriteTo(fsmono);
  265.                     fsmono.Close();
  266.  
  267.                     break;
  268.  
  269.                 case 2:
  270.                     uint unknown3 = toBEInt(brInfoStream.ReadUInt32());
  271.                     ChannelSplit = toBEInt(brInfoStream.ReadUInt32());
  272.                     uint unknown4 = toBEInt(brInfoStream.ReadUInt32());
  273.                     uint unknown5 = toBEInt(brInfoStream.ReadUInt32());
  274.                     channels[0] = new Channel();
  275.                     for (int a = 0; a < 16; a++)
  276.                     {
  277.                         channels[0].CoEfficients[a] = toBEInt(brInfoStream.ReadInt16());
  278.                     }
  279.                     channels[0].loop = (this.loop == 1);
  280.                     DataStream.Seek(4, SeekOrigin.Begin);
  281.                     length = toBEInt(brDataStream.ReadUInt32());
  282.                     channels[0].data = brDataStream.ReadBytes((int)ChannelSplit);
  283.                     channels[0].decodeDSP(this.loopstart);
  284.  
  285.                     FileStream fsleft = new FileStream(Path.GetTempPath() + "left" + this.SampleRate.ToString() + ".raw", FileMode.Create, FileAccess.Write);
  286.  
  287.                     channels[0].mspdata.WriteTo(fsleft);
  288.                     fsleft.Close();
  289.  
  290.  
  291.                     InfoStream.Seek(16, SeekOrigin.Current);
  292.                     channels[1] = new Channel();
  293.                     for (int a = 0; a < 16; a++)
  294.                     {
  295.                         channels[1].CoEfficients[a] = toBEInt(brInfoStream.ReadInt16());
  296.                     }
  297.                     channels[1].loop = (this.loop == 1);
  298.                     channels[1].data = brDataStream.ReadBytes((int)length - (int)ChannelSplit);
  299.                     channels[1].decodeDSP(this.loopstart);
  300.  
  301.                     FileStream fsright = new FileStream(Path.GetTempPath() + "right" + this.SampleRate.ToString() + ".raw", FileMode.Create, FileAccess.Write);
  302.  
  303.                     channels[1].mspdata.WriteTo(fsright);
  304.                     fsright.Close();
  305.  
  306.                     break;
  307.  
  308.             }
  309.  
  310.            
  311.  
  312.  
  313.         }
  314.  
  315.         private void processWAV()
  316.         {
  317.             // This is a bit inefficient since we split the wav stuff out to separate channels
  318.             // and then recombine it for DSound, doesn't matter too much though as we are
  319.             // only using memorystreams :)
  320.  
  321.  
  322.             int riffsize = brWholeStream.ReadInt32();
  323.             WholeStream.Seek(12, SeekOrigin.Current);
  324.             int pcm = brWholeStream.ReadInt16();
  325.  
  326.             if (pcm != 1)
  327.             {
  328.                 // Not PCM data
  329.                 return;
  330.             }
  331.             this.channelCount = (byte) brWholeStream.ReadInt16();
  332.             this.channels = new Channel[this.channelCount];
  333.             this.SampleRate = (ushort) brWholeStream.ReadInt32();
  334.             this.loop = 0;
  335.             WholeStream.Seek(12, SeekOrigin.Current);
  336.             channels[0] = new Channel();
  337.             channels[0].msploop = new MemoryStream();
  338.             BinaryWriter brleft = new BinaryWriter(channels[0].msploop);
  339.  
  340.             BinaryWriter brright = null;
  341.  
  342.             if (this.channelCount == 2)
  343.             {
  344.                 channels[1] = new Channel();
  345.                 channels[1].msploop = new MemoryStream();
  346.                 brright = new BinaryWriter(channels[0].msploop);
  347.                
  348.  
  349.             }
  350.  
  351.             while (WholeStream.Position < riffsize)
  352.             {
  353.                 brleft.Write(brWholeStream.ReadInt32());
  354.                 if (this.channels.Length == 2)
  355.                 {
  356.                     brright.Write(brWholeStream.ReadInt32());
  357.                 }
  358.  
  359.             }
  360.  
  361.             /*bwav.Write("RIFF".ToCharArray());
  362. bwav.Write(totallength + 0x2c);
  363. bwav.Write("WAVEfmt ".ToCharArray());
  364. bwav.Write((int)0x10);
  365. bwav.Write((short)1);
  366. bwav.Write((short)channelcount);
  367. bwav.Write((int)WiiSound.SampleRate);
  368. bwav.Write((int)bps);
  369. bwav.Write((short)(channelcount * 2));
  370. bwav.Write((short)0x10);
  371. bwav.Write("data".ToCharArray());
  372. bwav.Write(totallength);
  373.  * */
  374.  
  375.         }
  376.  
  377.         private void processAIF()
  378.         {
  379.  
  380.             uint aiffsize = brWholeStream.ReadUInt32();
  381.             byte[] aifftype = brWholeStream.ReadBytes(4);
  382.  
  383.             BinaryWriter brleft = null;
  384.  
  385.             BinaryWriter brright = null;
  386.             do
  387.             {
  388.                 //            WholeStream.Seek(0x90, SeekOrigin.Current);
  389.                 byte[] type = brWholeStream.ReadBytes(4);
  390.                 uint size = toBEInt(brWholeStream.ReadUInt32());
  391.                 long start = WholeStream.Position;
  392.  
  393.                 string sInType = System.Text.Encoding.ASCII.GetString(type);
  394.  
  395.  
  396.                 switch (sInType)
  397.                 {
  398.                     case "COMM":
  399.                         //header - we will assume this comes before ssnd
  400.                         this.channelCount = (byte) toBEInt(brWholeStream.ReadInt16());
  401.                         this.channels = new Channel[this.channelCount];
  402.  
  403.  
  404.                         ulong numsampleframes = brWholeStream.ReadUInt32();
  405.                         ushort bits = toBEInt(brWholeStream.ReadUInt16());
  406.                         ushort wtf = toBEInt(brWholeStream.ReadUInt16());
  407.                         this.SampleRate = toBEInt(brWholeStream.ReadUInt16());
  408.                         this.loop = 0;
  409.                         this.channels[0] = new Channel();
  410.                         this.channels[0].msploop = new MemoryStream();
  411.                         brleft = new BinaryWriter(channels[0].msploop);
  412.  
  413.                         if (this.channelCount == 2)
  414.                         {
  415.                             channels[1] = new Channel();
  416.                             channels[1].msploop = new MemoryStream();
  417.                             brright = new BinaryWriter(channels[0].msploop);
  418.                         }
  419.                         break;
  420.                     case "SSND":
  421.                         // Sound Data
  422.  
  423.  
  424.                         while (WholeStream.Position < (start + (long) size))
  425.                         {
  426.                             brleft.Write(toBEInt(brWholeStream.ReadInt32()));
  427.                             if (this.channels.Length == 2)
  428.                             {
  429.                                 brright.Write(toBEInt(brWholeStream.ReadInt32()));
  430.                             }
  431.  
  432.                         }
  433.                         break;
  434.  
  435.                 }
  436.  
  437.                 WholeStream.Seek(start + (long) size, SeekOrigin.Begin);
  438.  
  439.  
  440.  
  441.  
  442.  
  443.                
  444.                
  445.                 //WholeStream.Seek(12, SeekOrigin.Current);
  446.  
  447.  
  448.  
  449.             } while (WholeStream.Position < WholeStream.Length);
  450.  
  451.         }
  452.  
  453.  
  454.         public int toBEInt(int theint)
  455.         {
  456.             return ((theint & 0x000000ff) << 24) |
  457.            ((theint & 0x0000ff00) << 8) |
  458.            ((theint & 0x00ff0000) >> 8) | (int)
  459.            ((theint & 0xff000000) >> 24);
  460.         }
  461.         public uint toBEInt(uint theint)
  462.         {
  463.             return (uint)(theint >> 24) |
  464.              ((theint << 8) & 0x00FF0000) |
  465.              ((theint >> 8) & 0x0000FF00) |
  466.               (theint << 24);
  467.         }
  468.         public short toBEInt(short theshort)
  469.         {
  470.             int theint = (int)theshort;
  471.             int ret = ((theint >> 8) & 0xff) | (theint & 0xff) << 8;
  472.  
  473.             return (short)ret;
  474.         }
  475.         public ushort toBEInt(ushort theshort)
  476.         {
  477.             return (ushort)(theshort >> 8 | theshort << 8);
  478.  
  479.  
  480.         }
  481.  
  482.  
  483.     }
  484. }
  485.  
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×