mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
- Fixed Sarkhan Vol and Ajani Goldmane token controllership issues. Also fixed Ajani Goldmane?\127 lifegain after a different player takes control of it. - Memnarch's first ability will put the Artifact type at the beginning of the type text (so "Artifact Planeswalker - Ajani" instead of "Planeswalker - Ajani Artifact"). - Planeswalkers with the same "subtype" should get destroyed correctly now if there are two or more in play, even if one of them got "Memnarched" into an artifact.
522 lines
14 KiB
Java
522 lines
14 KiB
Java
/*
|
|
* 11/19/04 1.0 moved to LGPL.
|
|
* 02/23/99 JavaConversion by E.B
|
|
* Don Cross, April 1993.
|
|
* RIFF file format classes.
|
|
* See Chapter 8 of "Multimedia Programmer's Reference" in
|
|
* the Microsoft Windows SDK.
|
|
*
|
|
*-----------------------------------------------------------------------
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Library General Public License as published
|
|
* by the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*----------------------------------------------------------------------
|
|
*/
|
|
|
|
package javazoom.jl.converter;
|
|
|
|
/**
|
|
* Class allowing WaveFormat Access
|
|
*/
|
|
public class WaveFile extends RiffFile
|
|
{
|
|
public static final int MAX_WAVE_CHANNELS = 2;
|
|
|
|
static class WaveFormat_ChunkData
|
|
{
|
|
public short wFormatTag = 0; // Format category (PCM=1)
|
|
public short nChannels = 0; // Number of channels (mono=1, stereo=2)
|
|
public int nSamplesPerSec = 0; // Sampling rate [Hz]
|
|
public int nAvgBytesPerSec = 0;
|
|
public short nBlockAlign = 0;
|
|
public short nBitsPerSample = 0;
|
|
|
|
public WaveFormat_ChunkData()
|
|
{
|
|
wFormatTag = 1; // PCM
|
|
Config(44100,(short)16,(short)1);
|
|
}
|
|
|
|
public void Config (int NewSamplingRate, short NewBitsPerSample, short NewNumChannels)
|
|
{
|
|
nSamplesPerSec = NewSamplingRate;
|
|
nChannels = NewNumChannels;
|
|
nBitsPerSample = NewBitsPerSample;
|
|
nAvgBytesPerSec = (nChannels * nSamplesPerSec * nBitsPerSample) / 8;
|
|
nBlockAlign = (short) ((nChannels * nBitsPerSample) / 8);
|
|
}
|
|
}
|
|
|
|
|
|
class WaveFormat_Chunk
|
|
{
|
|
public RiffChunkHeader header;
|
|
public WaveFormat_ChunkData data;
|
|
|
|
public WaveFormat_Chunk()
|
|
{
|
|
header = new RiffChunkHeader();
|
|
data = new WaveFormat_ChunkData();
|
|
header.ckID = FourCC("fmt ");
|
|
header.ckSize = 16;
|
|
}
|
|
|
|
public int VerifyValidity()
|
|
{
|
|
boolean ret = header.ckID == FourCC("fmt ") &&
|
|
|
|
(data.nChannels == 1 || data.nChannels == 2) &&
|
|
|
|
data.nAvgBytesPerSec == ( data.nChannels *
|
|
data.nSamplesPerSec *
|
|
data.nBitsPerSample ) / 8 &&
|
|
|
|
data.nBlockAlign == ( data.nChannels *
|
|
data.nBitsPerSample ) / 8;
|
|
if (ret == true) return 1;
|
|
else return 0;
|
|
}
|
|
}
|
|
|
|
public static class WaveFileSample
|
|
{
|
|
public short[] chan;
|
|
|
|
public WaveFileSample()
|
|
{chan = new short[WaveFile.MAX_WAVE_CHANNELS];}
|
|
}
|
|
|
|
private WaveFormat_Chunk wave_format;
|
|
private RiffChunkHeader pcm_data;
|
|
private long pcm_data_offset = 0; // offset of 'pcm_data' in output file
|
|
private int num_samples = 0;
|
|
|
|
|
|
/**
|
|
* Constructs a new WaveFile instance.
|
|
*/
|
|
public WaveFile()
|
|
{
|
|
pcm_data = new RiffChunkHeader();
|
|
wave_format = new WaveFormat_Chunk();
|
|
pcm_data.ckID = FourCC("data");
|
|
pcm_data.ckSize = 0;
|
|
num_samples = 0;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*
|
|
public int OpenForRead (String Filename)
|
|
{
|
|
// Verify filename parameter as best we can...
|
|
if (Filename == null)
|
|
{
|
|
return DDC_INVALID_CALL;
|
|
}
|
|
int retcode = Open ( Filename, RFM_READ );
|
|
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
retcode = Expect ( "WAVE", 4 );
|
|
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
retcode = Read(wave_format,24);
|
|
|
|
if ( retcode == DDC_SUCCESS && !wave_format.VerifyValidity() )
|
|
{
|
|
// This isn't standard PCM, so we don't know what it is!
|
|
retcode = DDC_FILE_ERROR;
|
|
}
|
|
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
pcm_data_offset = CurrentFilePosition();
|
|
|
|
// Figure out number of samples from
|
|
// file size, current file position, and
|
|
// WAVE header.
|
|
retcode = Read (pcm_data, 8 );
|
|
num_samples = filelength(fileno(file)) - CurrentFilePosition();
|
|
num_samples /= NumChannels();
|
|
num_samples /= (BitsPerSample() / 8);
|
|
}
|
|
}
|
|
}
|
|
return retcode;
|
|
}*/
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public int OpenForWrite (String Filename, int SamplingRate, short BitsPerSample, short NumChannels)
|
|
{
|
|
// Verify parameters...
|
|
if ( (Filename==null) ||
|
|
(BitsPerSample != 8 && BitsPerSample != 16) ||
|
|
NumChannels < 1 || NumChannels > 2 )
|
|
{
|
|
return DDC_INVALID_CALL;
|
|
}
|
|
|
|
wave_format.data.Config ( SamplingRate, BitsPerSample, NumChannels );
|
|
|
|
int retcode = Open ( Filename, RFM_WRITE );
|
|
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
byte [] theWave = {(byte)'W',(byte)'A',(byte)'V',(byte)'E'};
|
|
retcode = Write ( theWave, 4 );
|
|
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
// Ecriture de wave_format
|
|
retcode = Write (wave_format.header, 8);
|
|
retcode = Write (wave_format.data.wFormatTag, 2);
|
|
retcode = Write (wave_format.data.nChannels, 2);
|
|
retcode = Write (wave_format.data.nSamplesPerSec, 4);
|
|
retcode = Write (wave_format.data.nAvgBytesPerSec, 4);
|
|
retcode = Write (wave_format.data.nBlockAlign, 2);
|
|
retcode = Write (wave_format.data.nBitsPerSample, 2);
|
|
/* byte[] br = new byte[16];
|
|
br[0] = (byte) ((wave_format.data.wFormatTag >> 8) & 0x00FF);
|
|
br[1] = (byte) (wave_format.data.wFormatTag & 0x00FF);
|
|
|
|
br[2] = (byte) ((wave_format.data.nChannels >> 8) & 0x00FF);
|
|
br[3] = (byte) (wave_format.data.nChannels & 0x00FF);
|
|
|
|
br[4] = (byte) ((wave_format.data.nSamplesPerSec >> 24)& 0x000000FF);
|
|
br[5] = (byte) ((wave_format.data.nSamplesPerSec >> 16)& 0x000000FF);
|
|
br[6] = (byte) ((wave_format.data.nSamplesPerSec >> 8)& 0x000000FF);
|
|
br[7] = (byte) (wave_format.data.nSamplesPerSec & 0x000000FF);
|
|
|
|
br[8] = (byte) ((wave_format.data.nAvgBytesPerSec>> 24)& 0x000000FF);
|
|
br[9] = (byte) ((wave_format.data.nAvgBytesPerSec >> 16)& 0x000000FF);
|
|
br[10] = (byte) ((wave_format.data.nAvgBytesPerSec >> 8)& 0x000000FF);
|
|
br[11] = (byte) (wave_format.data.nAvgBytesPerSec & 0x000000FF);
|
|
|
|
br[12] = (byte) ((wave_format.data.nBlockAlign >> 8) & 0x00FF);
|
|
br[13] = (byte) (wave_format.data.nBlockAlign & 0x00FF);
|
|
|
|
br[14] = (byte) ((wave_format.data.nBitsPerSample >> 8) & 0x00FF);
|
|
br[15] = (byte) (wave_format.data.nBitsPerSample & 0x00FF);
|
|
retcode = Write (br, 16); */
|
|
|
|
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
pcm_data_offset = CurrentFilePosition();
|
|
retcode = Write ( pcm_data, 8 );
|
|
}
|
|
}
|
|
}
|
|
|
|
return retcode;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*
|
|
public int ReadSample ( short[] Sample )
|
|
{
|
|
|
|
}*/
|
|
|
|
/**
|
|
*
|
|
*
|
|
public int WriteSample( short[] Sample )
|
|
{
|
|
int retcode = DDC_SUCCESS;
|
|
switch ( wave_format.data.nChannels )
|
|
{
|
|
case 1:
|
|
switch ( wave_format.data.nBitsPerSample )
|
|
{
|
|
case 8:
|
|
pcm_data.ckSize += 1;
|
|
retcode = Write ( Sample, 1 );
|
|
break;
|
|
|
|
case 16:
|
|
pcm_data.ckSize += 2;
|
|
retcode = Write ( Sample, 2 );
|
|
break;
|
|
|
|
default:
|
|
retcode = DDC_INVALID_CALL;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
switch ( wave_format.data.nBitsPerSample )
|
|
{
|
|
case 8:
|
|
retcode = Write ( Sample, 1 );
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
// &Sample[1]
|
|
retcode = Write (Sample, 1 );
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
pcm_data.ckSize += 2;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 16:
|
|
retcode = Write ( Sample, 2 );
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
// &Sample[1]
|
|
retcode = Write (Sample, 2 );
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
pcm_data.ckSize += 4;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
retcode = DDC_INVALID_CALL;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
retcode = DDC_INVALID_CALL;
|
|
}
|
|
|
|
return retcode;
|
|
}*/
|
|
|
|
/**
|
|
*
|
|
*
|
|
public int SeekToSample ( long SampleIndex )
|
|
{
|
|
if ( SampleIndex >= NumSamples() )
|
|
{
|
|
return DDC_INVALID_CALL;
|
|
}
|
|
int SampleSize = (BitsPerSample() + 7) / 8;
|
|
int rc = Seek ( pcm_data_offset + 8 +
|
|
SampleSize * NumChannels() * SampleIndex );
|
|
return rc;
|
|
}*/
|
|
|
|
/**
|
|
* Write 16-bit audio
|
|
*/
|
|
public int WriteData ( short[] data, int numData )
|
|
{
|
|
int extraBytes = numData * 2;
|
|
pcm_data.ckSize += extraBytes;
|
|
return super.Write ( data, extraBytes );
|
|
}
|
|
|
|
/**
|
|
* Read 16-bit audio.
|
|
*
|
|
public int ReadData (short[] data, int numData)
|
|
{return super.Read ( data, numData * 2);} */
|
|
|
|
/**
|
|
* Write 8-bit audio.
|
|
*
|
|
public int WriteData ( byte[] data, int numData )
|
|
{
|
|
pcm_data.ckSize += numData;
|
|
return super.Write ( data, numData );
|
|
}*/
|
|
|
|
/**
|
|
* Read 8-bit audio.
|
|
*
|
|
public int ReadData ( byte[] data, int numData )
|
|
{return super.Read ( data, numData );} */
|
|
|
|
|
|
/**
|
|
*
|
|
*
|
|
public int ReadSamples (int num, int [] WaveFileSample)
|
|
{
|
|
|
|
}*/
|
|
|
|
/**
|
|
*
|
|
*
|
|
public int WriteMonoSample ( short[] SampleData )
|
|
{
|
|
switch ( wave_format.data.nBitsPerSample )
|
|
{
|
|
case 8:
|
|
pcm_data.ckSize += 1;
|
|
return Write ( SampleData, 1 );
|
|
|
|
case 16:
|
|
pcm_data.ckSize += 2;
|
|
return Write ( SampleData, 2 );
|
|
}
|
|
return DDC_INVALID_CALL;
|
|
}*/
|
|
|
|
/**
|
|
*
|
|
*
|
|
public int WriteStereoSample ( short[] LeftSample, short[] RightSample )
|
|
{
|
|
int retcode = DDC_SUCCESS;
|
|
switch ( wave_format.data.nBitsPerSample )
|
|
{
|
|
case 8:
|
|
retcode = Write ( LeftSample, 1 );
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
retcode = Write ( RightSample, 1 );
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
pcm_data.ckSize += 2;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 16:
|
|
retcode = Write ( LeftSample, 2 );
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
retcode = Write ( RightSample, 2 );
|
|
if ( retcode == DDC_SUCCESS )
|
|
{
|
|
pcm_data.ckSize += 4;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
retcode = DDC_INVALID_CALL;
|
|
}
|
|
return retcode;
|
|
}*/
|
|
|
|
/**
|
|
*
|
|
*
|
|
public int ReadMonoSample ( short[] Sample )
|
|
{
|
|
int retcode = DDC_SUCCESS;
|
|
switch ( wave_format.data.nBitsPerSample )
|
|
{
|
|
case 8:
|
|
byte[] x = {0};
|
|
retcode = Read ( x, 1 );
|
|
Sample[0] = (short)(x[0]);
|
|
break;
|
|
|
|
case 16:
|
|
retcode = Read ( Sample, 2 );
|
|
break;
|
|
|
|
default:
|
|
retcode = DDC_INVALID_CALL;
|
|
}
|
|
return retcode;
|
|
}*/
|
|
|
|
/**
|
|
*
|
|
*
|
|
public int ReadStereoSample ( short[] LeftSampleData, short[] RightSampleData )
|
|
{
|
|
int retcode = DDC_SUCCESS;
|
|
byte[] x = new byte[2];
|
|
short[] y = new short[2];
|
|
switch ( wave_format.data.nBitsPerSample )
|
|
{
|
|
case 8:
|
|
retcode = Read ( x, 2 );
|
|
L[0] = (short) ( x[0] );
|
|
R[0] = (short) ( x[1] );
|
|
break;
|
|
|
|
case 16:
|
|
retcode = Read ( y, 4 );
|
|
L[0] = (short) ( y[0] );
|
|
R[0] = (short) ( y[1] );
|
|
break;
|
|
|
|
default:
|
|
retcode = DDC_INVALID_CALL;
|
|
}
|
|
return retcode;
|
|
}*/
|
|
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public int Close()
|
|
{
|
|
int rc = DDC_SUCCESS;
|
|
|
|
if ( fmode == RFM_WRITE )
|
|
rc = Backpatch ( pcm_data_offset, pcm_data, 8 );
|
|
if ( rc == DDC_SUCCESS )
|
|
rc = super.Close();
|
|
return rc;
|
|
}
|
|
|
|
// [Hz]
|
|
public int SamplingRate()
|
|
{return wave_format.data.nSamplesPerSec;}
|
|
|
|
public short BitsPerSample()
|
|
{return wave_format.data.nBitsPerSample;}
|
|
|
|
public short NumChannels()
|
|
{return wave_format.data.nChannels;}
|
|
|
|
public int NumSamples()
|
|
{return num_samples;}
|
|
|
|
|
|
/**
|
|
* Open for write using another wave file's parameters...
|
|
*/
|
|
public int OpenForWrite (String Filename, WaveFile OtherWave )
|
|
{
|
|
return OpenForWrite ( Filename,
|
|
OtherWave.SamplingRate(),
|
|
OtherWave.BitsPerSample(),
|
|
OtherWave.NumChannels() );
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public long CurrentFilePosition()
|
|
{
|
|
return super.CurrentFilePosition();
|
|
}
|
|
|
|
/* public int FourCC(String ChunkName)
|
|
{
|
|
byte[] p = {0x20,0x20,0x20,0x20};
|
|
ChunkName.getBytes(0,4,p,0);
|
|
int ret = (((p[0] << 24)& 0xFF000000) | ((p[1] << 16)&0x00FF0000) | ((p[2] << 8)&0x0000FF00) | (p[3]&0x000000FF));
|
|
return ret;
|
|
}*/
|
|
|
|
} |