X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=FDK%2F%E3%82%B3%E3%83%BC%E3%83%89%2F03.%E3%82%B5%E3%82%A6%E3%83%B3%E3%83%89%2FCxa.cs;fp=FDK%2F%E3%82%B3%E3%83%BC%E3%83%89%2F03.%E3%82%B5%E3%82%A6%E3%83%B3%E3%83%89%2FCxa.cs;h=ee239fe046bd0599fda5c314fa4c312513af638d;hb=7bf3e650c7c6f5afac463ea6e288fcd3fad4387b;hp=0000000000000000000000000000000000000000;hpb=296446998eeba408353da55a275458b590e4ebf5;p=dtxmania%2Fdtxmania.git
diff --git a/FDK/ã³ã¼ã/03.ãµã¦ã³ã/Cxa.cs b/FDK/ã³ã¼ã/03.ãµã¦ã³ã/Cxa.cs
new file mode 100644
index 00000000..ee239fe0
--- /dev/null
+++ b/FDK/ã³ã¼ã/03.ãµã¦ã³ã/Cxa.cs
@@ -0,0 +1,380 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.IO;
+using System.Diagnostics;
+using System.Threading;
+
+
+namespace FDK
+{
+ public unsafe class Cxa : SoundDecoder //, IDisposable
+ {
+ static byte[] FOURCC = Encoding.ASCII.GetBytes( "1DWK" ); // KWD1 ã® little endian
+
+ #region [ XAç¨æ§é ä½ã®å®£è¨ ]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct XASTREAMHEADER {
+ public byte* pSrc;
+ public uint nSrcLen;
+ public uint nSrcUsed;
+ public byte* pDst;
+ public uint nDstLen;
+ public uint nDstUsed;
+ }
+
+ [StructLayout( LayoutKind.Sequential )]
+ public struct XAHEADER
+ {
+ public uint id;
+ public uint nDataLen;
+ public uint nSamples;
+ public ushort nSamplesPerSec;
+ public byte nBits;
+ public byte nChannels;
+ public uint nLoopPtr;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
+ public short[] befL;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
+ public short[] befR;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
+ public byte[] pad;
+ }
+ #endregion
+
+ #region [ xadec.dllã¨ã®ãªã³ã¯ ]
+ [DllImport( "xadec.dll", EntryPoint = "xaDecodeOpen", CallingConvention = CallingConvention.Cdecl )]
+ public extern static IntPtr xaDecodeOpen( ref XAHEADER pxah, out FDK.CWin32.WAVEFORMATEX pwfx );
+ [DllImport( "xadec.dll", EntryPoint = "xaDecodeClose", CallingConvention = CallingConvention.Cdecl )]
+ public extern static bool xaDecodeClose( IntPtr hxas );
+ [DllImport( "xadec.dll", EntryPoint = "xaDecodeSize", CallingConvention = CallingConvention.Cdecl )]
+ public extern static bool xaDecodeSize( IntPtr hxas, uint slen, out uint pdlen );
+ [DllImport( "xadec.dll", EntryPoint = "xaDecodeConvert", CallingConvention = CallingConvention.Cdecl )]
+ public extern static bool xaDecodeConvert( IntPtr hxas, ref XASTREAMHEADER psh );
+ #endregion
+
+ public XAHEADER xaheader;
+ public XASTREAMHEADER xastreamheader;
+ public CWin32.WAVEFORMATEX waveformatex;
+
+ private string filename;
+ private byte[] srcBuf = null;
+ private int nHandle = -1;
+
+ public override int Open( string filename )
+ {
+ this.filename = filename;
+
+ #region [ XAãããã¨ãXAãã¼ã¿ã®èªã¿åºã ]
+ xaheader = new XAHEADER();
+ using ( FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ) ) // FileShare ãä»ãã¨ããªãã¨ãClose() å¾ãããã¯ãããã??
+ {
+ using ( BinaryReader br = new BinaryReader( fs ) )
+ {
+ xaheader.id = br.ReadUInt32();
+ xaheader.nDataLen = br.ReadUInt32();
+ xaheader.nSamples = br.ReadUInt32();
+ xaheader.nSamplesPerSec = br.ReadUInt16();
+ xaheader.nBits = br.ReadByte();
+ xaheader.nChannels = br.ReadByte();
+ xaheader.nLoopPtr = br.ReadUInt32();
+
+ xaheader.befL = new short[ 2 ];
+ xaheader.befR = new short[ 2 ];
+ xaheader.pad = new byte[ 4 ];
+
+ xaheader.befL[ 0 ] = br.ReadInt16();
+ xaheader.befL[ 1 ] = br.ReadInt16();
+ xaheader.befR[ 0 ] = br.ReadInt16();
+ xaheader.befR[ 1 ] = br.ReadInt16();
+ xaheader.pad = br.ReadBytes( 4 );
+
+ srcBuf = new byte[ xaheader.nDataLen ];
+ srcBuf = br.ReadBytes( (int) xaheader.nDataLen );
+ }
+ }
+ //string xaid = Encoding.ASCII.GetString( xah.id );
+ #region [ ãããã°è¡¨ç¤º ]
+ //Debug.WriteLine( "**XAHEADER**" );
+ //Debug.WriteLine( "id= " + xaheader.id.ToString( "X8" ) );
+ //Debug.WriteLine( "nDataLen= " + xaheader.nDataLen.ToString( "X8" ) );
+ //Debug.WriteLine( "nSamples= " + xaheader.nSamples.ToString( "X8" ) );
+ //Debug.WriteLine( "nSamplesPerSec= " + xaheader.nSamplesPerSec.ToString( "X4" ) );
+ //Debug.WriteLine( "nBits= " + xaheader.nBits.ToString( "X2" ) );
+ //Debug.WriteLine( "nChannels= " + xaheader.nChannels.ToString( "X2" ) );
+ //Debug.WriteLine( "nLoopPtr= " + xaheader.nLoopPtr.ToString( "X8" ) );
+ //Debug.WriteLine( "befL[0]= " + xaheader.befL[ 0 ].ToString( "X4" ) );
+ //Debug.WriteLine( "befL[1]= " + xaheader.befL[ 1 ].ToString( "X4" ) );
+ //Debug.WriteLine( "befR[0]= " + xaheader.befR[ 0 ].ToString( "X4" ) );
+ //Debug.WriteLine( "befR[1]= " + xaheader.befR[ 1 ].ToString( "X4" ) );
+ #endregion
+ #endregion
+
+ IntPtr hxas;
+
+ #region [ WAVEFORMEXæ
å ±ã®åå¾ ]
+ waveformatex = new CWin32.WAVEFORMATEX();
+ hxas = xaDecodeOpen( ref xaheader, out waveformatex );
+ if ( hxas == null )
+ {
+ Trace.TraceError( "Error: xa: Open(): xaDecodeOpen(): " + Path.GetFileName( filename ) );
+ return -1;
+ }
+
+ #region [ ãããã°è¡¨ç¤º ]
+ //Debug.WriteLine( "**WAVEFORMATEX**" );
+ //Debug.WriteLine( "wFormatTag= " + waveformatex.wFormatTag.ToString( "X4" ) );
+ //Debug.WriteLine( "nChannels = " + waveformatex.nChannels.ToString( "X4" ) );
+ //Debug.WriteLine( "nSamplesPerSec= " + waveformatex.nSamplesPerSec.ToString( "X8" ) );
+ //Debug.WriteLine( "nAvgBytesPerSec= " + waveformatex.nAvgBytesPerSec.ToString( "X8" ) );
+ //Debug.WriteLine( "nBlockAlign= " + waveformatex.nBlockAlign.ToString( "X4" ) );
+ //Debug.WriteLine( "wBitsPerSample= " + waveformatex.wBitsPerSample.ToString( "X4" ) );
+ //Debug.WriteLine( "cbSize= " + waveformatex.cbSize.ToString( "X4" ) );
+ #endregion
+ #endregion
+
+ this.nHandle = (int) hxas;
+ return (int) hxas;
+ }
+ public override int GetFormat( int nHandle, ref CWin32.WAVEFORMATEX wfx )
+ {
+ #region [ WAVEFORMATEXæ§é ä½ã®æåã³ãã¼ ]
+ wfx.nAvgBytesPerSec = waveformatex.nAvgBytesPerSec;
+ wfx.wBitsPerSample = waveformatex.wBitsPerSample;
+ wfx.nBlockAlign = waveformatex.nBlockAlign;
+ wfx.nChannels = waveformatex.nChannels;
+ wfx.wFormatTag = waveformatex.wFormatTag;
+ wfx.nSamplesPerSec = waveformatex.nSamplesPerSec;
+
+ return 0;
+ #endregion
+ }
+ public override uint GetTotalPCMSize( int nHandle )
+ {
+ #region [ ãã¼ã¿é·ã®åå¾ ]
+ uint dlen;
+ xaDecodeSize( (IntPtr) nHandle, xaheader.nDataLen, out dlen );
+ #region [ ãããã°è¡¨ç¤º ]
+ //Debug.WriteLine( "**INTERNAL VALUE**" );
+ //Debug.WriteLine( "dlen= " + dlen );
+ #endregion
+ #endregion
+
+ return dlen;
+ }
+ public override int Seek( int nHandle, uint dwPosition )
+ {
+ return 0;
+ }
+ public override int Decode( int nHandle, IntPtr pDest, uint szDestSize, int bLoop )
+ {
+ #region [ xaãã¼ã¿ã®ãã³ã¼ã ]
+ xastreamheader = new XASTREAMHEADER();
+ unsafe
+ {
+ fixed ( byte* pXaBuf = srcBuf )
+ {
+ byte* pWavBuf = (byte*) pDest;
+
+ xastreamheader.pSrc = pXaBuf;
+ xastreamheader.nSrcLen = xaheader.nDataLen;
+ xastreamheader.nSrcUsed = 0;
+ xastreamheader.pDst = pWavBuf;
+ xastreamheader.nDstLen = szDestSize;
+ xastreamheader.nDstUsed = 0;
+ if ( !xaDecodeConvert( (IntPtr) nHandle, ref xastreamheader ) )
+ {
+ Trace.TraceError( "Error: xaDecodeConvert(): " + Path.GetFileName( filename ) );
+ return -1;
+ }
+ }
+ }
+ #region [ ãããã°è¡¨ç¤º ]
+ //Debug.WriteLine( "**XASTREAMHEADER**" );
+ //Debug.WriteLine( "nSrcLen= " + xastreamheader.nSrcLen );
+ //Debug.WriteLine( "nSrcUsed= " + xastreamheader.nSrcUsed );
+ //Debug.WriteLine( "nDstLen= " + xastreamheader.nDstLen );
+ //Debug.WriteLine( "nDstUsed= " + xastreamheader.nDstUsed );
+ #endregion
+ #endregion
+
+ return 0;
+ }
+ public override void Close( int nHandle )
+ {
+ #region [ xaãã¡ã¤ã«ã®ã¯ãã¼ãº ]
+ if ( !xaDecodeClose( (IntPtr) nHandle ) )
+ {
+ Trace.TraceError( "Error: xaDecodeClose(): " + Path.GetFileName( filename ) );
+ }
+ srcBuf = null;
+ #endregion
+ }
+
+
+
+ //#region [ IDisposable å®è£
]
+ ////-----------------
+ //private bool bDisposeå®äºæ¸ã¿ = false;
+ //public void Dispose()
+ //{
+ // if ( !this.bDisposeå®äºæ¸ã¿ )
+ // {
+ // if ( srcBuf != null )
+ // {
+ // srcBuf = null;
+ // }
+ // if ( dstBuf != null )
+ // {
+ // dstBuf = null;
+ // }
+
+ // if ( this.nHandle >= 0 )
+ // {
+ // this.Close( this.nHandle );
+ // this.nHandle = -1;
+ // }
+ // this.bDisposeå®äºæ¸ã¿ = true;
+ // }
+ //}
+ ////-----------------
+ //#endregion
+
+#if false
+ ///
+ /// xaãã¡ã¤ã«ãèªã¿è¾¼ãã§ãwavã«decodeãã
+ ///
+ /// xaãã¡ã¤ã«å
+ /// wavãã¡ã¤ã«ãæ ¼ç´ããããããã¡
+ ///
+ public bool Decode( string filename, out byte[] wavBuf )
+ {
+ // Debug.WriteLine( "xa: Decode: " + Path.GetFileName( filename ) );
+
+ #region [ XAãããã¨ãXAãã¼ã¿ã®èªã¿åºã ]
+ xaheader = new XAHEADER();
+ byte[] xaBuf;
+ using ( FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ) ) // FileShare ãä»ãã¨ããªãã¨ãClose() å¾ãããã¯ãããã??
+ {
+ using ( BinaryReader br = new BinaryReader( fs ) )
+ {
+ xaheader.id = br.ReadUInt32();
+ xaheader.nDataLen = br.ReadUInt32();
+ xaheader.nSamples = br.ReadUInt32();
+ xaheader.nSamplesPerSec = br.ReadUInt16();
+ xaheader.nBits = br.ReadByte();
+ xaheader.nChannels = br.ReadByte();
+ xaheader.nLoopPtr = br.ReadUInt32();
+
+ xaheader.befL = new short[ 2 ];
+ xaheader.befR = new short[ 2 ];
+ xaheader.pad = new byte[ 4 ];
+
+ xaheader.befL[ 0 ] = br.ReadInt16();
+ xaheader.befL[ 1 ] = br.ReadInt16();
+ xaheader.befR[ 0 ] = br.ReadInt16();
+ xaheader.befR[ 1 ] = br.ReadInt16();
+ xaheader.pad = br.ReadBytes( 4 );
+
+ xaBuf = new byte[ xaheader.nDataLen ];
+ xaBuf = br.ReadBytes( (int) xaheader.nDataLen );
+ }
+ }
+ //string xaid = Encoding.ASCII.GetString( xah.id );
+ #region [ ãããã°è¡¨ç¤º ]
+ //Debug.WriteLine( "**XAHEADER**" );
+ //Debug.WriteLine( "id= " + xaheader.id.ToString( "X8" ) );
+ //Debug.WriteLine( "nDataLen= " + xaheader.nDataLen.ToString( "X8" ) );
+ //Debug.WriteLine( "nSamples= " + xaheader.nSamples.ToString( "X8" ) );
+ //Debug.WriteLine( "nSamplesPerSec= " + xaheader.nSamplesPerSec.ToString( "X4" ) );
+ //Debug.WriteLine( "nBits= " + xaheader.nBits.ToString( "X2" ) );
+ //Debug.WriteLine( "nChannels= " + xaheader.nChannels.ToString( "X2" ) );
+ //Debug.WriteLine( "nLoopPtr= " + xaheader.nLoopPtr.ToString( "X8" ) );
+ //Debug.WriteLine( "befL[0]= " + xaheader.befL[ 0 ].ToString( "X4" ) );
+ //Debug.WriteLine( "befL[1]= " + xaheader.befL[ 1 ].ToString( "X4" ) );
+ //Debug.WriteLine( "befR[0]= " + xaheader.befR[ 0 ].ToString( "X4" ) );
+ //Debug.WriteLine( "befR[1]= " + xaheader.befR[ 1 ].ToString( "X4" ) );
+ #endregion
+ #endregion
+
+ object lockobj = new object();
+ lock ( lockobj ) // ã¹ã¬ããã»ã¼ããããªãããç¥ããªãã®ã§ã念ã®ãã
+ {
+ #region [ WAVEFORMEXæ
å ±ã®åå¾ ]
+ waveformatex = new CWin32.WAVEFORMATEX();
+ IntPtr hxas = xaDecodeOpen( ref xaheader, out waveformatex );
+ if ( hxas == null )
+ {
+ Trace.TraceError( "Error: xaDecodeOpen(): " + Path.GetFileName( filename ) );
+ wavBuf = null;
+ return false;
+ }
+
+ #region [ ãããã°è¡¨ç¤º ]
+ //Debug.WriteLine( "**WAVEFORMATEX**" );
+ //Debug.WriteLine( "wFormatTag= " + waveformatex.wFormatTag.ToString( "X4" ) );
+ //Debug.WriteLine( "nChannels = " + waveformatex.nChannels.ToString( "X4" ) );
+ //Debug.WriteLine( "nSamplesPerSec= " + waveformatex.nSamplesPerSec.ToString( "X8" ) );
+ //Debug.WriteLine( "nAvgBytesPerSec= " + waveformatex.nAvgBytesPerSec.ToString( "X8" ) );
+ //Debug.WriteLine( "nBlockAlign= " + waveformatex.nBlockAlign.ToString( "X4" ) );
+ //Debug.WriteLine( "wBitsPerSample= " + waveformatex.wBitsPerSample.ToString( "X4" ) );
+ //Debug.WriteLine( "cbSize= " + waveformatex.cbSize.ToString( "X4" ) );
+ #endregion
+ #endregion
+
+ #region [ ãã¼ã¿é·ã®åå¾ ]
+ uint dlen;
+ xaDecodeSize( hxas, xaheader.nDataLen, out dlen );
+ #region [ ãããã°è¡¨ç¤º ]
+ //Debug.WriteLine( "**INTERNAL VALUE**" );
+ //Debug.WriteLine( "dlen= " + dlen );
+ #endregion
+ #endregion
+
+ #region [ xaãã¼ã¿ã®ãã³ã¼ã ]
+ wavBuf = new byte[ dlen ];
+ xastreamheader = new XASTREAMHEADER();
+
+ unsafe
+ {
+ fixed ( byte* pXaBuf = xaBuf, pWavBuf = wavBuf )
+ {
+ xastreamheader.pSrc = pXaBuf;
+ xastreamheader.nSrcLen = xaheader.nDataLen;
+ xastreamheader.nSrcUsed = 0;
+ xastreamheader.pDst = pWavBuf;
+ xastreamheader.nDstLen = dlen;
+ xastreamheader.nDstUsed = 0;
+ bool b = xaDecodeConvert( hxas, ref xastreamheader );
+ if ( !b )
+ {
+ Trace.TraceError( "Error: xaDecodeConvert(): " + Path.GetFileName( filename ) );
+ wavBuf = null;
+ return false;
+ }
+ }
+ }
+ #region [ ãããã°è¡¨ç¤º ]
+ //Debug.WriteLine( "**XASTREAMHEADER**" );
+ //Debug.WriteLine( "nSrcLen= " + xastreamheader.nSrcLen );
+ //Debug.WriteLine( "nSrcUsed= " + xastreamheader.nSrcUsed );
+ //Debug.WriteLine( "nDstLen= " + xastreamheader.nDstLen );
+ //Debug.WriteLine( "nDstUsed= " + xastreamheader.nDstUsed );
+ #endregion
+ #endregion
+
+ #region [ xaãã¡ã¤ã«ã®ã¯ãã¼ãº ]
+ bool bb = xaDecodeClose( hxas );
+ if ( !bb )
+ {
+ Trace.TraceError( "Error: xaDecodeClose(): " + Path.GetFileName( filename ) );
+ }
+ #endregion
+ }
+
+ return true;
+ }
+#endif
+ }
+}