Removed all warnings. FFT still needs work.

Added test application.

svn path=/trunk/csvorbis/; revision=4017
This commit is contained in:
Mark Crichton 2002-04-24 04:12:50 +00:00
Родитель 6530017e23
Коммит 7aed3ef62b
36 изменённых файлов: 6600 добавлений и 6074 удалений

Двоичные данные
OggDecoder/App.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Просмотреть файл

@ -0,0 +1,58 @@
using System.Reflection;
using System.Runtime.CompilerServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

343
OggDecoder/OggDecoder.cs Normal file
Просмотреть файл

@ -0,0 +1,343 @@
using System;
using System.IO;
using csogg;
using csvorbis;
namespace OggDecoder
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Decoder
{
static int convsize=4096*2;
static byte[] convbuffer=new byte[convsize]; // take 8k out of the data segment, not the stack
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
TextWriter s_err = Console.Error;
FileStream input = null, output = null;
if(args.Length == 2)
{
try
{
input = new FileStream(args[0], FileMode.Open);
output = new FileStream(args[1], FileMode.OpenOrCreate);
}
catch(Exception e)
{
s_err.WriteLine(e);
}
}
else
{
return;
}
SyncState oy=new SyncState(); // sync and verify incoming physical bitstream
StreamState os=new StreamState(); // take physical pages, weld into a logical stream of packets
Page og=new Page(); // one Ogg bitstream page. Vorbis packets are inside
Packet op=new Packet(); // one raw packet of data for decode
Info vi=new Info(); // struct that stores all the static vorbis bitstream settings
Comment vc=new Comment(); // struct that stores all the bitstream user comments
DspState vd=new DspState(); // central working state for the packet->PCM decoder
Block vb=new Block(vd); // local working space for packet->PCM decode
byte[] buffer;
int bytes=0;
// Decode setup
oy.init(); // Now we can read pages
while(true)
{ // we repeat if the bitstream is chained
int eos=0;
// grab some data at the head of the stream. We want the first page
// (which is guaranteed to be small and only contain the Vorbis
// stream initial header) We need the first page to get the stream
// serialno.
// submit a 4k block to libvorbis' Ogg layer
int index=oy.buffer(4096);
buffer=oy.data;
try
{
s_err.WriteLine("Read a little bit...");
bytes = input.Read(buffer, index, 4096);
}
catch(Exception e)
{
s_err.WriteLine(e);
}
oy.wrote(bytes);
// Get the first page.
if(oy.pageout(og)!=1)
{
// have we simply run out of data? If so, we're done.
if(bytes<4096)break;
// error case. Must not be Vorbis data
s_err.WriteLine("Input does not appear to be an Ogg bitstream.");
}
// Get the serial number and set up the rest of decode.
// serialno first; use it to set up a logical stream
os.init(og.serialno());
// extract the initial header from the first page and verify that the
// Ogg bitstream is in fact Vorbis data
// I handle the initial header first instead of just having the code
// read all three Vorbis headers at once because reading the initial
// header is an easy way to identify a Vorbis bitstream and it's
// useful to see that functionality seperated out.
vi.init();
vc.init();
if(os.pagein(og)<0)
{
// error; stream version mismatch perhaps
s_err.WriteLine("Error reading first page of Ogg bitstream data.");
}
if(os.packetout(op)!=1)
{
// no page? must not be vorbis
s_err.WriteLine("Error reading initial header packet.");
}
if(vi.synthesis_headerin(vc,op)<0)
{
// error case; not a vorbis header
s_err.WriteLine("This Ogg bitstream does not contain Vorbis audio data.");
}
// At this point, we're sure we're Vorbis. We've set up the logical
// (Ogg) bitstream decoder. Get the comment and codebook headers and
// set up the Vorbis decoder
// The next two packets in order are the comment and codebook headers.
// They're likely large and may span multiple pages. Thus we reead
// and submit data until we get our two pacakets, watching that no
// pages are missing. If a page is missing, error out; losing a
// header page is the only place where missing data is fatal. */
int i=0;
s_err.WriteLine("Starting the fun...");
while(i<2)
{
while(i<2)
{
int result=oy.pageout(og);
if(result==0) break; // Need more data
// Don't complain about missing or corrupt data yet. We'll
// catch it at the packet output phase
if(result==1)
{
os.pagein(og); // we can ignore any errors here
// as they'll also become apparent
// at packetout
while(i<2)
{
result=os.packetout(op);
if(result==0)break;
if(result==-1)
{
// Uh oh; data at some point was corrupted or missing!
// We can't tolerate that in a header. Die.
s_err.WriteLine("Corrupt secondary header. Exiting.");
}
vi.synthesis_headerin(vc,op);
i++;
}
}
}
// no harm in not checking before adding more
index=oy.buffer(4096);
buffer=oy.data;
try
{
bytes=input.Read(buffer, index, 4096);
}
catch(Exception e)
{
s_err.WriteLine(e);
}
if(bytes==0 && i<2)
{
s_err.WriteLine("End of file before finding all Vorbis headers!");
}
oy.wrote(bytes);
}
// Throw the comments plus a few lines about the bitstream we're
// decoding
{
byte[][] ptr=vc.user_comments;
for(int j=0; j<ptr.Length;j++)
{
if(ptr[j]==null) break;
s_err.WriteLine(ptr[j].ToString());
}
s_err.WriteLine("\nBitstream is "+vi.channels+" channel, "+vi.rate+"Hz");
s_err.WriteLine("Encoded by: "+vc.vendor.ToString()+"\n");
}
convsize=4096/vi.channels;
// OK, got and parsed all three headers. Initialize the Vorbis
// packet->PCM decoder.
s_err.WriteLine("Entering Init Routines");
vd.synthesis_init(vi); // central decode state
s_err.WriteLine("synthesis_init DONE");
vb.init(vd); // local state for most of the decode
s_err.WriteLine("Init DONE!");
// so multiple block decodes can
// proceed in parallel. We could init
// multiple vorbis_block structures
// for vd here
float[][][] _pcm=new float[1][][];
int[] _index=new int[vi.channels];
// The rest is just a straight decode loop until end of stream
while(eos==0)
{
while(eos==0)
{
int result=oy.pageout(og);
if(result==0)break; // need more data
if(result==-1)
{ // missing or corrupt data at this page position
s_err.WriteLine("Corrupt or missing data in bitstream; continuing...");
}
else
{
os.pagein(og); // can safely ignore errors at
// this point
while(true)
{
result=os.packetout(op);
if(result==0)break; // need more data
if(result==-1)
{ // missing or corrupt data at this page position
// no reason to complain; already complained above
}
else
{
// we have a packet. Decode it
int samples;
if(vb.synthesis(op)==0)
{ // test for success!
s_err.WriteLine("Blockin' the synth");
vd.synthesis_blockin(vb);
s_err.WriteLine("Done.");
}
// **pcm is a multichannel float vector. In stereo, for
// example, pcm[0] is left, and pcm[1] is right. samples is
// the size of each channel. Convert the float values
// (-1.<=range<=1.) to whatever PCM format and write it out
while((samples=vd.synthesis_pcmout(_pcm, _index))>0)
{
float[][] pcm=_pcm[0];
bool clipflag=false;
int bout=(samples<convsize?samples:convsize);
// convert floats to 16 bit signed ints (host order) and
// interleave
for(i=0;i<vi.channels;i++)
{
int ptr=i*2;
//int ptr=i;
int mono=_index[i];
for(int j=0;j<bout;j++)
{
int val=(int)(pcm[i][mono+j]*32767.0);
// short val=(short)(pcm[i][mono+j]*32767.);
// int val=(int)Math.round(pcm[i][mono+j]*32767.);
// might as well guard against clipping
if(val>32767)
{
val=32767;
clipflag=true;
}
if(val<-32768)
{
val=-32768;
clipflag=true;
}
if(val<0) val=val|0x8000;
convbuffer[ptr]=(byte)(val);
convbuffer[ptr+1]=(byte)((uint)val>>8);
ptr+=2*(vi.channels);
}
}
if(clipflag)
s_err.WriteLine("Clipping in frame "+vd.sequence);
s_err.WriteLine("ScribbleScribble");
output.Write(convbuffer, 0, 2*vi.channels*bout);
vd.synthesis_read(bout); // tell libvorbis how
// many samples we
// actually consumed
}
}
}
if(og.eos()!=0)eos=1;
}
}
if(eos==0)
{
index=oy.buffer(4096);
buffer=oy.data;
try
{
bytes=input.Read(buffer,index,4096);
}
catch(Exception e)
{
s_err.WriteLine(e);
}
oy.wrote(bytes);
if(bytes==0)eos=1;
}
}
// clean up this logical bitstream; before exit we see if we're
// followed by another [chained]
os.clear();
// ogg_page and ogg_packet structs always point to storage in
// libvorbis. They're never freed or manipulated directly
vb.clear();
vd.clear();
vi.clear(); // must be called last
}
// OK, clean up the framer
oy.clear();
s_err.WriteLine("Done.");
}
}
}

Просмотреть файл

@ -0,0 +1,107 @@
<VisualStudioProject>
<CSHARP
ProjectType = "Local"
ProductVersion = "7.0.9466"
SchemaVersion = "1.0"
ProjectGuid = "{4CA9EB23-E111-4DAD-9932-F73E8E6C54C5}"
>
<Build>
<Settings
ApplicationIcon = "App.ico"
AssemblyKeyContainerName = ""
AssemblyName = "OggDecoder"
AssemblyOriginatorKeyFile = ""
DefaultClientScript = "JScript"
DefaultHTMLPageLayout = "Grid"
DefaultTargetSchema = "IE50"
DelaySign = "false"
OutputType = "Exe"
RootNamespace = "OggDecoder"
StartupObject = ""
>
<Config
Name = "Debug"
AllowUnsafeBlocks = "false"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "DEBUG;TRACE"
DocumentationFile = ""
DebugSymbols = "true"
FileAlignment = "4096"
IncrementalBuild = "true"
Optimize = "false"
OutputPath = "bin\Debug\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
<Config
Name = "Release"
AllowUnsafeBlocks = "false"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "TRACE"
DocumentationFile = ""
DebugSymbols = "false"
FileAlignment = "4096"
IncrementalBuild = "false"
Optimize = "true"
OutputPath = "bin\Release\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
</Settings>
<References>
<Reference
Name = "System"
AssemblyName = "System"
HintPath = "..\..\..\..\..\..\WINNT\Microsoft.NET\Framework\v1.0.3705\System.dll"
/>
<Reference
Name = "System.Data"
AssemblyName = "System.Data"
HintPath = "..\..\..\..\..\..\WINNT\Microsoft.NET\Framework\v1.0.3705\System.Data.dll"
/>
<Reference
Name = "System.XML"
AssemblyName = "System.XML"
HintPath = "..\..\..\..\..\..\WINNT\Microsoft.NET\Framework\v1.0.3705\System.XML.dll"
/>
<Reference
Name = "csogg"
Project = "{FA4ACE8B-CDEE-41A3-92D7-C73069B84B83}"
Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
/>
<Reference
Name = "csvorbis"
Project = "{0087C0AF-E896-4C55-A999-5245560BCBE3}"
Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
/>
</References>
</Build>
<Files>
<Include>
<File
RelPath = "App.ico"
BuildAction = "Content"
/>
<File
RelPath = "AssemblyInfo.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "OggDecoder.cs"
SubType = "Code"
BuildAction = "Compile"
/>
</Include>
</Files>
</CSHARP>
</VisualStudioProject>

Просмотреть файл

@ -0,0 +1,48 @@
<VisualStudioProject>
<CSHARP>
<Build>
<Settings ReferencePath = "" >
<Config
Name = "Debug"
EnableASPDebugging = "false"
EnableASPXDebugging = "false"
EnableUnmanagedDebugging = "false"
EnableSQLServerDebugging = "false"
RemoteDebugEnabled = "false"
RemoteDebugMachine = ""
StartAction = "Project"
StartArguments = ""
StartPage = ""
StartProgram = ""
StartURL = ""
StartWorkingDirectory = ""
StartWithIE = "true"
/>
<Config
Name = "Release"
EnableASPDebugging = "false"
EnableASPXDebugging = "false"
EnableUnmanagedDebugging = "false"
EnableSQLServerDebugging = "false"
RemoteDebugEnabled = "false"
RemoteDebugMachine = ""
StartAction = "Project"
StartArguments = ""
StartPage = ""
StartProgram = ""
StartURL = ""
StartWorkingDirectory = ""
StartWithIE = "true"
/>
</Settings>
</Build>
<OtherProjectSettings
CopyProjectDestinationFolder = ""
CopyProjectUncPath = ""
CopyProjectOption = "0"
ProjectView = "ProjectFiles"
ProjectTrust = "0"
/>
</CSHARP>
</VisualStudioProject>

Просмотреть файл

@ -70,7 +70,7 @@ namespace csogg
storage = bytes;
}
public void write(uint value, int bits)
public void write(int vvalue, int bits)
{
if(endbyte + 4 >= storage)
{
@ -80,23 +80,23 @@ namespace csogg
storage += BUFFER_INCREMENT;
}
value &= mask[bits];
vvalue = (int)((uint)vvalue & mask[bits]);
bits += endbit;
buffer[ptr] |= (byte)(value << endbit);
buffer[ptr] |= (byte)(vvalue << endbit);
if(bits >= 8)
{
buffer[ptr+1] = (byte)(value >> (8-endbit));
buffer[ptr+1] = (byte)((uint)vvalue >> (8-endbit));
if(bits >= 16)
{
buffer[ptr+2] = (byte)(value >> (16-endbit));
buffer[ptr+2] = (byte)((uint)vvalue >> (16-endbit));
if (bits >= 24)
{
buffer[ptr+3] = (byte)(value >> (24-endbit));
buffer[ptr+3] = (byte)((uint)vvalue >> (24-endbit));
if(bits >= 32)
{
if(endbit > 0)
buffer[ptr+4] = (byte)(value >> (32-endbit));
buffer[ptr+4] = (byte)((uint)vvalue >> (32-endbit));
else
buffer[ptr+4]=0;
}
@ -265,6 +265,11 @@ namespace csogg
return(ret);
}
public byte[] buf()
{
return(buffer);
}
public csBuffer()
{
// Really a noop?

Просмотреть файл

@ -9,14 +9,14 @@
<Settings
ApplicationIcon = ""
AssemblyKeyContainerName = ""
AssemblyName = "cogg"
AssemblyName = "csogg"
AssemblyOriginatorKeyFile = ""
DefaultClientScript = "JScript"
DefaultHTMLPageLayout = "Grid"
DefaultTargetSchema = "IE50"
DelaySign = "false"
OutputType = "Library"
RootNamespace = "cogg"
RootNamespace = "csogg"
StartupObject = ""
>
<Config

Просмотреть файл

@ -25,8 +25,11 @@
using System;
class AllocChain
namespace csvorbis
{
Object ptr;
AllocChain next;
};
class AllocChain
{
//Object ptr;
//AllocChain next;
};
}

Просмотреть файл

@ -26,162 +26,180 @@
using System;
using csogg;
public class Block{
///necessary stream state for linking to the framing abstraction
float[][] pcm=new float[0][]; // this is a pointer into local storage
Buffer opb=new Buffer();
namespace csvorbis
{
public class Block
{
///necessary stream state for linking to the framing abstraction
internal float[][] pcm=new float[0][]; // this is a pointer into local storage
internal csBuffer opb=new csBuffer();
int lW;
int W;
int nW;
int pcmend;
int mode;
internal int lW;
internal int W;
internal int nW;
internal int pcmend;
internal int mode;
int eofflag;
long granulepos;
long sequence;
DspState vd; // For read-only access of configuration
internal int eofflag;
internal long granulepos;
internal long sequence;
internal DspState vd; // For read-only access of configuration
// local storage to avoid remallocing; it's up to the mapping to
// structure it
//byte[] localstore;
//int localtop;
//int localalloc;
//int totaluse;
//AllocChain reap;
// local storage to avoid remallocing; it's up to the mapping to
// structure it
//byte[] localstore;
//int localtop;
//int localalloc;
//int totaluse;
//AllocChain reap;
// bitmetrics for the frame
int glue_bits;
int time_bits;
int floor_bits;
int res_bits;
// bitmetrics for the frame
internal int glue_bits;
internal int time_bits;
internal int floor_bits;
internal int res_bits;
public Block(DspState vd){
this.vd=vd;
// localalloc=0;
// localstore=null;
if(vd.analysisp!=0){
opb.writeinit();
}
}
public Block(DspState vd)
{
this.vd=vd;
// localalloc=0;
// localstore=null;
if(vd.analysisp!=0)
{
opb.writeinit();
}
}
public void init(DspState vd){
this.vd=vd;
}
public void init(DspState vd)
{
this.vd=vd;
}
// int alloc(int bytes){
// bytes=(bytes+(8-1))&(~(8-1));
// if(bytes+localtop>localalloc){
// if(localstore!=null){
// AllocChain link=new AllocChain();
// totaluse+=localtop;
// link.next=reap;
// link.ptr=localstore;
// reap=link;
// }
// // highly conservative
// localalloc=bytes;
// localstore=new byte[localalloc];
// localtop=0;
// }
// {
// int foo=localtop;
// //void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
// localtop+=bytes;
// return foo;
// }
// }
// int alloc(int bytes){
// bytes=(bytes+(8-1))&(~(8-1));
// if(bytes+localtop>localalloc){
// if(localstore!=null){
// AllocChain link=new AllocChain();
// totaluse+=localtop;
// link.next=reap;
// link.ptr=localstore;
// reap=link;
// }
// // highly conservative
// localalloc=bytes;
// localstore=new byte[localalloc];
// localtop=0;
// }
// {
// int foo=localtop;
// //void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
// localtop+=bytes;
// return foo;
// }
// }
// reap the chain, pull the ripcord
// void ripcord(){
// // reap the chain
// while(reap!=null){
// AllocChain next=reap.next;
// //free(reap->ptr);
// reap.ptr=null;
// //memset(reap,0,sizeof(struct alloc_chain));
// //free(reap);
// reap=next;
// }
// // consolidate storage
// if(totaluse!=0){
// //vb->localstore=realloc(vb->localstore,vb->totaluse+vb->localalloc);
// byte[] foo=new byte[totaluse+localalloc];
// System.arraycopy(localstore, 0, foo, 0, localstore.length);
// localstore=foo;
// localalloc+=totaluse;
// totaluse=0;
// }
// // pull the ripcord
// localtop=0;
// reap=null;
// }
// reap the chain, pull the ripcord
// void ripcord(){
// // reap the chain
// while(reap!=null){
// AllocChain next=reap.next;
// //free(reap->ptr);
// reap.ptr=null;
// //memset(reap,0,sizeof(struct alloc_chain));
// //free(reap);
// reap=next;
// }
// // consolidate storage
// if(totaluse!=0){
// //vb->localstore=realloc(vb->localstore,vb->totaluse+vb->localalloc);
// byte[] foo=new byte[totaluse+localalloc];
// Array.Copy(localstore, 0, foo, 0, localstore.length);
// localstore=foo;
// localalloc+=totaluse;
// totaluse=0;
// }
// // pull the ripcord
// localtop=0;
// reap=null;
// }
public int clear(){
if(vd!=null){
if(vd.analysisp!=0){
opb.writeclear();
}
}
//ripcord();
//if(localstore!=null)
// localstore=null;
//memset(vb,0,sizeof(vorbis_block));
return(0);
}
public int clear()
{
if(vd!=null)
{
if(vd.analysisp!=0)
{
opb.writeclear();
}
}
//ripcord();
//if(localstore!=null)
// localstore=null;
//memset(vb,0,sizeof(vorbis_block));
return(0);
}
public int synthesis(Packet op){
Info vi=vd.vi;
public int synthesis(Packet op)
{
Info vi=vd.vi;
// first things first. Make sure decode is ready
// ripcord();
opb.readinit(op.packet_base, op.packet, op.bytes);
// first things first. Make sure decode is ready
// ripcord();
opb.readinit(op.packet_base, op.packet, op.bytes);
// Check the packet type
if(opb.read(1)!=0){
// Oops. This is not an audio data packet
return(-1);
}
// Check the packet type
if(opb.read(1)!=0)
{
// Oops. This is not an audio data packet
return(-1);
}
// read our mode and pre/post windowsize
int _mode=opb.read(vd.modebits);
if(_mode==-1)return(-1);
// read our mode and pre/post windowsize
int _mode=opb.read(vd.modebits);
if(_mode==-1)return(-1);
mode=_mode;
W=vi.mode_param[mode].blockflag;
if(W!=0){
lW=opb.read(1);
nW=opb.read(1);
if(nW==-1) return(-1);
}
else{
lW=0;
nW=0;
}
mode=_mode;
W=vi.mode_param[mode].blockflag;
if(W!=0)
{
lW=opb.read(1);
nW=opb.read(1);
if(nW==-1) return(-1);
}
else
{
lW=0;
nW=0;
}
// more setup
granulepos=op.granulepos;
sequence=op.packetno-3; // first block is third packet
eofflag=op.e_o_s;
// more setup
granulepos=op.granulepos;
sequence=op.packetno-3; // first block is third packet
eofflag=op.e_o_s;
// alloc pcm passback storage
pcmend=vi.blocksizes[W];
//pcm=alloc(vi.channels);
if(pcm.length<vi.channels){
pcm=new float[vi.channels][];
}
for(int i=0;i<vi.channels;i++){
if(pcm[i]==null || pcm[i].length<pcmend){
pcm[i]=new float[pcmend];
//pcm[i]=alloc(pcmend);
}
else{
for(int j=0;j<pcmend;j++){ pcm[i][j]=0; }
}
}
// alloc pcm passback storage
pcmend=vi.blocksizes[W];
//pcm=alloc(vi.channels);
if(pcm.Length<vi.channels)
{
pcm=new float[vi.channels][];
}
for(int i=0;i<vi.channels;i++)
{
if(pcm[i]==null || pcm[i].Length<pcmend)
{
pcm[i]=new float[pcmend];
//pcm[i]=alloc(pcmend);
}
else
{
for(int j=0;j<pcmend;j++){ pcm[i][j]=0; }
}
}
// unpack_header enforces range checking
int type=vi.map_type[vi.mode_param[mode].mapping];
return(FuncMapping.mapping_P[type].inverse(this, vd.mode[mode]));
}
// unpack_header enforces range checking
int type=vi.map_type[vi.mode_param[mode].mapping];
return(FuncMapping.mapping_P[type].inverse(this, vd.mode[mode]));
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -24,262 +24,284 @@
*/
using System;
using System.Text;
using csogg;
// the comments are not part of vorbis_info so that vorbis_info can be
// static storage
public class Comment
namespace csvorbis
{
private static byte[] _vorbis="vorbis".getBytes();
private static int OV_EFAULT=-129;
private static int OV_EIMPL=-130;
// unlimited user comment fields. libvorbis writes 'libvorbis'
// whatever vendor is set to in encode
public byte[][] user_comments;
public int[] comment_lengths;
public int comments;
public byte[] vendor;
public void init()
// the comments are not part of vorbis_info so that vorbis_info can be
// static storage
public class Comment
{
user_comments=null;
comments=0;
vendor=null;
}
private static String _vorbis="vorbis";
public void add(String comment)
{
add(comment.getBytes());
}
//private static int OV_EFAULT=-129;
private static int OV_EIMPL=-130;
private void add(byte[] comment)
{
byte[][] foo=new byte[comments+2][];
if(user_comments!=null)
// unlimited user comment fields. libvorbis writes 'libvorbis'
// whatever vendor is set to in encode
public byte[][] user_comments;
public int[] comment_lengths;
public int comments;
public byte[] vendor;
public void init()
{
System.arraycopy(user_comments, 0, foo, 0, comments);
user_comments=null;
comments=0;
vendor=null;
}
user_comments=foo;
int[] goo=new int[comments+2];
if(comment_lengths!=null)
public void add(String comment)
{
System.arraycopy(comment_lengths, 0, goo, 0, comments);
ASCIIEncoding AE = new ASCIIEncoding();
byte[] comment_byt = AE.GetBytes(comment);
add(comment_byt);
}
comment_lengths=goo;
byte[] bar=new byte[comment.length+1];
System.arraycopy(comment, 0, bar, 0, comment.length);
user_comments[comments]=bar;
comment_lengths[comments]=comment.length;
comments++;
user_comments[comments]=null;
}
private void add(byte[] comment)
{
byte[][] foo=new byte[comments+2][];
if(user_comments!=null)
{
Array.Copy(user_comments, 0, foo, 0, comments);
}
user_comments=foo;
public void add_tag(String tag, String contents)
{
if(contents==null) contents="";
add(tag+"="+contents);
}
int[] goo=new int[comments+2];
if(comment_lengths!=null)
{
Array.Copy(comment_lengths, 0, goo, 0, comments);
}
comment_lengths=goo;
/*
private void add_tag(byte[] tag, byte[] contents){
byte[] foo=new byte[tag.length+contents.length+1];
int j=0;
for(int i=0; i<tag.length; i++){foo[j++]=tag[i];}
foo[j++]=(byte)'='; j++;
for(int i=0; i<contents.length; i++){foo[j++]=tag[i];}
add(foo);
}
*/
byte[] bar=new byte[comment.Length+1];
Array.Copy(comment, 0, bar, 0, comment.Length);
user_comments[comments]=bar;
comment_lengths[comments]=comment.Length;
comments++;
user_comments[comments]=null;
}
public void add_tag(String tag, String contents)
{
if(contents==null) contents="";
add(tag+"="+contents);
}
/*
private void add_tag(byte[] tag, byte[] contents){
byte[] foo=new byte[tag.length+contents.length+1];
int j=0;
for(int i=0; i<tag.length; i++){foo[j++]=tag[i];}
foo[j++]=(byte)'='; j++;
for(int i=0; i<contents.length; i++){foo[j++]=tag[i];}
add(foo);
}
*/
// This is more or less the same as strncasecmp - but that doesn't exist
// * everywhere, and this is a fairly trivial function, so we include it
static int tagcompare(byte[] s1, byte[] s2, int n)
{
int c=0;
byte u1, u2;
while(c < n)
// This is more or less the same as strncasecmp - but that doesn't exist
// * everywhere, and this is a fairly trivial function, so we include it
static bool tagcompare(byte[] s1, byte[] s2, int n)
{
u1=s1[c]; u2=s2[c];
if(u1>='A')u1=(byte)(u1-'A'+'a');
if(u2>='A')u2=(byte)(u2-'A'+'a');
if(u1!=u2){ return false; }
c++;
}
return true;
}
public String query(String tag)
{
return query(tag, 0);
}
public String query(String tag, int count)
{
int foo=query(tag.getBytes(), count);
if(foo==-1)return null;
byte[] comment=user_comments[foo];
for(int i=0; i<comment_lengths[foo]; i++)
{
if(comment[i]=='=')
int c=0;
byte u1, u2;
while(c < n)
{
return new String(comment, i+1, comment_lengths[foo]-(i+1));
u1=s1[c]; u2=s2[c];
if(u1>='A')u1=(byte)(u1-'A'+'a');
if(u2>='A')u2=(byte)(u2-'A'+'a');
if(u1!=u2){ return false; }
c++;
}
return true;
}
return null;
}
private int query(byte[] tag, int count)
{
int i=0;
int found = 0;
int taglen = tag.length;
byte[] fulltag = new byte[taglen+2];
System.arraycopy(tag, 0, fulltag, 0, tag.length);
fulltag[tag.length]=(byte)'=';
for(i=0;i<comments;i++)
public String query(String tag)
{
if(tagcompare(user_comments[i], fulltag, taglen))
return query(tag, 0);
}
public String query(String tag, int count)
{
ASCIIEncoding AE = new ASCIIEncoding();
byte[] tag_byt = AE.GetBytes(tag);
int foo=query(tag_byt, count);
if(foo==-1)return null;
byte[] comment=user_comments[foo];
for(int i=0; i<comment_lengths[foo]; i++)
{
if(count==found)
if(comment[i]=='=')
{
// We return a pointer to the data, not a copy
//return user_comments[i] + taglen + 1;
return i;
//TODO
//return new String(comment, i+1, comment_lengths[foo]-(i+1));
return "Meme";
}
else{ found++; }
}
return null;
}
return -1;
}
int unpack(Buffer opb)
{
int vendorlen=opb.read(32);
if(vendorlen<0)
private int query(byte[] tag, int count)
{
//goto err_out;
clear();
return(-1);
int i=0;
int found = 0;
int taglen = tag.Length;
byte[] fulltag = new byte[taglen+2];
Array.Copy(tag, 0, fulltag, 0, tag.Length);
fulltag[tag.Length]=(byte)'=';
for(i=0;i<comments;i++)
{
if(tagcompare(user_comments[i], fulltag, taglen))
{
if(count==found)
{
// We return a pointer to the data, not a copy
//return user_comments[i] + taglen + 1;
return i;
}
else{ found++; }
}
}
return -1;
}
vendor=new byte[vendorlen+1];
opb.read(vendor,vendorlen);
comments=opb.read(32);
if(comments<0)
internal int unpack(csBuffer opb)
{
//goto err_out;
clear();
return(-1);
}
user_comments=new byte[comments+1][];
comment_lengths=new int[comments+1];
for(int i=0;i<comments;i++)
{
int len=opb.read(32);
if(len<0)
int vendorlen=opb.read(32);
if(vendorlen<0)
{
//goto err_out;
clear();
return(-1);
}
comment_lengths[i]=len;
user_comments[i]=new byte[len+1];
opb.read(user_comments[i], len);
}
if(opb.read(1)!=1)
{
//goto err_out; // EOP check
clear();
return(-1);
}
return(0);
// err_out:
// comment_clear(vc);
// return(-1);
}
int pack(Buffer opb)
{
byte[] temp="Xiphophorus libVorbis I 20000508".getBytes();
// preamble
opb.write(0x03,8);
opb.write(_vorbis);
// vendor
opb.write(temp.length,32);
opb.write(temp);
// comments
opb.write(comments,32);
if(comments!=0)
{
vendor=new byte[vendorlen+1];
opb.read(vendor,vendorlen);
comments=opb.read(32);
if(comments<0)
{
//goto err_out;
clear();
return(-1);
}
user_comments=new byte[comments+1][];
comment_lengths=new int[comments+1];
for(int i=0;i<comments;i++)
{
if(user_comments[i]!=null)
int len=opb.read(32);
if(len<0)
{
opb.write(comment_lengths[i],32);
opb.write(user_comments[i]);
//goto err_out;
clear();
return(-1);
}
else
comment_lengths[i]=len;
user_comments[i]=new byte[len+1];
opb.read(user_comments[i], len);
}
if(opb.read(1)!=1)
{
//goto err_out; // EOP check
clear();
return(-1);
}
return(0);
// err_out:
// comment_clear(vc);
// return(-1);
}
int pack(csBuffer opb)
{
String temp="Xiphophorus libVorbis I 20000508";
ASCIIEncoding AE = new ASCIIEncoding();
byte[] temp_byt = AE.GetBytes(temp);
byte[] _vorbis_byt = AE.GetBytes(_vorbis);
// preamble
opb.write(0x03,8);
opb.write(_vorbis_byt);
// vendor
opb.write(temp.Length,32);
opb.write(temp_byt);
// comments
opb.write(comments,32);
if(comments!=0)
{
for(int i=0;i<comments;i++)
{
opb.write(0,32);
if(user_comments[i]!=null)
{
opb.write(comment_lengths[i],32);
opb.write(user_comments[i]);
}
else
{
opb.write(0,32);
}
}
}
opb.write(1,1);
return(0);
}
opb.write(1,1);
return(0);
}
public int header_out(Packet op)
{
Buffer opb=new Buffer();
opb.writeinit();
if(pack(opb)!=0) return OV_EIMPL;
op.packet_base = new byte[opb.bytes()];
op.packet=0;
op.bytes=opb.bytes();
System.arraycopy(opb.buffer(), 0, op.packet_base, 0, op.bytes);
op.b_o_s=0;
op.e_o_s=0;
op.granulepos=0;
return 0;
}
void clear()
{
for(int i=0;i<comments;i++)
user_comments[i]=null;
user_comments=null;
vendor=null;
}
public String getVendor()
{
return new String(vendor, 0, vendor.length-1);
}
public String getComment(int i)
{
if(comments<=i)return null;
return new String(user_comments[i], 0, user_comments[i].length-1);
}
public String toString()
{
String foo="Vendor: "+new String(vendor, 0, vendor.length-1);
for(int i=0; i<comments; i++)
public int header_out(Packet op)
{
foo=foo+"\nComment: "+new String(user_comments[i], 0, user_comments[i].length-1);
csBuffer opb=new csBuffer();
opb.writeinit();
if(pack(opb)!=0) return OV_EIMPL;
op.packet_base = new byte[opb.bytes()];
op.packet=0;
op.bytes=opb.bytes();
Array.Copy(opb.buf(), 0, op.packet_base, 0, op.bytes);
op.b_o_s=0;
op.e_o_s=0;
op.granulepos=0;
return 0;
}
foo=foo+"\n";
return foo;
}
void clear()
{
for(int i=0;i<comments;i++)
user_comments[i]=null;
user_comments=null;
vendor=null;
}
public String getVendor()
{
//TODO
//return new String(vendor.ToString(), 0, vendor.Length-1);
return "The Labs";
}
public String getComment(int i)
{
if(comments<=i)return null;
//TODO
//Encoding asc = Encoding.ASCII;
//return new String(user_comments[i], 0, user_comments[i].Length-1, asc);
return "There is no spoon.";
}
public String toString()
{
//TODO
//String foo="Vendor: "+new String(vendor.ToString(), 0, vendor.Length-1);
//for(int i=0; i<comments; i++)
//{
// foo=foo+"\nComment: "+new String(user_comments[i].ToString(), 0, user_comments[i].Length-1);
//}
//foo=foo+"\n";
//return foo;
return "Blah\n";
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -25,471 +25,422 @@
using System;
using csogg;
using csvorbis;
public class DspState
namespace csvorbis
{
static float M_PI=3.1415926539f;
static int VI_TRANSFORMB=1;
static int VI_WINDOWB=1;
int analysisp;
Info vi;
int modebits;
float[][] pcm;
//float[][] pcmret;
int pcm_storage;
int pcm_current;
int pcm_returned;
float[] multipliers;
int envelope_storage;
int envelope_current;
int eofflag;
int lW;
int W;
int nW;
int centerW;
long granulepos;
long sequence;
long glue_bits;
long time_bits;
long floor_bits;
long res_bits;
// local lookup storage
//!! Envelope ve=new Envelope(); // envelope
//float **window[2][2][2]; // block, leadin, leadout, type
float[][][][][] wnd; // block, leadin, leadout, type
//vorbis_look_transform **transform[2]; // block, type
Object[][] transform;
CodeBook[] fullbooks;
// backend lookups are tied to the mode, not the backend or naked mapping
Object[] mode;
// local storage, only used on the encoding side. This way the
// application does not need to worry about freeing some packets'
// memory and not others'; packet storage is always tracked.
// Cleared next call to a _dsp_ function
byte[] header;
byte[] header1;
byte[] header2;
public DspState()
public class DspState
{
transform=new Object[2][];
wnd=new float[2][][][][];
wnd[0]=new float[2][][][];
wnd[0][0]=new float[2][][];
wnd[0][1]=new float[2][][];
wnd[0][0][0]=new float[2][];
wnd[0][0][1]=new float[2][];
wnd[0][1][0]=new float[2][];
wnd[0][1][1]=new float[2][];
wnd[1]=new float[2][][][];
wnd[1][0]=new float[2][][];
wnd[1][1]=new float[2][][];
wnd[1][0][0]=new float[2][];
wnd[1][0][1]=new float[2][];
wnd[1][1][0]=new float[2][];
wnd[1][1][1]=new float[2][];
}
static float M_PI=3.1415926539f;
static int VI_TRANSFORMB=1;
static int VI_WINDOWB=1;
private static int ilog2(int v)
{
int ret=0;
while(v>1)
internal int analysisp;
internal Info vi;
internal int modebits;
float[][] pcm;
//float[][] pcmret;
int pcm_storage;
int pcm_current;
int pcm_returned;
float[] multipliers;
int envelope_storage;
int envelope_current;
int eofflag;
int lW;
int W;
int nW;
int centerW;
long granulepos;
public long sequence;
long glue_bits;
long time_bits;
long floor_bits;
long res_bits;
// local lookup storage
//!! Envelope ve=new Envelope(); // envelope
//float **window[2][2][2]; // block, leadin, leadout, type
internal float[][][][][] wnd; // block, leadin, leadout, type
//vorbis_look_transform **transform[2]; // block, type
internal Object[][] transform;
internal CodeBook[] fullbooks;
// backend lookups are tied to the mode, not the backend or naked mapping
internal Object[] mode;
// local storage, only used on the encoding side. This way the
// application does not need to worry about freeing some packets'
// memory and not others'; packet storage is always tracked.
// Cleared next call to a _dsp_ function
byte[] header;
byte[] header1;
byte[] header2;
public DspState()
{
ret++;
(uint)v >>= 1;
transform=new Object[2][];
wnd=new float[2][][][][];
wnd[0]=new float[2][][][];
wnd[0][0]=new float[2][][];
wnd[0][1]=new float[2][][];
wnd[0][0][0]=new float[2][];
wnd[0][0][1]=new float[2][];
wnd[0][1][0]=new float[2][];
wnd[0][1][1]=new float[2][];
wnd[1]=new float[2][][][];
wnd[1][0]=new float[2][][];
wnd[1][1]=new float[2][][];
wnd[1][0][0]=new float[2][];
wnd[1][0][1]=new float[2][];
wnd[1][1][0]=new float[2][];
wnd[1][1][1]=new float[2][];
}
return(ret);
}
static float[] window(int type, int wnd, int left, int right)
{
float[] ret=new float[wnd];
switch(type)
private static int ilog2(int v)
{
case 0:
// The 'vorbis window' (window 0) is sin(sin(x)*sin(x)*2pi)
int ret=0;
while(v>1)
{
int leftbegin=wnd/4-left/2;
int rightbegin=wnd-wnd/4-right/2;
ret++;
v = (int)((uint)v >> 1);
}
return(ret);
}
internal static float[] window(int type, int wnd, int left, int right)
{
float[] ret=new float[wnd];
switch(type)
{
case 0:
// The 'vorbis window' (window 0) is sin(sin(x)*sin(x)*2pi)
{
int leftbegin=wnd/4-left/2;
int rightbegin=wnd-wnd/4-right/2;
for(int i=0;i<left;i++)
{
float x=(float)((i+.5)/left*M_PI/2.0);
x=(float)Math.sin(x);
x*=x;
x*=M_PI/2.0;
x=(float)Math.sin(x);
ret[i+leftbegin]=x;
}
for(int i=0;i<left;i++)
{
float x=(float)((i+.5)/left*M_PI/2.0);
x=(float)Math.Sin(x);
x*=x;
x*=(float)(M_PI/2.0);
x=(float)Math.Sin(x);
ret[i+leftbegin]=x;
}
for(int i=leftbegin+left;i<rightbegin;i++)
{
ret[i]=1.f;
}
for(int i=leftbegin+left;i<rightbegin;i++)
{
ret[i]=1.0f;
}
for(int i=0;i<right;i++)
{
float x=(float)((right-i-.5)/right*M_PI/2.0);
x=(float)Math.sin(x);
x*=x;
x*=M_PI/2.0;
x=(float)Math.sin(x);
ret[i+rightbegin]=x;
for(int i=0;i<right;i++)
{
float x=(float)((right-i-.5)/right*M_PI/2.0);
x=(float)Math.Sin(x);
x*=x;
x*=(float)(M_PI/2.0);
x=(float)Math.Sin(x);
ret[i+rightbegin]=x;
}
}
break;
default:
//free(ret);
return(null);
}
break;
default:
//free(ret);
return(null);
}
return(ret);
}
// Analysis side code, but directly related to blocking. Thus it's
// here and not in analysis.c (which is for analysis transforms only).
// The init is here because some of it is shared
int init(Info vi, int encp)
{
//System.err.println("DspState.init: vi="+vi+", encp="+encp);
//memset(v,0,sizeof(vorbis_dsp_state));
this.vi=vi;
modebits=ilog2(vi.modes);
transform[0]=new Object[VI_TRANSFORMB];
transform[1]=new Object[VI_TRANSFORMB];
// MDCT is tranform 0
transform[0][0]=new Mdct();
transform[1][0]=new Mdct();
((Mdct)transform[0][0]).init(vi.blocksizes[0]);
((Mdct)transform[1][0]).init(vi.blocksizes[1]);
wnd[0][0][0]=new float[VI_WINDOWB][];
wnd[0][0][1]=wnd[0][0][0];
wnd[0][1][0]=wnd[0][0][0];
wnd[0][1][1]=wnd[0][0][0];
wnd[1][0][0]=new float[VI_WINDOWB][];
wnd[1][0][1]=new float[VI_WINDOWB][];
wnd[1][1][0]=new float[VI_WINDOWB][];
wnd[1][1][1]=new float[VI_WINDOWB][];
for(int i=0;i<VI_WINDOWB;i++)
{
wnd[0][0][0][i]=
wnd(i,vi.blocksizes[0],vi.blocksizes[0]/2,vi.blocksizes[0]/2);
wnd[1][0][0][i]=
wnd(i,vi.blocksizes[1],vi.blocksizes[0]/2,vi.blocksizes[0]/2);
wnd[1][0][1][i]=
wnd(i,vi.blocksizes[1],vi.blocksizes[0]/2,vi.blocksizes[1]/2);
wnd[1][1][0][i]=
wnd(i,vi.blocksizes[1],vi.blocksizes[1]/2,vi.blocksizes[0]/2);
wnd[1][1][1][i]=
wnd(i,vi.blocksizes[1],vi.blocksizes[1]/2,vi.blocksizes[1]/2);
return(ret);
}
// if(encp){ // encode/decode differ here
// // finish the codebooks
// fullbooks=new CodeBook[vi.books];
// for(int i=0;i<vi.books;i++){
// fullbooks[i]=new CodeBook();
// fullbooks[i].init_encode(vi.book_param[i]);
// }
// analysisp=1;
// }
// else{
// finish the codebooks
fullbooks=new CodeBook[vi.books];
for(int i=0;i<vi.books;i++)
// Analysis side code, but directly related to blocking. Thus it's
// here and not in analysis.c (which is for analysis transforms only).
// The init is here because some of it is shared
int init(Info vi, bool encp)
{
fullbooks[i]=new CodeBook();
fullbooks[i].init_decode(vi.book_param[i]);
}
// }
Console.Error.WriteLine("DspState.init: vi="+vi+", encp="+encp);
//memset(v,0,sizeof(vorbis_dsp_state));
this.vi=vi;
modebits=ilog2(vi.modes);
// initialize the storage vectors to a decent size greater than the
// minimum
pcm_storage=8192; // we'll assume later that we have
// a minimum of twice the blocksize of
// accumulated samples in analysis
pcm=new float[vi.channels][];
//pcmret=new float[vi.channels][];
{
for(int i=0;i<vi.channels;i++)
{
pcm[i]=new float[pcm_storage];
}
}
transform[0]=new Object[VI_TRANSFORMB];
transform[1]=new Object[VI_TRANSFORMB];
// all 1 (large block) or 0 (small block)
// explicitly set for the sake of clarity
lW=0; // previous window size
W=0; // current window size
// MDCT is tranform 0
// all vector indexes; multiples of samples_per_envelope_step
centerW=vi.blocksizes[1]/2;
transform[0][0]=new Mdct();
transform[1][0]=new Mdct();
((Mdct)transform[0][0]).init(vi.blocksizes[0]);
((Mdct)transform[1][0]).init(vi.blocksizes[1]);
pcm_current=centerW;
wnd[0][0][0]=new float[VI_WINDOWB][];
wnd[0][0][1]=wnd[0][0][0];
wnd[0][1][0]=wnd[0][0][0];
wnd[0][1][1]=wnd[0][0][0];
wnd[1][0][0]=new float[VI_WINDOWB][];
wnd[1][0][1]=new float[VI_WINDOWB][];
wnd[1][1][0]=new float[VI_WINDOWB][];
wnd[1][1][1]=new float[VI_WINDOWB][];
// initialize all the mapping/backend lookups
mode=new Object[vi.modes];
for(int i=0;i<vi.modes;i++)
{
int mapnum=vi.mode_param[i].mapping;
int maptype=vi.map_type[mapnum];
mode[i]=FuncMapping.mapping_P[maptype].look(this,vi.mode_param[i],
vi.map_param[mapnum]);
}
return(0);
}
public int synthesis_init(Info vi)
{
init(vi, false);
// Adjust centerW to allow an easier mechanism for determining output
pcm_returned=centerW;
centerW-= vi.blocksizes[W]/4+vi.blocksizes[lW]/4;
granulepos=-1;
sequence=-1;
return(0);
}
DspState(Info vi) : this()
{
init(vi, false);
// Adjust centerW to allow an easier mechanism for determining output
pcm_returned=centerW;
centerW-= vi.blocksizes[W]/4+vi.blocksizes[lW]/4;
granulepos=-1;
sequence=-1;
}
// Unike in analysis, the window is only partially applied for each
// block. The time domain envelope is not yet handled at the point of
// calling (as it relies on the previous block).
public int synthesis_blockin(Block vb)
{
// Shift out any PCM/multipliers that we returned previously
// centerW is currently the center of the last block added
if(centerW>vi.blocksizes[1]/2 && pcm_returned>8192)
{
// don't shift too much; we need to have a minimum PCM buffer of
// 1/2 long block
int shiftPCM=centerW-vi.blocksizes[1]/2;
shiftPCM=(pcm_returned<shiftPCM?pcm_returned:shiftPCM);
pcm_current-=shiftPCM;
centerW-=shiftPCM;
pcm_returned-=shiftPCM;
if(shiftPCM!=0)
for(int i=0;i<VI_WINDOWB;i++)
{
for(int i=0;i<vi.channels;i++)
{
System.arraycopy(pcm[i], shiftPCM, pcm[i], 0, pcm_current);
}
wnd[0][0][0][i]=
window(i,vi.blocksizes[0],vi.blocksizes[0]/2,vi.blocksizes[0]/2);
wnd[1][0][0][i]=
window(i,vi.blocksizes[1],vi.blocksizes[0]/2,vi.blocksizes[0]/2);
wnd[1][0][1][i]=
window(i,vi.blocksizes[1],vi.blocksizes[0]/2,vi.blocksizes[1]/2);
wnd[1][1][0][i]=
window(i,vi.blocksizes[1],vi.blocksizes[1]/2,vi.blocksizes[0]/2);
wnd[1][1][1][i]=
window(i,vi.blocksizes[1],vi.blocksizes[1]/2,vi.blocksizes[1]/2);
}
}
lW=W;
W=vb.W;
nW=-1;
// if(encp){ // encode/decode differ here
// // finish the codebooks
// fullbooks=new CodeBook[vi.books];
// for(int i=0;i<vi.books;i++){
// fullbooks[i]=new CodeBook();
// fullbooks[i].init_encode(vi.book_param[i]);
// }
// analysisp=1;
// }
// else{
// finish the codebooks
fullbooks=new CodeBook[vi.books];
for(int i=0;i<vi.books;i++)
{
fullbooks[i]=new CodeBook();
fullbooks[i].init_decode(vi.book_param[i]);
}
Console.Error.WriteLine("fullbooks done");
// }
glue_bits+=vb.glue_bits;
time_bits+=vb.time_bits;
floor_bits+=vb.floor_bits;
res_bits+=vb.res_bits;
if(sequence+1 != vb.sequence)granulepos=-1; // out of sequence; lose count
sequence=vb.sequence;
{
int sizeW=vi.blocksizes[W];
int _centerW=centerW+vi.blocksizes[lW]/4+sizeW/4;
int beginW=_centerW-sizeW/2;
int endW=beginW+sizeW;
int beginSl=0;
int endSl=0;
// Do we have enough PCM/mult storage for the block?
if(endW>pcm_storage)
// initialize the storage vectors to a decent size greater than the
// minimum
pcm_storage=8192; // we'll assume later that we have
// a minimum of twice the blocksize of
// accumulated samples in analysis
pcm=new float[vi.channels][];
//pcmret=new float[vi.channels][];
{
// expand the storage
pcm_storage=endW+vi.blocksizes[1];
for(int i=0;i<vi.channels;i++)
{
float[] foo=new float[pcm_storage];
System.arraycopy(pcm[i], 0, foo, 0, pcm[i].length);
pcm[i]=foo;
pcm[i]=new float[pcm_storage];
}
}
// overlap/add PCM
switch(W)
{
case 0:
beginSl=0;
endSl=vi.blocksizes[0]/2;
break;
case 1:
beginSl=vi.blocksizes[1]/4-vi.blocksizes[lW]/4;
endSl=beginSl+vi.blocksizes[lW]/2;
break;
}
// all 1 (large block) or 0 (small block)
// explicitly set for the sake of clarity
lW=0; // previous window size
W=0; // current window size
for(int j=0;j<vi.channels;j++)
{
int _pcm=beginW;
// the overlap/add section
int i=0;
for(i=beginSl;i<endSl;i++)
// all vector indexes; multiples of samples_per_envelope_step
centerW=vi.blocksizes[1]/2;
pcm_current=centerW;
// initialize all the mapping/backend lookups
mode=new Object[vi.modes];
Console.Error.WriteLine("vi.modes: "+vi.modes);
for(int i=0;i<vi.modes;i++)
{
pcm[j][_pcm+i]+=vb.pcm[j][i];
}
// the remaining section
for(;i<sizeW;i++)
{
pcm[j][_pcm+i]=vb.pcm[j][i];
int mapnum=vi.mode_param[i].mapping;
int maptype=vi.map_type[mapnum];
Console.Error.WriteLine("Entering mapping.");
mode[i]=FuncMapping.mapping_P[maptype].look(this,vi.mode_param[i],
vi.map_param[mapnum]);
Console.Error.WriteLine("Done Mapping");
}
return(0);
}
// track the frame number... This is for convenience, but also
// making sure our last packet doesn't end with added padding. If
// the last packet is partial, the number of samples we'll have to
// return will be past the vb->granulepos.
//
// This is not foolproof! It will be confused if we begin
// decoding at the last page after a seek or hole. In that case,
// we don't have a starting point to judge where the last frame
// is. For this reason, vorbisfile will always try to make sure
// it reads the last two marked pages in proper sequence
if(granulepos==-1)
public int synthesis_init(Info vi)
{
granulepos=vb.granulepos;
init(vi, false);
// Adjust centerW to allow an easier mechanism for determining output
pcm_returned=centerW;
centerW-= vi.blocksizes[W]/4+vi.blocksizes[lW]/4;
granulepos=-1;
sequence=-1;
return(0);
}
else
DspState(Info vi) : this()
{
granulepos+=(_centerW-centerW);
if(vb.granulepos!=-1 && granulepos!=vb.granulepos)
init(vi, false);
// Adjust centerW to allow an easier mechanism for determining output
pcm_returned=centerW;
centerW-= vi.blocksizes[W]/4+vi.blocksizes[lW]/4;
granulepos=-1;
sequence=-1;
}
// Unike in analysis, the window is only partially applied for each
// block. The time domain envelope is not yet handled at the point of
// calling (as it relies on the previous block).
public int synthesis_blockin(Block vb)
{
// Shift out any PCM/multipliers that we returned previously
// centerW is currently the center of the last block added
if(centerW>vi.blocksizes[1]/2 && pcm_returned>8192)
{
if(granulepos>vb.granulepos && vb.eofflag!=0)
// don't shift too much; we need to have a minimum PCM buffer of
// 1/2 long block
int shiftPCM=centerW-vi.blocksizes[1]/2;
shiftPCM=(pcm_returned<shiftPCM?pcm_returned:shiftPCM);
pcm_current-=shiftPCM;
centerW-=shiftPCM;
pcm_returned-=shiftPCM;
if(shiftPCM!=0)
{
// partial last frame. Strip the padding off
_centerW-=(granulepos-vb.granulepos);
}// else{ Shouldn't happen *unless* the bitstream is out of
// spec. Either way, believe the bitstream }
granulepos=vb.granulepos;
for(int i=0;i<vi.channels;i++)
{
Array.Copy(pcm[i], shiftPCM, pcm[i], 0, pcm_current);
}
}
}
}
// Update, cleanup
lW=W;
W=vb.W;
nW=-1;
centerW=_centerW;
pcm_current=endW;
if(vb.eofflag!=0)eofflag=1;
}
return(0);
}
glue_bits+=vb.glue_bits;
time_bits+=vb.time_bits;
floor_bits+=vb.floor_bits;
res_bits+=vb.res_bits;
if(sequence+1 != vb.sequence)granulepos=-1; // out of sequence; lose count
sequence=vb.sequence;
// pcm==NULL indicates we just want the pending samples, no more
public int synthesis_pcmout(float[][][] _pcm, int[] index)
{
if(pcm_returned<centerW)
{
if(_pcm!=null)
int sizeW=vi.blocksizes[W];
int _centerW=centerW+vi.blocksizes[lW]/4+sizeW/4;
int beginW=_centerW-sizeW/2;
int endW=beginW+sizeW;
int beginSl=0;
int endSl=0;
// Do we have enough PCM/mult storage for the block?
if(endW>pcm_storage)
{
// expand the storage
pcm_storage=endW+vi.blocksizes[1];
for(int i=0;i<vi.channels;i++)
{
// pcmret[i]=pcm[i]+v.pcm_returned;
//!!!!!!!!
index[i]=pcm_returned;
float[] foo=new float[pcm_storage];
Array.Copy(pcm[i], 0, foo, 0, pcm[i].Length);
pcm[i]=foo;
}
_pcm[0]=pcm;
}
return(centerW-pcm_returned);
// overlap/add PCM
switch(W)
{
case 0:
beginSl=0;
endSl=vi.blocksizes[0]/2;
break;
case 1:
beginSl=vi.blocksizes[1]/4-vi.blocksizes[lW]/4;
endSl=beginSl+vi.blocksizes[lW]/2;
break;
}
for(int j=0;j<vi.channels;j++)
{
int _pcm=beginW;
// the overlap/add section
int i=0;
for(i=beginSl;i<endSl;i++)
{
pcm[j][_pcm+i]+=vb.pcm[j][i];
}
// the remaining section
for(;i<sizeW;i++)
{
pcm[j][_pcm+i]=vb.pcm[j][i];
}
}
// track the frame number... This is for convenience, but also
// making sure our last packet doesn't end with added padding. If
// the last packet is partial, the number of samples we'll have to
// return will be past the vb->granulepos.
//
// This is not foolproof! It will be confused if we begin
// decoding at the last page after a seek or hole. In that case,
// we don't have a starting point to judge where the last frame
// is. For this reason, vorbisfile will always try to make sure
// it reads the last two marked pages in proper sequence
if(granulepos==-1)
{
granulepos=vb.granulepos;
}
else
{
granulepos+=(_centerW-centerW);
if(vb.granulepos!=-1 && granulepos!=vb.granulepos)
{
if(granulepos>vb.granulepos && vb.eofflag!=0)
{
// partial last frame. Strip the padding off
_centerW = _centerW - (int)(granulepos-vb.granulepos);
}// else{ Shouldn't happen *unless* the bitstream is out of
// spec. Either way, believe the bitstream }
granulepos=vb.granulepos;
}
}
// Update, cleanup
centerW=_centerW;
pcm_current=endW;
if(vb.eofflag!=0)eofflag=1;
}
return(0);
}
// pcm==NULL indicates we just want the pending samples, no more
public int synthesis_pcmout(float[][][] _pcm, int[] index)
{
if(pcm_returned<centerW)
{
if(_pcm!=null)
{
for(int i=0;i<vi.channels;i++)
{
// pcmret[i]=pcm[i]+v.pcm_returned;
//!!!!!!!!
index[i]=pcm_returned;
}
_pcm[0]=pcm;
}
return(centerW-pcm_returned);
}
return(0);
}
public int synthesis_read(int bytes)
{
if(bytes!=0 && pcm_returned+bytes>centerW)return(-1);
pcm_returned+=bytes;
return(0);
}
public void clear()
{
}
return(0);
}
public int synthesis_read(int bytes)
{
if(bytes!=0 && pcm_returned+bytes>centerW)return(-1);
pcm_returned+=bytes;
return(0);
}
public void clear()
{
/*
if(window[0][0][0]!=0){
for(i=0;i<VI_WINDOWB;i++)
if(v->window[0][0][0][i])free(v->window[0][0][0][i]);
free(v->window[0][0][0]);
for(j=0;j<2;j++)
for(k=0;k<2;k++){
for(i=0;i<VI_WINDOWB;i++)
if(v->window[1][j][k][i])free(v->window[1][j][k][i]);
free(v->window[1][j][k]);
}
}
if(v->pcm){
for(i=0;i<vi->channels;i++)
if(v->pcm[i])free(v->pcm[i]);
free(v->pcm);
if(v->pcmret)free(v->pcmret);
}
if(v->multipliers)free(v->multipliers);
_ve_envelope_clear(&v->ve);
if(v->transform[0]){
mdct_clear(v->transform[0][0]);
free(v->transform[0][0]);
free(v->transform[0]);
}
if(v->transform[1]){
mdct_clear(v->transform[1][0]);
free(v->transform[1][0]);
free(v->transform[1]);
}
// free mode lookups; these are actually vorbis_look_mapping structs
if(vi){
for(i=0;i<vi->modes;i++){
int mapnum=vi->mode_param[i]->mapping;
int maptype=vi->map_type[mapnum];
_mapping_P[maptype]->free_look(v->mode[i]);
}
// free codebooks
for(i=0;i<vi->books;i++)
vorbis_book_clear(v->fullbooks+i);
}
if(v->mode)free(v->mode);
if(v->fullbooks)free(v->fullbooks);
// free header, header1, header2
if(v->header)free(v->header);
if(v->header1)free(v->header1);
if(v->header2)free(v->header2);
memset(v,0,sizeof(vorbis_dsp_state));
}
*/
}
}
}

Просмотреть файл

@ -25,12 +25,16 @@
using System;
class EncodeAuxNearestMatch{
int[] ptr0;
int[] ptr1;
namespace csvorbis
{
class EncodeAuxNearestMatch
{
internal int[] ptr0;
internal int[] ptr1;
int[] p; // decision points (each is an entry)
int[] q; // decision points (each is an entry)
int aux; // number of tree entries
int alloc;
internal int[] p; // decision points (each is an entry)
internal int[] q; // decision points (each is an entry)
internal int aux; // number of tree entries
internal int alloc;
}
}

Просмотреть файл

@ -25,9 +25,13 @@
using System;
class EncodeAuxThreshMatch{
float[] quantthresh;
int[] quantmap;
int quantvals;
int threshvals;
}
namespace csvorbis
{
class EncodeAuxThreshMatch
{
internal float[] quantthresh;
internal int[] quantmap;
internal int quantvals;
internal int threshvals;
}
}

Просмотреть файл

@ -26,370 +26,374 @@
using System;
using csogg;
class Floor0 : FuncFloor
namespace csvorbis
{
void pack(Object i, Buffer opb)
class Floor0 : FuncFloor
{
InfoFloor0 info=(InfoFloor0)i;
opb.write(info.order,8);
opb.write(info.rate,16);
opb.write(info.barkmap,16);
opb.write(info.ampbits,6);
opb.write(info.ampdB,8);
opb.write(info.numbooks-1,4);
for(int j=0;j<info.numbooks;j++)
opb.write(info.books[j],8);
}
Object unpack(Info vi , Buffer opb)
{
InfoFloor0 info=new InfoFloor0();
info.order=opb.read(8);
info.rate=opb.read(16);
info.barkmap=opb.read(16);
info.ampbits=opb.read(6);
info.ampdB=opb.read(8);
info.numbooks=opb.read(4)+1;
if((info.order<1)||
(info.rate<1)||
(info.barkmap<1)||
(info.numbooks<1))
override public void pack(Object i, csBuffer opb)
{
//free_info(info);
return(null);
InfoFloor0 info=(InfoFloor0)i;
opb.write(info.order,8);
opb.write(info.rate,16);
opb.write(info.barkmap,16);
opb.write(info.ampbits,6);
opb.write(info.ampdB,8);
opb.write(info.numbooks-1,4);
for(int j=0;j<info.numbooks;j++)
opb.write(info.books[j],8);
}
for(int j=0;j<info.numbooks;j++)
override public Object unpack(Info vi , csBuffer opb)
{
info.books[j]=opb.read(8);
if(info.books[j]<0 || info.books[j]>=vi.books)
InfoFloor0 info=new InfoFloor0();
info.order=opb.read(8);
info.rate=opb.read(16);
info.barkmap=opb.read(16);
info.ampbits=opb.read(6);
info.ampdB=opb.read(8);
info.numbooks=opb.read(4)+1;
if((info.order<1)||
(info.rate<1)||
(info.barkmap<1)||
(info.numbooks<1))
{
//free_info(info);
return(null);
}
}
return(info);
// err_out:
// free_info(info);
// return(NULL);
}
Object look(DspState vd, InfoMode mi, Object i)
{
float scale;
Info vi=vd.vi;
InfoFloor0 info=(InfoFloor0)i;
LookFloor0 look=new LookFloor0();
look.m=info.order;
look.n=vi.blocksizes[mi.blockflag]/2;
look.ln=info.barkmap;
look.vi=info;
look.lpclook.init(look.ln,look.m);
// we choose a scaling constant so that:
// floor(bark(rate/2-1)*C)=mapped-1
// floor(bark(rate/2)*C)=mapped
scale=look.ln/toBARK((float)(info.rate/2.0));
// the mapping from a linear scale to a smaller bark scale is
// straightforward. We do *not* make sure that the linear mapping
// does not skip bark-scale bins; the decoder simply skips them and
// the encoder may do what it wishes in filling them. They're
// necessary in some mapping combinations to keep the scale spacing
// accurate
look.linearmap=new int[look.n];
for(int j=0;j<look.n;j++)
{
int val=(int)Math.floor(toBARK((float)((info.rate/2.0)/look.n*j))
*scale); // bark numbers represent band edges
if(val>=look.ln)val=look.ln; // guard against the approximation
look.linearmap[j]=val;
}
return look;
}
static float toBARK(float f)
{
return (float)(13.1*Math.atan(.00074*(f))+2.24*Math.atan((f)*(f)*1.85e-8)+1e-4*(f));
}
Object state(Object i)
{
EchstateFloor0 state=new EchstateFloor0();
InfoFloor0 info=(InfoFloor0)i;
// a safe size if usually too big (dim==1)
state.codewords=new int[info.order];
state.curve=new float[info.barkmap];
state.frameno=-1;
return(state);
}
override public void free_info(Object i){}
override public void free_look(Object i){}
override public void free_state(Object vs){}
override public int forward(Block vb, Object i, float[] fin, float[] fout, Object vs){return 0;}
float[] lsp=null;
int inverse(Block vb, Object i, float[] fout)
{
//System.err.println("Floor0.inverse "+i.getClass()+"]");
LookFloor0 look=(LookFloor0)i;
InfoFloor0 info=look.vi;
int ampraw=vb.opb.read(info.ampbits);
if(ampraw>0)
{ // also handles the -1 out of data case
int maxval=(1<<info.ampbits)-1;
float amp=(float)ampraw/maxval*info.ampdB;
int booknum=vb.opb.read(ilog(info.numbooks));
if(booknum!=-1 && booknum<info.numbooks)
for(int j=0;j<info.numbooks;j++)
{
info.books[j]=opb.read(8);
if(info.books[j]<0 || info.books[j]>=vi.books)
{
//free_info(info);
return(null);
}
}
return(info);
// err_out:
// free_info(info);
// return(NULL);
}
override public Object look(DspState vd, InfoMode mi, Object i)
{
Console.Error.WriteLine("Floor0::look");
float scale;
Info vi=vd.vi;
InfoFloor0 info=(InfoFloor0)i;
LookFloor0 look=new LookFloor0();
look.m=info.order;
look.n=vi.blocksizes[mi.blockflag]/2;
look.ln=info.barkmap;
look.vi=info;
look.lpclook.init(look.ln,look.m);
lock(this)
{
if(lsp==null||lsp.length<look.m)
// we choose a scaling constant so that:
// floor(bark(rate/2-1)*C)=mapped-1
// floor(bark(rate/2)*C)=mapped
scale=look.ln/toBARK((float)(info.rate/2.0));
// the mapping from a linear scale to a smaller bark scale is
// straightforward. We do *not* make sure that the linear mapping
// does not skip bark-scale bins; the decoder simply skips them and
// the encoder may do what it wishes in filling them. They're
// necessary in some mapping combinations to keep the scale spacing
// accurate
look.linearmap=new int[look.n];
for(int j=0;j<look.n;j++)
{
int val=(int)Math.Floor(toBARK((float)((info.rate/2.0)/look.n*j))
*scale); // bark numbers represent band edges
if(val>=look.ln)val=look.ln; // guard against the approximation
look.linearmap[j]=val;
}
return look;
}
static float toBARK(float f)
{
return (float)(13.1*Math.Atan(.00074*(f))+2.24*Math.Atan((f)*(f)*1.85e-8)+1e-4*(f));
}
Object state(Object i)
{
EchstateFloor0 state=new EchstateFloor0();
InfoFloor0 info=(InfoFloor0)i;
// a safe size if usually too big (dim==1)
state.codewords=new int[info.order];
state.curve=new float[info.barkmap];
state.frameno=-1;
return(state);
}
override public void free_info(Object i){}
override public void free_look(Object i){}
override public void free_state(Object vs){}
override public int forward(Block vb, Object i, float[] fin, float[] fout, Object vs){return 0;}
float[] lsp=null;
int inverse(Block vb, Object i, float[] fout)
{
//System.err.println("Floor0.inverse "+i.getClass()+"]");
LookFloor0 look=(LookFloor0)i;
InfoFloor0 info=look.vi;
int ampraw=vb.opb.read(info.ampbits);
if(ampraw>0)
{ // also handles the -1 out of data case
int maxval=(1<<info.ampbits)-1;
float amp=(float)ampraw/maxval*info.ampdB;
int booknum=vb.opb.read(ilog(info.numbooks));
if(booknum!=-1 && booknum<info.numbooks)
{
lock(this)
{
if(lsp==null||lsp.Length<look.m)
{
lsp=new float[look.m];
}
else
{
for(int j=0; j<look.m; j++)lsp[j]=0.0f;
}
CodeBook b=vb.vd.fullbooks[info.books[booknum]];
float last=0.0f;
//memset(out,0,sizeof(float)*look->m);
for(int j=0; j<look.m; j++)fout[j]=0.0f;
for(int j=0;j<look.m;j+=b.dim)
{
if(b.decodevs(lsp, j, vb.opb, 1, -1)==-1)
{
//goto eop;
// memset(out,0,sizeof(float)*look->n);
for(int k=0; k<look.n; k++)fout[k]=0.0f;
return(0);
}
}
for(int j=0;j<look.m;)
{
for(int k=0;k<b.dim;k++,j++)lsp[j]+=last;
last=lsp[j-1];
}
// take the coefficients back to a spectral envelope curve
/*
lsp_to_lpc(out,out,look.m);
lpc_to_curve(out,out,amp,look,"",0);
for(int j=0;j<look.n;j++){
out[j]=fromdB(out[j]-info.ampdB);
}
*/
Lsp.lsp_to_curve(fout,look.linearmap,look.n,look.ln,
lsp,look.m,amp,info.ampdB);
return(1);
}
}
}
// eop:
// memset(out,0,sizeof(float)*look->n);
return(0);
}
override public Object inverse1(Block vb, Object i, Object memo)
{
//System.err.println("Floor0.inverse "+i.getClass()+"]");
LookFloor0 look=(LookFloor0)i;
InfoFloor0 info=look.vi;
float[] lsp=null;
if(memo is float[])
{
lsp=(float[])memo;
}
int ampraw=vb.opb.read(info.ampbits);
if(ampraw>0)
{ // also handles the -1 out of data case
int maxval=(1<<info.ampbits)-1;
float amp=(float)ampraw/maxval*info.ampdB;
int booknum=vb.opb.read(ilog(info.numbooks));
if(booknum!=-1 && booknum<info.numbooks)
{
CodeBook b=vb.vd.fullbooks[info.books[booknum]];
float last=0.0f;
if(lsp==null||lsp.Length<look.m+1)
{
lsp=new float[look.m];
lsp=new float[look.m+1];
}
else
{
for(int j=0; j<look.m; j++)lsp[j]=0.f;
for(int j=0; j<lsp.Length; j++)lsp[j]=0.0f;
}
CodeBook b=vb.vd.fullbooks[info.books[booknum]];
float last=0.f;
//memset(out,0,sizeof(float)*look->m);
for(int j=0; j<look.m; j++)fout[j]=0.0f;
for(int j=0;j<look.m;j+=b.dim)
{
if(b.decodevs(lsp, j, vb.opb, 1, -1)==-1)
if(b.decodev_set(lsp, j, vb.opb, b.dim)==-1)
{
//goto eop;
// memset(out,0,sizeof(float)*look->n);
for(int k=0; k<look.n; k++)fout[k]=0.0f;
return(0);
return(null);
}
}
for(int j=0;j<look.m;)
{
for(int k=0;k<b.dim;k++,j++)lsp[j]+=last;
last=lsp[j-1];
}
// take the coefficients back to a spectral envelope curve
/*
lsp_to_lpc(out,out,look.m);
lpc_to_curve(out,out,amp,look,"",0);
for(int j=0;j<look.n;j++){
out[j]=fromdB(out[j]-info.ampdB);
}
*/
Lsp.lsp_to_curve(fout,look.linearmap,look.n,look.ln,
lsp,look.m,amp,info.ampdB);
return(1);
lsp[look.m]=amp;
return(lsp);
}
}
// eop:
return(null);
}
// eop:
// memset(out,0,sizeof(float)*look->n);
return(0);
}
Object inverse1(Block vb, Object i, Object memo)
{
//System.err.println("Floor0.inverse "+i.getClass()+"]");
LookFloor0 look=(LookFloor0)i;
InfoFloor0 info=look.vi;
float[] lsp=null;
if(memo is float[])
override public int inverse2(Block vb, Object i, Object memo, float[] fout)
{
lsp=(float[])memo;
}
//System.err.println("Floor0.inverse "+i.getClass()+"]");
LookFloor0 look=(LookFloor0)i;
InfoFloor0 info=look.vi;
int ampraw=vb.opb.read(info.ampbits);
if(ampraw>0)
{ // also handles the -1 out of data case
int maxval=(1<<info.ampbits)-1;
float amp=(float)ampraw/maxval*info.ampdB;
int booknum=vb.opb.read(ilog(info.numbooks));
if(booknum!=-1 && booknum<info.numbooks)
if(memo!=null)
{
CodeBook b=vb.vd.fullbooks[info.books[booknum]];
float last=0.f;
float[] lsp=(float[])memo;
float amp=lsp[look.m];
if(lsp==null||lsp.length<look.m+1)
{
lsp=new float[look.m+1];
}
else
{
for(int j=0; j<lsp.length; j++)lsp[j]=0.f;
}
for(int j=0;j<look.m;j+=b.dim)
{
if(b.decodev_set(lsp, j, vb.opb, b.dim)==-1)
{
//goto eop;
return(null);
}
}
for(int j=0;j<look.m;)
{
for(int k=0;k<b.dim;k++,j++)lsp[j]+=last;
last=lsp[j-1];
}
lsp[look.m]=amp;
return(lsp);
Lsp.lsp_to_curve(fout,look.linearmap,look.n,look.ln,
lsp,look.m,amp,info.ampdB);
return(1);
}
}
// eop:
return(null);
}
int inverse2(Block vb, Object i, Object memo, float[] fout)
{
//System.err.println("Floor0.inverse "+i.getClass()+"]");
LookFloor0 look=(LookFloor0)i;
InfoFloor0 info=look.vi;
if(memo!=null)
{
float[] lsp=(float[])memo;
float amp=lsp[look.m];
Lsp.lsp_to_curve(fout,look.linearmap,look.n,look.ln,
lsp,look.m,amp,info.ampdB);
return(1);
}
// eop:
// memset(out,0,sizeof(float)*look->n);
for(int j=0; j<look.n; j++)
{
fout[j]=0.f;
}
return(0);
}
static float fromdB(float x)
{
return (float)(Math.exp((x)*.11512925));
}
private static int ilog(int v)
{
int ret=0;
while(v!=0)
{
ret++;
(uint)v>>=1;
}
return(ret);
}
static void lsp_to_lpc(float[] lsp, float[] lpc, int m)
{
int i,j,m2=m/2;
float[] O=new float[m2];
float[] E=new float[m2];
float A;
float[] Ae=new float[m2+1];
float[] Ao=new float[m2+1];
float B;
float[] Be=new float[m2];
float[] Bo=new float[m2];
float temp;
// even/odd roots setup
for(i=0;i<m2;i++)
{
O[i]=(float)(-2.0*Math.cos(lsp[i*2]));
E[i]=(float)(-2.0*Math.cos(lsp[i*2+1]));
// eop:
// memset(out,0,sizeof(float)*look->n);
for(int j=0; j<look.n; j++)
{
fout[j]=0.0f;
}
return(0);
}
// set up impulse response
for(j=0;j<m2;j++)
static float fromdB(float x)
{
Ae[j]=0.f;
Ao[j]=1.f;
Be[j]=0.f;
Bo[j]=1.f;
return (float)(Math.Exp((x)*.11512925));
}
Ao[j]=1.f;
Ae[j]=1.f;
// run impulse response
for(i=1;i<m+1;i++)
private static int ilog(int v)
{
A=B=0.f;
int ret=0;
while(v!=0)
{
ret++;
v = (int)((uint)v >> 1);
}
return(ret);
}
static void lsp_to_lpc(float[] lsp, float[] lpc, int m)
{
int i,j,m2=m/2;
float[] O=new float[m2];
float[] E=new float[m2];
float A;
float[] Ae=new float[m2+1];
float[] Ao=new float[m2+1];
float B;
float[] Be=new float[m2];
float[] Bo=new float[m2];
float temp;
// even/odd roots setup
for(i=0;i<m2;i++)
{
O[i]=(float)(-2.0*Math.Cos(lsp[i*2]));
E[i]=(float)(-2.0*Math.Cos(lsp[i*2+1]));
}
// set up impulse response
for(j=0;j<m2;j++)
{
temp=O[j]*Ao[j]+Ae[j];
Ae[j]=Ao[j];
Ao[j]=A;
A+=temp;
temp=E[j]*Bo[j]+Be[j];
Be[j]=Bo[j];
Bo[j]=B;
B+=temp;
Ae[j]=0.0f;
Ao[j]=1.0f;
Be[j]=0.0f;
Bo[j]=1.0f;
}
Ao[j]=1.0f;
Ae[j]=1.0f;
// run impulse response
for(i=1;i<m+1;i++)
{
A=B=0.0f;
for(j=0;j<m2;j++)
{
temp=O[j]*Ao[j]+Ae[j];
Ae[j]=Ao[j];
Ao[j]=A;
A+=temp;
temp=E[j]*Bo[j]+Be[j];
Be[j]=Bo[j];
Bo[j]=B;
B+=temp;
}
lpc[i-1]=(A+Ao[j]+B-Ae[j])/2;
Ao[j]=A;
Ae[j]=B;
}
lpc[i-1]=(A+Ao[j]+B-Ae[j])/2;
Ao[j]=A;
Ae[j]=B;
}
}
static void lpc_to_curve(float[] curve, float[] lpc,float amp,
LookFloor0 l, String name, int frameno)
{
// l->m+1 must be less than l->ln, but guard in case we get a bad stream
float[] lcurve=new float[Math.max(l.ln*2,l.m*2+2)];
if(amp==0)
static void lpc_to_curve(float[] curve, float[] lpc,float amp,
LookFloor0 l, String name, int frameno)
{
//memset(curve,0,sizeof(float)*l->n);
for(int j=0; j<l.n; j++)curve[j]=0.0f;
return;
// l->m+1 must be less than l->ln, but guard in case we get a bad stream
float[] lcurve=new float[Math.Max(l.ln*2,l.m*2+2)];
if(amp==0)
{
//memset(curve,0,sizeof(float)*l->n);
for(int j=0; j<l.n; j++)curve[j]=0.0f;
return;
}
l.lpclook.lpc_to_curve(lcurve,lpc,amp);
for(int i=0;i<l.n;i++)curve[i]=lcurve[l.linearmap[i]];
}
l.lpclook.lpc_to_curve(lcurve,lpc,amp);
for(int i=0;i<l.n;i++)curve[i]=lcurve[l.linearmap[i]];
}
}
class InfoFloor0
{
int order;
int rate;
int barkmap;
class InfoFloor0
{
internal int order;
internal int rate;
internal int barkmap;
int ampbits;
int ampdB;
internal int ampbits;
internal int ampdB;
int numbooks; // <= 16
int[] books=new int[16];
}
internal int numbooks; // <= 16
internal int[] books=new int[16];
}
class LookFloor0
{
int n;
int ln;
int m;
int[] linearmap;
class LookFloor0
{
internal int n;
internal int ln;
internal int m;
internal int[] linearmap;
InfoFloor0 vi;
Lpc lpclook=new Lpc();
}
internal InfoFloor0 vi;
internal Lpc lpclook=new Lpc();
}
class EchstateFloor0
{
int[] codewords;
float[] curve;
long frameno;
long codes;
}
class EchstateFloor0
{
internal int[] codewords;
internal float[] curve;
internal long frameno;
//internal long codes;
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -26,17 +26,20 @@
using System;
using csogg;
abstract class FuncFloor
namespace csvorbis
{
public static FuncFloor[] floor_P={new Floor0(),new Floor1()};
abstract class FuncFloor
{
public static FuncFloor[] floor_P={new Floor0(),new Floor1()};
public abstract void pack(Object i, Buffer opb);
public abstract Object unpack(Info vi, Buffer opb);
public abstract Object look(DspState vd, InfoMode mi, Object i);
public abstract void free_info(Object i);
public abstract void free_look(Object i);
public abstract void free_state(Object vs);
public abstract int forward(Block vb, Object i, float[] fin, float[] fout, Object vs);
public abstract Object inverse1(Block vb, Object i, Object memo);
public abstract int inverse2(Block vb, Object i, Object memo, float[] fout);
public abstract void pack(Object i, csBuffer opb);
public abstract Object unpack(Info vi, csBuffer opb);
public abstract Object look(DspState vd, InfoMode mi, Object i);
public abstract void free_info(Object i);
public abstract void free_look(Object i);
public abstract void free_state(Object vs);
public abstract int forward(Block vb, Object i, float[] fin, float[] fout, Object vs);
public abstract Object inverse1(Block vb, Object i, Object memo);
public abstract int inverse2(Block vb, Object i, Object memo, float[] fout);
}
}

Просмотреть файл

@ -26,13 +26,17 @@
using System;
using csogg;
abstract class FuncMapping{
public static FuncMapping[] mapping_P={new Mapping0()};
namespace csvorbis
{
abstract class FuncMapping
{
public static FuncMapping[] mapping_P={new Mapping0()};
public abstract void pack(Info info , Object imap, Buffer buffer);
public abstract Object unpack(Info info , Buffer buffer);
public abstract Object look(DspState vd, InfoMode vm, Object m);
public abstract void free_info(Object imap);
public abstract void free_look(Object imap);
public abstract int inverse(Block vd, Object lm);
}
public abstract void pack(Info info , Object imap, csBuffer buffer);
public abstract Object unpack(Info info , csBuffer buffer);
public abstract Object look(DspState vd, InfoMode vm, Object m);
public abstract void free_info(Object imap);
public abstract void free_look(Object imap);
public abstract int inverse(Block vd, Object lm);
}
}

Просмотреть файл

@ -26,17 +26,21 @@
using System;
using csogg;
abstract class FuncResidue
namespace csvorbis
{
public static FuncResidue[] residue_P={new Residue0(),
new Residue1(),
new Residue2()};
abstract class FuncResidue
{
public static FuncResidue[] residue_P={new Residue0(),
new Residue1(),
new Residue2()};
public abstract void pack(Object vr, csBuffer opb);
public abstract Object unpack(Info vi, csBuffer opb);
public abstract Object look(DspState vd, InfoMode vm, Object vr);
public abstract void free_info(Object i);
public abstract void free_look(Object i);
public abstract int forward(Block vb,Object vl, float[][] fin, int ch);
public abstract void pack(Object vr, csBuffer opb);
public abstract Object unpack(Info vi, csBuffer opb);
public abstract Object look(DspState vd, InfoMode vm, Object vr);
public abstract void free_info(Object i);
public abstract void free_look(Object i);
public abstract int forward(Block vb,Object vl, float[][] fin, int ch);
public abstract int inverse(Block vb, Object vl, float[][] fin, int[] nonzero,int ch);}
public abstract int inverse(Block vb, Object vl, float[][] fin, int[] nonzero,int ch);
}
}

Просмотреть файл

@ -26,14 +26,18 @@
using System;
using csogg;
abstract class FuncTime{
public static FuncTime[] time_P={new Time0()};
namespace csvorbis
{
abstract class FuncTime
{
public static FuncTime[] time_P={new Time0()};
public abstract void pack(Object i, csBuffer opb);
public abstract Object unpack(Info vi , csBuffer opb);
public abstract Object look(DspState vd, InfoMode vm, Object i);
public abstract void free_info(Object i);
public abstract void free_look(Object i);
public abstract int forward(Block vb, Object i);
public abstract int inverse(Block vb, Object i, float[] fin, float[] fout);
}
public abstract void pack(Object i, csBuffer opb);
public abstract Object unpack(Info vi , csBuffer opb);
public abstract Object look(DspState vd, InfoMode vm, Object i);
public abstract void free_info(Object i);
public abstract void free_look(Object i);
public abstract int forward(Block vb, Object i);
public abstract int inverse(Block vb, Object i, float[] fin, float[] fout);
}
}

Просмотреть файл

@ -23,489 +23,552 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
using System;
using System.Text;
using csogg;
public class Info{
private static int OV_EBADPACKET=-136;
private static int OV_ENOTAUDIO=-135;
private static byte[] _vorbis="vorbis".getBytes();
private static int VI_TIMEB=1;
private static int VI_FLOORB=2;
private static int VI_RESB=3;
private static int VI_MAPB=1;
private static int VI_WINDOWB=1;
namespace csvorbis
{
public class Info
{
private static int OV_EBADPACKET=-136;
private static int OV_ENOTAUDIO=-135;
private static string _vorbis="vorbis";
private static int VI_TIMEB=1;
private static int VI_FLOORB=2;
private static int VI_RESB=3;
private static int VI_MAPB=1;
private static int VI_WINDOWB=1;
public int version;
public int channels;
public int rate;
public int version;
public int channels;
public int rate;
// The below bitrate declarations are *hints*.
// Combinations of the three values carry the following implications:
//
// all three set to the same value:
// implies a fixed rate bitstream
// only nominal set:
// implies a VBR stream that averages the nominal bitrate. No hard
// upper/lower limit
// upper and or lower set:
// implies a VBR bitstream that obeys the bitrate limits. nominal
// may also be set to give a nominal rate.
// none set:
// the coder does not care to speculate.
// The below bitrate declarations are *hints*.
// Combinations of the three values carry the following implications:
//
// all three set to the same value:
// implies a fixed rate bitstream
// only nominal set:
// implies a VBR stream that averages the nominal bitrate. No hard
// upper/lower limit
// upper and or lower set:
// implies a VBR bitstream that obeys the bitrate limits. nominal
// may also be set to give a nominal rate.
// none set:
// the coder does not care to speculate.
int bitrate_upper;
int bitrate_nominal;
int bitrate_lower;
internal int bitrate_upper;
internal int bitrate_nominal;
internal int bitrate_lower;
// Vorbis supports only short and long blocks, but allows the
// encoder to choose the sizes
// Vorbis supports only short and long blocks, but allows the
// encoder to choose the sizes
int[] blocksizes=new int[2];
internal int[] blocksizes=new int[2];
// modes are the primary means of supporting on-the-fly different
// blocksizes, different channel mappings (LR or mid-side),
// different residue backends, etc. Each mode consists of a
// blocksize flag and a mapping (along with the mapping setup
// modes are the primary means of supporting on-the-fly different
// blocksizes, different channel mappings (LR or mid-side),
// different residue backends, etc. Each mode consists of a
// blocksize flag and a mapping (along with the mapping setup
int modes;
int maps;
int times;
int floors;
int residues;
int books;
int psys; // encode only
internal int modes;
internal int maps;
internal int times;
internal int floors;
internal int residues;
internal int books;
internal int psys; // encode only
InfoMode[] mode_param=null;
internal InfoMode[] mode_param=null;
int[] map_type=null;
Object[] map_param=null;
internal int[] map_type=null;
internal Object[] map_param=null;
int[] time_type=null;
Object[] time_param=null;
internal int[] time_type=null;
internal Object[] time_param=null;
int[] floor_type=null;
Object[] floor_param=null;
internal int[] floor_type=null;
internal Object[] floor_param=null;
int[] residue_type=null;
Object[] residue_param=null;
internal int[] residue_type=null;
internal Object[] residue_param=null;
StaticCodeBook[] book_param=null;
internal StaticCodeBook[] book_param=null;
PsyInfo[] psy_param=new PsyInfo[64]; // encode only
internal PsyInfo[] psy_param=new PsyInfo[64]; // encode only
// for block long/sort tuning; encode only
int envelopesa;
float preecho_thresh;
float preecho_clamp;
// for block long/sort tuning; encode only
//internal int envelopesa;
//internal float preecho_thresh;
//internal float preecho_clamp;
// used by synthesis, which has a full, alloced vi
public void init(){
rate=0;
//memset(vi,0,sizeof(vorbis_info));
}
// used by synthesis, which has a full, alloced vi
public void init()
{
rate=0;
//memset(vi,0,sizeof(vorbis_info));
}
public void clear(){
for(int i=0;i<modes;i++){ mode_param[i]=null; }
mode_param=null;
public void clear()
{
for(int i=0;i<modes;i++){ mode_param[i]=null; }
mode_param=null;
for(int i=0;i<maps;i++){ // unpack does the range checking
FuncMapping.mapping_P[map_type[i]].free_info(map_param[i]);
}
map_param=null;
for(int i=0;i<maps;i++)
{ // unpack does the range checking
FuncMapping.mapping_P[map_type[i]].free_info(map_param[i]);
}
map_param=null;
for(int i=0;i<times;i++){ // unpack does the range checking
FuncTime.time_P[time_type[i]].free_info(time_param[i]);
}
time_param=null;
for(int i=0;i<times;i++)
{ // unpack does the range checking
FuncTime.time_P[time_type[i]].free_info(time_param[i]);
}
time_param=null;
for(int i=0;i<floors;i++){ // unpack does the range checking
FuncFloor.floor_P[floor_type[i]].free_info(floor_param[i]);
}
floor_param=null;
for(int i=0;i<floors;i++)
{ // unpack does the range checking
FuncFloor.floor_P[floor_type[i]].free_info(floor_param[i]);
}
floor_param=null;
for(int i=0;i<residues;i++){ // unpack does the range checking
FuncResidue.residue_P[residue_type[i]].free_info(residue_param[i]);
}
residue_param=null;
for(int i=0;i<residues;i++)
{ // unpack does the range checking
FuncResidue.residue_P[residue_type[i]].free_info(residue_param[i]);
}
residue_param=null;
// the static codebooks *are* freed if you call info_clear, because
// decode side does alloc a 'static' codebook. Calling clear on the
// full codebook does not clear the static codebook (that's our
// responsibility)
for(int i=0;i<books;i++){
// just in case the decoder pre-cleared to save space
if(book_param[i]!=null){
book_param[i].clear();
book_param[i]=null;
}
}
//if(vi->book_param)free(vi->book_param);
book_param=null;
// the static codebooks *are* freed if you call info_clear, because
// decode side does alloc a 'static' codebook. Calling clear on the
// full codebook does not clear the static codebook (that's our
// responsibility)
for(int i=0;i<books;i++)
{
// just in case the decoder pre-cleared to save space
if(book_param[i]!=null)
{
book_param[i].clear();
book_param[i]=null;
}
}
//if(vi->book_param)free(vi->book_param);
book_param=null;
for(int i=0;i<psys;i++){
psy_param[i].free();
}
//if(vi->psy_param)free(vi->psy_param);
//memset(vi,0,sizeof(vorbis_info));
}
for(int i=0;i<psys;i++)
{
psy_param[i].free();
}
//if(vi->psy_param)free(vi->psy_param);
//memset(vi,0,sizeof(vorbis_info));
}
// Header packing/unpacking
int unpack_info(csBuffer opb){
version=opb.read(32);
if(version!=0)return(-1);
// Header packing/unpacking
int unpack_info(csBuffer opb)
{
version=opb.read(32);
if(version!=0)return(-1);
channels=opb.read(8);
rate=opb.read(32);
channels=opb.read(8);
rate=opb.read(32);
bitrate_upper=opb.read(32);
bitrate_nominal=opb.read(32);
bitrate_lower=opb.read(32);
bitrate_upper=opb.read(32);
bitrate_nominal=opb.read(32);
bitrate_lower=opb.read(32);
blocksizes[0]=1<<opb.read(4);
blocksizes[1]=1<<opb.read(4);
blocksizes[0]=1<<opb.read(4);
blocksizes[1]=1<<opb.read(4);
if((rate<1) ||
(channels<1)||
(blocksizes[0]<8)||
(blocksizes[1]<blocksizes[0]) ||
(opb.read(1)!=1)){
//goto err_out; // EOP check
clear();
return(-1);
}
return(0);
// err_out:
// vorbis_info_clear(vi);
// return(-1);
}
if((rate<1) ||
(channels<1)||
(blocksizes[0]<8)||
(blocksizes[1]<blocksizes[0]) ||
(opb.read(1)!=1))
{
//goto err_out; // EOP check
clear();
return(-1);
}
return(0);
// err_out:
// vorbis_info_clear(vi);
// return(-1);
}
// all of the real encoding details are here. The modes, books,
// everything
int unpack_books(csBuffer opb){
// all of the real encoding details are here. The modes, books,
// everything
int unpack_books(csBuffer opb)
{
//d* codebooks
books=opb.read(8)+1;
//d* codebooks
books=opb.read(8)+1;
if(book_param==null || book_param.length!=books)
book_param=new StaticCodeBook[books];
for(int i=0;i<books;i++){
book_param[i]=new StaticCodeBook();
if(book_param[i].unpack(opb)!=0){
//goto err_out;
clear();
return(-1);
}
}
if(book_param==null || book_param.Length!=books)
book_param=new StaticCodeBook[books];
for(int i=0;i<books;i++)
{
book_param[i]=new StaticCodeBook();
if(book_param[i].unpack(opb)!=0)
{
//goto err_out;
clear();
return(-1);
}
}
// time backend settings
times=opb.read(6)+1;
if(time_type==null || time_type.length!=times) time_type=new int[times];
if(time_param==null || time_param.length!=times)
time_param=new Object[times];
for(int i=0;i<times;i++){
time_type[i]=opb.read(16);
if(time_type[i]<0 || time_type[i]>=VI_TIMEB){
//goto err_out;
clear();
return(-1);
}
time_param[i]=FuncTime.time_P[time_type[i]].unpack(this, opb);
if(time_param[i]==null){
//goto err_out;
clear();
return(-1);
}
}
// time backend settings
times=opb.read(6)+1;
if(time_type==null || time_type.Length!=times) time_type=new int[times];
if(time_param==null || time_param.Length!=times)
time_param=new Object[times];
for(int i=0;i<times;i++)
{
time_type[i]=opb.read(16);
if(time_type[i]<0 || time_type[i]>=VI_TIMEB)
{
//goto err_out;
clear();
return(-1);
}
time_param[i]=FuncTime.time_P[time_type[i]].unpack(this, opb);
if(time_param[i]==null)
{
//goto err_out;
clear();
return(-1);
}
}
// floor backend settings
floors=opb.read(6)+1;
if(floor_type==null || floor_type.length!=floors)
floor_type=new int[floors];
if(floor_param==null || floor_param.length!=floors)
floor_param=new Object[floors];
// floor backend settings
floors=opb.read(6)+1;
if(floor_type==null || floor_type.Length!=floors)
floor_type=new int[floors];
if(floor_param==null || floor_param.Length!=floors)
floor_param=new Object[floors];
for(int i=0;i<floors;i++){
floor_type[i]=opb.read(16);
if(floor_type[i]<0 || floor_type[i]>=VI_FLOORB){
//goto err_out;
clear();
return(-1);
}
for(int i=0;i<floors;i++)
{
floor_type[i]=opb.read(16);
if(floor_type[i]<0 || floor_type[i]>=VI_FLOORB)
{
//goto err_out;
clear();
return(-1);
}
floor_param[i]=FuncFloor.floor_P[floor_type[i]].unpack(this,opb);
if(floor_param[i]==null){
//goto err_out;
clear();
return(-1);
}
}
floor_param[i]=FuncFloor.floor_P[floor_type[i]].unpack(this,opb);
if(floor_param[i]==null)
{
//goto err_out;
clear();
return(-1);
}
}
// residue backend settings
residues=opb.read(6)+1;
// residue backend settings
residues=opb.read(6)+1;
if(residue_type==null || residue_type.length!=residues)
residue_type=new int[residues];
if(residue_type==null || residue_type.Length!=residues)
residue_type=new int[residues];
if(residue_param==null || residue_param.length!=residues)
residue_param=new Object[residues];
if(residue_param==null || residue_param.Length!=residues)
residue_param=new Object[residues];
for(int i=0;i<residues;i++){
residue_type[i]=opb.read(16);
if(residue_type[i]<0 || residue_type[i]>=VI_RESB){
// goto err_out;
clear();
return(-1);
}
residue_param[i]=FuncResidue.residue_P[residue_type[i]].unpack(this,opb);
if(residue_param[i]==null){
// goto err_out;
clear();
return(-1);
}
}
for(int i=0;i<residues;i++)
{
residue_type[i]=opb.read(16);
if(residue_type[i]<0 || residue_type[i]>=VI_RESB)
{
// goto err_out;
clear();
return(-1);
}
residue_param[i]=FuncResidue.residue_P[residue_type[i]].unpack(this,opb);
if(residue_param[i]==null)
{
// goto err_out;
clear();
return(-1);
}
}
// map backend settings
maps=opb.read(6)+1;
if(map_type==null || map_type.length!=maps) map_type=new int[maps];
if(map_param==null || map_param.length!=maps) map_param=new Object[maps];
for(int i=0;i<maps;i++){
map_type[i]=opb.read(16);
if(map_type[i]<0 || map_type[i]>=VI_MAPB){
// goto err_out;
clear();
return(-1);
}
map_param[i]=FuncMapping.mapping_P[map_type[i]].unpack(this,opb);
if(map_param[i]==null){
// goto err_out;
clear();
return(-1);
}
}
// map backend settings
maps=opb.read(6)+1;
if(map_type==null || map_type.Length!=maps) map_type=new int[maps];
if(map_param==null || map_param.Length!=maps) map_param=new Object[maps];
for(int i=0;i<maps;i++)
{
map_type[i]=opb.read(16);
if(map_type[i]<0 || map_type[i]>=VI_MAPB)
{
// goto err_out;
clear();
return(-1);
}
map_param[i]=FuncMapping.mapping_P[map_type[i]].unpack(this,opb);
if(map_param[i]==null)
{
// goto err_out;
clear();
return(-1);
}
}
// mode settings
modes=opb.read(6)+1;
if(mode_param==null || mode_param.length!=modes)
mode_param=new InfoMode[modes];
for(int i=0;i<modes;i++){
mode_param[i]=new InfoMode();
mode_param[i].blockflag=opb.read(1);
mode_param[i].windowtype=opb.read(16);
mode_param[i].transformtype=opb.read(16);
mode_param[i].mapping=opb.read(8);
// mode settings
modes=opb.read(6)+1;
if(mode_param==null || mode_param.Length!=modes)
mode_param=new InfoMode[modes];
for(int i=0;i<modes;i++)
{
mode_param[i]=new InfoMode();
mode_param[i].blockflag=opb.read(1);
mode_param[i].windowtype=opb.read(16);
mode_param[i].transformtype=opb.read(16);
mode_param[i].mapping=opb.read(8);
if((mode_param[i].windowtype>=VI_WINDOWB)||
(mode_param[i].transformtype>=VI_WINDOWB)||
(mode_param[i].mapping>=maps)){
// goto err_out;
clear();
return(-1);
}
}
if((mode_param[i].windowtype>=VI_WINDOWB)||
(mode_param[i].transformtype>=VI_WINDOWB)||
(mode_param[i].mapping>=maps))
{
// goto err_out;
clear();
return(-1);
}
}
if(opb.read(1)!=1){
//goto err_out; // top level EOP check
clear();
return(-1);
}
if(opb.read(1)!=1)
{
//goto err_out; // top level EOP check
clear();
return(-1);
}
return(0);
// err_out:
// vorbis_info_clear(vi);
// return(-1);
}
return(0);
// err_out:
// vorbis_info_clear(vi);
// return(-1);
}
// The Vorbis header is in three packets; the initial small packet in
// the first page that identifies basic parameters, a second packet
// with bitstream comments and a third packet that holds the
// codebook.
// The Vorbis header is in three packets; the initial small packet in
// the first page that identifies basic parameters, a second packet
// with bitstream comments and a third packet that holds the
// codebook.
public int synthesis_headerin(Comment vc, Packet op){
Buffer opb=new Buffer();
public int synthesis_headerin(Comment vc, Packet op)
{
csBuffer opb=new csBuffer();
if(op!=null){
opb.readinit(op.packet_base, op.packet, op.bytes);
if(op!=null)
{
opb.readinit(op.packet_base, op.packet, op.bytes);
// Which of the three types of header is this?
// Also verify header-ness, vorbis
{
byte[] buffer=new byte[6];
int packtype=opb.read(8);
//memset(buffer,0,6);
opb.read(buffer,6);
if(buffer[0]!='v' || buffer[1]!='o' || buffer[2]!='r' ||
buffer[3]!='b' || buffer[4]!='i' || buffer[5]!='s'){
// not a vorbis header
return(-1);
}
switch(packtype){
case 0x01: // least significant *bit* is read first
if(op.b_o_s==0){
// Not the initial packet
return(-1);
}
if(rate!=0){
// previously initialized info header
return(-1);
}
return(unpack_info(opb));
case 0x03: // least significant *bit* is read first
if(rate==0){
// um... we didn't get the initial header
return(-1);
}
return(vc.unpack(opb));
case 0x05: // least significant *bit* is read first
if(rate==0 || vc.vendor==null){
// um... we didn;t get the initial header or comments yet
return(-1);
}
return(unpack_books(opb));
default:
// Not a valid vorbis header type
//return(-1);
break;
}
}
}
return(-1);
}
// Which of the three types of header is this?
// Also verify header-ness, vorbis
{
byte[] buffer=new byte[6];
int packtype=opb.read(8);
//memset(buffer,0,6);
opb.read(buffer,6);
if(buffer[0]!='v' || buffer[1]!='o' || buffer[2]!='r' ||
buffer[3]!='b' || buffer[4]!='i' || buffer[5]!='s')
{
// not a vorbis header
return(-1);
}
switch(packtype)
{
case 0x01: // least significant *bit* is read first
if(op.b_o_s==0)
{
// Not the initial packet
return(-1);
}
if(rate!=0)
{
// previously initialized info header
return(-1);
}
return(unpack_info(opb));
case 0x03: // least significant *bit* is read first
if(rate==0)
{
// um... we didn't get the initial header
return(-1);
}
return(vc.unpack(opb));
case 0x05: // least significant *bit* is read first
if(rate==0 || vc.vendor==null)
{
// um... we didn;t get the initial header or comments yet
return(-1);
}
return(unpack_books(opb));
default:
// Not a valid vorbis header type
//return(-1);
break;
}
}
}
return(-1);
}
// pack side
int pack_info(csBuffer opb){
// preamble
opb.write(0x01,8);
opb.write(_vorbis);
// pack side
int pack_info(csBuffer opb)
{
ASCIIEncoding AE = new ASCIIEncoding();
byte[] _vorbis_byt = AE.GetBytes(_vorbis);
// basic information about the stream
opb.write(0x00,32);
opb.write(channels,8);
opb.write(rate,32);
// preamble
opb.write(0x01,8);
opb.write(_vorbis_byt);
opb.write(bitrate_upper,32);
opb.write(bitrate_nominal,32);
opb.write(bitrate_lower,32);
// basic information about the stream
opb.write(0x00,32);
opb.write(channels,8);
opb.write(rate,32);
opb.write(ilog2(blocksizes[0]),4);
opb.write(ilog2(blocksizes[1]),4);
opb.write(1,1);
return(0);
}
opb.write(bitrate_upper,32);
opb.write(bitrate_nominal,32);
opb.write(bitrate_lower,32);
int pack_books(csBuffer opb){
opb.write(0x05,8);
opb.write(_vorbis);
opb.write(ilog2(blocksizes[0]),4);
opb.write(ilog2(blocksizes[1]),4);
opb.write(1,1);
return(0);
}
// books
opb.write(books-1,8);
for(int i=0;i<books;i++){
if(book_param[i].pack(opb)!=0){
//goto err_out;
return(-1);
}
}
int pack_books(csBuffer opb)
{
ASCIIEncoding AE = new ASCIIEncoding();
byte[] _vorbis_byt = AE.GetBytes(_vorbis);
opb.write(0x05,8);
opb.write(_vorbis_byt);
// times
opb.write(times-1,6);
for(int i=0;i<times;i++){
opb.write(time_type[i],16);
FuncTime.time_P[time_type[i]].pack(this.time_param[i],opb);
}
// books
opb.write(books-1,8);
for(int i=0;i<books;i++)
{
if(book_param[i].pack(opb)!=0)
{
//goto err_out;
return(-1);
}
}
// floors
opb.write(floors-1,6);
for(int i=0;i<floors;i++){
opb.write(floor_type[i],16);
FuncFloor.floor_P[floor_type[i]].pack(floor_param[i],opb);
}
// times
opb.write(times-1,6);
for(int i=0;i<times;i++)
{
opb.write(time_type[i],16);
FuncTime.time_P[time_type[i]].pack(this.time_param[i],opb);
}
// residues
opb.write(residues-1,6);
for(int i=0;i<residues;i++){
opb.write(residue_type[i],16);
FuncResidue.residue_P[residue_type[i]].pack(residue_param[i],opb);
}
// floors
opb.write(floors-1,6);
for(int i=0;i<floors;i++)
{
opb.write(floor_type[i],16);
FuncFloor.floor_P[floor_type[i]].pack(floor_param[i],opb);
}
// residues
opb.write(residues-1,6);
for(int i=0;i<residues;i++)
{
opb.write(residue_type[i],16);
FuncResidue.residue_P[residue_type[i]].pack(residue_param[i],opb);
}
// maps
opb.write(maps-1,6);
for(int i=0;i<maps;i++){
opb.write(map_type[i],16);
FuncMapping.mapping_P[map_type[i]].pack(this,map_param[i],opb);
}
// maps
opb.write(maps-1,6);
for(int i=0;i<maps;i++)
{
opb.write(map_type[i],16);
FuncMapping.mapping_P[map_type[i]].pack(this,map_param[i],opb);
}
// modes
opb.write(modes-1,6);
for(int i=0;i<modes;i++){
opb.write(mode_param[i].blockflag,1);
opb.write(mode_param[i].windowtype,16);
opb.write(mode_param[i].transformtype,16);
opb.write(mode_param[i].mapping,8);
}
opb.write(1,1);
return(0);
//err_out:
//return(-1);
}
// modes
opb.write(modes-1,6);
for(int i=0;i<modes;i++)
{
opb.write(mode_param[i].blockflag,1);
opb.write(mode_param[i].windowtype,16);
opb.write(mode_param[i].transformtype,16);
opb.write(mode_param[i].mapping,8);
}
opb.write(1,1);
return(0);
//err_out:
//return(-1);
}
// static void v_writestring(Buffer o, byte[] s){
// int i=0;
// while(s[i]!=0){
// o.write(s[i++],8);
// }
// }
// static void v_writestring(csBuffer o, byte[] s){
// int i=0;
// while(s[i]!=0){
// o.write(s[i++],8);
// }
// }
// static void v_readstring(Buffer o, byte[] buf, int bytes){
// int i=0
// while(bytes--!=0){
// buf[i++]=o.read(8);
// }
// }
// static void v_readstring(csBuffer o, byte[] buf, int bytes){
// int i=0
// while(bytes--!=0){
// buf[i++]=o.read(8);
// }
// }
// private Buffer opb_blocksize=new Buffer();
public int blocksize(Packet op){
//codec_setup_info *ci=vi->codec_setup;
Buffer opb=new Buffer();
// synchronized(opb_blocksize){
int mode;
// private csBuffer opb_blocksize=new csBuffer();
public int blocksize(Packet op)
{
//codec_setup_info *ci=vi->codec_setup;
csBuffer opb=new csBuffer();
// synchronized(opb_blocksize){
int mode;
opb.readinit(op.packet_base, op.packet, op.bytes);
opb.readinit(op.packet_base, op.packet, op.bytes);
/* Check the packet type */
if(opb.read(1)!=0){
/* Oops. This is not an audio data packet */
return(OV_ENOTAUDIO);
}
{
int modebits=0;
int v=modes;
while(v>1){
modebits++;
(uint)v>>=1;
}
/* Check the packet type */
if(opb.read(1)!=0)
{
/* Oops. This is not an audio data packet */
return(OV_ENOTAUDIO);
}
{
int modebits=0;
int v=modes;
while(v>1)
{
modebits++;
v = (int)((uint)v >> 1);
}
/* read our mode and pre/post windowsize */
mode=opb.read(modebits);
}
if(mode==-1)return(OV_EBADPACKET);
return(blocksizes[mode_param[mode].blockflag]);
// }
}
/* read our mode and pre/post windowsize */
mode=opb.read(modebits);
}
if(mode==-1)return(OV_EBADPACKET);
return(blocksizes[mode_param[mode].blockflag]);
// }
}
private static int ilog2(int v){
int ret=0;
while(v>1){
ret++;
(uint)v >>=1 ;
}
return(ret);
}
private static int ilog2(int v)
{
int ret=0;
while(v>1)
{
ret++;
v = (int)((uint)v >> 1);
}
return(ret);
}
public String toString(){
return "version:"+new Integer(version)+
", channels:"+new Integer(channels)+
", rate:"+new Integer(rate)+
", bitrate:"+new Integer(bitrate_upper)+","+
new Integer(bitrate_nominal)+","+
new Integer(bitrate_lower);
}
}
public String toString()
{
return "version:"+ version.ToString() +
", channels:"+ channels.ToString() +
", rate:"+ rate.ToString() +
", bitrate:"+ bitrate_upper.ToString() +","+
bitrate_nominal.ToString() +","+
bitrate_lower.ToString();
}
}
}

Просмотреть файл

@ -26,9 +26,13 @@
using System;
using csogg;
class InfoMode{
int blockflag;
int windowtype;
int transformtype;
int mapping;
}
namespace csvorbis
{
class InfoMode
{
internal int blockflag;
internal int windowtype;
internal int transformtype;
internal int mapping;
}
}

Просмотреть файл

@ -26,130 +26,136 @@
using System;
using csogg;
class Lookup{
static int COS_LOOKUP_SZ=128;
static float[] COS_LOOKUP={
+1.0000000000000f,+0.9996988186962f,+0.9987954562052f,+0.9972904566787f,
+0.9951847266722f,+0.9924795345987f,+0.9891765099648f,+0.9852776423889f,
+0.9807852804032f,+0.9757021300385f,+0.9700312531945f,+0.9637760657954f,
+0.9569403357322f,+0.9495281805930f,+0.9415440651830f,+0.9329927988347f,
+0.9238795325113f,+0.9142097557035f,+0.9039892931234f,+0.8932243011955f,
+0.8819212643484f,+0.8700869911087f,+0.8577286100003f,+0.8448535652497f,
+0.8314696123025f,+0.8175848131516f,+0.8032075314806f,+0.7883464276266f,
+0.7730104533627f,+0.7572088465065f,+0.7409511253550f,+0.7242470829515f,
+0.7071067811865f,+0.6895405447371f,+0.6715589548470f,+0.6531728429538f,
+0.6343932841636f,+0.6152315905806f,+0.5956993044924f,+0.5758081914178f,
+0.5555702330196f,+0.5349976198871f,+0.5141027441932f,+0.4928981922298f,
+0.4713967368260f,+0.4496113296546f,+0.4275550934303f,+0.4052413140050f,
+0.3826834323651f,+0.3598950365350f,+0.3368898533922f,+0.3136817403989f,
+0.2902846772545f,+0.2667127574749f,+0.2429801799033f,+0.2191012401569f,
+0.1950903220161f,+0.1709618887603f,+0.1467304744554f,+0.1224106751992f,
+0.0980171403296f,+0.0735645635997f,+0.0490676743274f,+0.0245412285229f,
+0.0000000000000f,-0.0245412285229f,-0.0490676743274f,-0.0735645635997f,
-0.0980171403296f,-0.1224106751992f,-0.1467304744554f,-0.1709618887603f,
-0.1950903220161f,-0.2191012401569f,-0.2429801799033f,-0.2667127574749f,
-0.2902846772545f,-0.3136817403989f,-0.3368898533922f,-0.3598950365350f,
-0.3826834323651f,-0.4052413140050f,-0.4275550934303f,-0.4496113296546f,
-0.4713967368260f,-0.4928981922298f,-0.5141027441932f,-0.5349976198871f,
-0.5555702330196f,-0.5758081914178f,-0.5956993044924f,-0.6152315905806f,
-0.6343932841636f,-0.6531728429538f,-0.6715589548470f,-0.6895405447371f,
-0.7071067811865f,-0.7242470829515f,-0.7409511253550f,-0.7572088465065f,
-0.7730104533627f,-0.7883464276266f,-0.8032075314806f,-0.8175848131516f,
-0.8314696123025f,-0.8448535652497f,-0.8577286100003f,-0.8700869911087f,
-0.8819212643484f,-0.8932243011955f,-0.9039892931234f,-0.9142097557035f,
-0.9238795325113f,-0.9329927988347f,-0.9415440651830f,-0.9495281805930f,
-0.9569403357322f,-0.9637760657954f,-0.9700312531945f,-0.9757021300385f,
-0.9807852804032f,-0.9852776423889f,-0.9891765099648f,-0.9924795345987f,
-0.9951847266722f,-0.9972904566787f,-0.9987954562052f,-0.9996988186962f,
-1.0000000000000f,
};
/* interpolated lookup based cos function, domain 0 to PI only */
static float coslook(float a){
double d=a*(.31830989*(float)COS_LOOKUP_SZ);
int i=(int)d;
return COS_LOOKUP[i]+ ((float)(d-i))*(COS_LOOKUP[i+1]-COS_LOOKUP[i]);
}
namespace csvorbis
{
class Lookup
{
static int COS_LOOKUP_SZ=128;
static float[] COS_LOOKUP={
+1.0000000000000f,+0.9996988186962f,+0.9987954562052f,+0.9972904566787f,
+0.9951847266722f,+0.9924795345987f,+0.9891765099648f,+0.9852776423889f,
+0.9807852804032f,+0.9757021300385f,+0.9700312531945f,+0.9637760657954f,
+0.9569403357322f,+0.9495281805930f,+0.9415440651830f,+0.9329927988347f,
+0.9238795325113f,+0.9142097557035f,+0.9039892931234f,+0.8932243011955f,
+0.8819212643484f,+0.8700869911087f,+0.8577286100003f,+0.8448535652497f,
+0.8314696123025f,+0.8175848131516f,+0.8032075314806f,+0.7883464276266f,
+0.7730104533627f,+0.7572088465065f,+0.7409511253550f,+0.7242470829515f,
+0.7071067811865f,+0.6895405447371f,+0.6715589548470f,+0.6531728429538f,
+0.6343932841636f,+0.6152315905806f,+0.5956993044924f,+0.5758081914178f,
+0.5555702330196f,+0.5349976198871f,+0.5141027441932f,+0.4928981922298f,
+0.4713967368260f,+0.4496113296546f,+0.4275550934303f,+0.4052413140050f,
+0.3826834323651f,+0.3598950365350f,+0.3368898533922f,+0.3136817403989f,
+0.2902846772545f,+0.2667127574749f,+0.2429801799033f,+0.2191012401569f,
+0.1950903220161f,+0.1709618887603f,+0.1467304744554f,+0.1224106751992f,
+0.0980171403296f,+0.0735645635997f,+0.0490676743274f,+0.0245412285229f,
+0.0000000000000f,-0.0245412285229f,-0.0490676743274f,-0.0735645635997f,
-0.0980171403296f,-0.1224106751992f,-0.1467304744554f,-0.1709618887603f,
-0.1950903220161f,-0.2191012401569f,-0.2429801799033f,-0.2667127574749f,
-0.2902846772545f,-0.3136817403989f,-0.3368898533922f,-0.3598950365350f,
-0.3826834323651f,-0.4052413140050f,-0.4275550934303f,-0.4496113296546f,
-0.4713967368260f,-0.4928981922298f,-0.5141027441932f,-0.5349976198871f,
-0.5555702330196f,-0.5758081914178f,-0.5956993044924f,-0.6152315905806f,
-0.6343932841636f,-0.6531728429538f,-0.6715589548470f,-0.6895405447371f,
-0.7071067811865f,-0.7242470829515f,-0.7409511253550f,-0.7572088465065f,
-0.7730104533627f,-0.7883464276266f,-0.8032075314806f,-0.8175848131516f,
-0.8314696123025f,-0.8448535652497f,-0.8577286100003f,-0.8700869911087f,
-0.8819212643484f,-0.8932243011955f,-0.9039892931234f,-0.9142097557035f,
-0.9238795325113f,-0.9329927988347f,-0.9415440651830f,-0.9495281805930f,
-0.9569403357322f,-0.9637760657954f,-0.9700312531945f,-0.9757021300385f,
-0.9807852804032f,-0.9852776423889f,-0.9891765099648f,-0.9924795345987f,
-0.9951847266722f,-0.9972904566787f,-0.9987954562052f,-0.9996988186962f,
-1.0000000000000f,
};
/* interpolated lookup based cos function, domain 0 to PI only */
internal static float coslook(float a)
{
double d=a*(.31830989*(float)COS_LOOKUP_SZ);
int i=(int)d;
return COS_LOOKUP[i]+ ((float)(d-i))*(COS_LOOKUP[i+1]-COS_LOOKUP[i]);
}
static int INVSQ_LOOKUP_SZ=32;
static float[] INVSQ_LOOKUP={
1.414213562373f,1.392621247646f,1.371988681140f,1.352246807566f,
1.333333333333f,1.315191898443f,1.297771369046f,1.281025230441f,
1.264911064067f,1.249390095109f,1.234426799697f,1.219988562661f,
1.206045378311f,1.192569588000f,1.179535649239f,1.166919931983f,
1.154700538379f,1.142857142857f,1.131370849898f,1.120224067222f,
1.109400392450f,1.098884511590f,1.088662107904f,1.078719779941f,
1.069044967650f,1.059625885652f,1.050451462878f,1.041511287847f,
1.032795558989f,1.024295039463f,1.016001016002f,1.007905261358f,
1.000000000000f,
};
/* interpolated 1./sqrt(p) where .5 <= p < 1. */
static float invsqlook(float a){
// System.out.println(a);
double d=a*(2.f*(float)INVSQ_LOOKUP_SZ)-(float)INVSQ_LOOKUP_SZ;
int i=(int)d;
return INVSQ_LOOKUP[i]+ ((float)(d-i))*(INVSQ_LOOKUP[i+1]-INVSQ_LOOKUP[i]);
}
static int INVSQ_LOOKUP_SZ=32;
static float[] INVSQ_LOOKUP={
1.414213562373f,1.392621247646f,1.371988681140f,1.352246807566f,
1.333333333333f,1.315191898443f,1.297771369046f,1.281025230441f,
1.264911064067f,1.249390095109f,1.234426799697f,1.219988562661f,
1.206045378311f,1.192569588000f,1.179535649239f,1.166919931983f,
1.154700538379f,1.142857142857f,1.131370849898f,1.120224067222f,
1.109400392450f,1.098884511590f,1.088662107904f,1.078719779941f,
1.069044967650f,1.059625885652f,1.050451462878f,1.041511287847f,
1.032795558989f,1.024295039463f,1.016001016002f,1.007905261358f,
1.000000000000f,
};
/* interpolated 1./sqrt(p) where .5 <= p < 1. */
internal static float invsqlook(float a)
{
// System.out.println(a);
double d=a*(2.0f*(float)INVSQ_LOOKUP_SZ)-(float)INVSQ_LOOKUP_SZ;
int i=(int)d;
return INVSQ_LOOKUP[i]+ ((float)(d-i))*(INVSQ_LOOKUP[i+1]-INVSQ_LOOKUP[i]);
}
static int INVSQ2EXP_LOOKUP_MIN=-32;
static int INVSQ2EXP_LOOKUP_MAX=32;
static float[] INVSQ2EXP_LOOKUP={
65536.f, 46340.95001f, 32768.f, 23170.47501f,
16384.f, 11585.2375f, 8192.f, 5792.618751f,
4096.f, 2896.309376f, 2048.f, 1448.154688f,
1024.f, 724.0773439f, 512.f, 362.038672f,
256.f, 181.019336f, 128.f, 90.50966799f,
64.f, 45.254834f, 32.f, 22.627417f,
16.f, 11.3137085f, 8.f, 5.656854249f,
4.f, 2.828427125f, 2.f, 1.414213562f,
1.f, 0.7071067812f, 0.5f, 0.3535533906f,
0.25f, 0.1767766953f, 0.125f, 0.08838834765f,
0.0625f, 0.04419417382f, 0.03125f, 0.02209708691f,
0.015625f, 0.01104854346f, 0.0078125f, 0.005524271728f,
0.00390625f, 0.002762135864f, 0.001953125f, 0.001381067932f,
0.0009765625f, 0.000690533966f, 0.00048828125f, 0.000345266983f,
0.000244140625f,0.0001726334915f,0.0001220703125f,8.631674575e-05f,
6.103515625e-05f,4.315837288e-05f,3.051757812e-05f,2.157918644e-05f,
1.525878906e-05f,
};
/* interpolated 1./sqrt(p) where .5 <= p < 1. */
static float invsq2explook(int a){
return INVSQ2EXP_LOOKUP[a-INVSQ2EXP_LOOKUP_MIN];
}
static int INVSQ2EXP_LOOKUP_MIN=-32;
//static int INVSQ2EXP_LOOKUP_MAX=32;
static float[] INVSQ2EXP_LOOKUP={
65536.0f, 46340.95001f, 32768.0f, 23170.47501f,
16384.0f, 11585.2375f, 8192.0f, 5792.618751f,
4096.0f, 2896.309376f, 2048.0f, 1448.154688f,
1024.0f, 724.0773439f, 512.0f, 362.038672f,
256.0f, 181.019336f, 128.0f, 90.50966799f,
64.0f, 45.254834f, 32.0f, 22.627417f,
16.0f, 11.3137085f, 8.0f, 5.656854249f,
4.0f, 2.828427125f, 2.0f, 1.414213562f,
1.0f, 0.7071067812f, 0.5f, 0.3535533906f,
0.25f, 0.1767766953f, 0.125f, 0.08838834765f,
0.0625f, 0.04419417382f, 0.03125f, 0.02209708691f,
0.015625f, 0.01104854346f, 0.0078125f, 0.005524271728f,
0.00390625f, 0.002762135864f, 0.001953125f, 0.001381067932f,
0.0009765625f, 0.000690533966f, 0.00048828125f, 0.000345266983f,
0.000244140625f,0.0001726334915f,0.0001220703125f,8.631674575e-05f,
6.103515625e-05f,4.315837288e-05f,3.051757812e-05f,2.157918644e-05f,
1.525878906e-05f,
};
/* interpolated 1./sqrt(p) where .5 <= p < 1. */
internal static float invsq2explook(int a)
{
return INVSQ2EXP_LOOKUP[a-INVSQ2EXP_LOOKUP_MIN];
}
const int FROMdB_LOOKUP_SZ=35;
const int FROMdB2_LOOKUP_SZ=32;
const int FROMdB_SHIFT=5;
const int FROMdB2_SHIFT=3;
const int FROMdB2_MASK=31;
static float[] FROMdB_LOOKUP = {
1.0f, 0.6309573445f, 0.3981071706f, 0.2511886432f,
0.1584893192f, 0.1f, 0.06309573445f, 0.03981071706f,
0.02511886432f, 0.01584893192f, 0.01f, 0.006309573445f,
0.003981071706f, 0.002511886432f, 0.001584893192f, 0.001f,
0.0006309573445f,0.0003981071706f,0.0002511886432f,0.0001584893192f,
0.0001f,6.309573445e-05f,3.981071706e-05f,2.511886432e-05f,
1.584893192e-05f, 1e-05f,6.309573445e-06f,3.981071706e-06f,
2.511886432e-06f,1.584893192e-06f, 1e-06f,6.309573445e-07f,
3.981071706e-07f,2.511886432e-07f,1.584893192e-07f,
};
static float[] FROMdB2_LOOKUP = {
0.9928302478f, 0.9786445908f, 0.9646616199f, 0.9508784391f,
0.9372921937f, 0.92390007f, 0.9106992942f, 0.8976871324f,
0.8848608897f, 0.8722179097f, 0.8597555737f, 0.8474713009f,
0.835362547f, 0.8234268041f, 0.8116616003f, 0.8000644989f,
0.7886330981f, 0.7773650302f, 0.7662579617f, 0.755309592f,
0.7445176537f, 0.7338799116f, 0.7233941627f, 0.7130582353f,
0.7028699885f, 0.6928273125f, 0.6829281272f, 0.6731703824f,
0.6635520573f, 0.6540711597f, 0.6447257262f, 0.6355138211f,
};
/* interpolated lookup based fromdB function, domain -140dB to 0dB only */
static float fromdBlook(float a){
int i=(int)(a*((float)(-(1<<FROMdB2_SHIFT))));
return (i<0)?1.f:
((i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))?0.f:
FROMdB_LOOKUP[(uint)i>>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]);
}
const int FROMdB_LOOKUP_SZ=35;
const int FROMdB2_LOOKUP_SZ=32;
const int FROMdB_SHIFT=5;
const int FROMdB2_SHIFT=3;
const int FROMdB2_MASK=31;
static float[] FROMdB_LOOKUP = {
1.0f, 0.6309573445f, 0.3981071706f, 0.2511886432f,
0.1584893192f, 0.1f, 0.06309573445f, 0.03981071706f,
0.02511886432f, 0.01584893192f, 0.01f, 0.006309573445f,
0.003981071706f, 0.002511886432f, 0.001584893192f, 0.001f,
0.0006309573445f,0.0003981071706f,0.0002511886432f,0.0001584893192f,
0.0001f,6.309573445e-05f,3.981071706e-05f,2.511886432e-05f,
1.584893192e-05f, 1e-05f,6.309573445e-06f,3.981071706e-06f,
2.511886432e-06f,1.584893192e-06f, 1e-06f,6.309573445e-07f,
3.981071706e-07f,2.511886432e-07f,1.584893192e-07f,
};
static float[] FROMdB2_LOOKUP = {
0.9928302478f, 0.9786445908f, 0.9646616199f, 0.9508784391f,
0.9372921937f, 0.92390007f, 0.9106992942f, 0.8976871324f,
0.8848608897f, 0.8722179097f, 0.8597555737f, 0.8474713009f,
0.835362547f, 0.8234268041f, 0.8116616003f, 0.8000644989f,
0.7886330981f, 0.7773650302f, 0.7662579617f, 0.755309592f,
0.7445176537f, 0.7338799116f, 0.7233941627f, 0.7130582353f,
0.7028699885f, 0.6928273125f, 0.6829281272f, 0.6731703824f,
0.6635520573f, 0.6540711597f, 0.6447257262f, 0.6355138211f,
};
/* interpolated lookup based fromdB function, domain -140dB to 0dB only */
internal static float fromdBlook(float a)
{
int i=(int)(a*((float)(-(1<<FROMdB2_SHIFT))));
return (i<0)?1.0f:
((i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))?0.0f:
FROMdB_LOOKUP[(uint)i>>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]);
}
}
}

Просмотреть файл

@ -26,229 +26,176 @@
using System;
using csogg;
class Lpc{
Drft fft=new Drft();
namespace csvorbis
{
class Lpc
{
Drft fft=new Drft();
int ln;
int m;
int ln;
int m;
// Autocorrelation LPC coeff generation algorithm invented by
// N. Levinson in 1947, modified by J. Durbin in 1959.
// Autocorrelation LPC coeff generation algorithm invented by
// N. Levinson in 1947, modified by J. Durbin in 1959.
// Input : n elements of time doamin data
// Output: m lpc coefficients, excitation energy
// Input : n elements of time doamin data
// Output: m lpc coefficients, excitation energy
static float lpc_from_data(float[] data, float[] lpc,int n,int m){
float[] aut=new float[m+1];
float error;
int i,j;
static float lpc_from_data(float[] data, float[] lpc,int n,int m)
{
float[] aut=new float[m+1];
float error;
int i,j;
// autocorrelation, p+1 lag coefficients
// autocorrelation, p+1 lag coefficients
j=m+1;
while(j--!=0){
float d=0;
for(i=j;i<n;i++)d+=data[i]*data[i-j];
aut[j]=d;
}
j=m+1;
while(j--!=0)
{
float d=0.0F;
for(i=j;i<n;i++)d+=data[i]*data[i-j];
aut[j]=d;
}
// Generate lpc coefficients from autocorr values
// Generate lpc coefficients from autocorr values
error=aut[0];
/*
if(error==0){
for(int k=0; k<m; k++) lpc[k]=0.0f;
return 0;
}
*/
error=aut[0];
/*
if(error==0){
for(int k=0; k<m; k++) lpc[k]=0.0f;
return 0;
}
*/
for(i=0;i<m;i++){
float r=-aut[i+1];
for(i=0;i<m;i++)
{
float r=-aut[i+1];
if(error==0){
for(int k=0; k<m; k++) lpc[k]=0.0f;
return 0;
}
if(error==0)
{
for(int k=0; k<m; k++) lpc[k]=0.0f;
return 0;
}
// Sum up this iteration's reflection coefficient; note that in
// Vorbis we don't save it. If anyone wants to recycle this code
// and needs reflection coefficients, save the results of 'r' from
// each iteration.
// Sum up this iteration's reflection coefficient; note that in
// Vorbis we don't save it. If anyone wants to recycle this code
// and needs reflection coefficients, save the results of 'r' from
// each iteration.
for(j=0;j<i;j++)r-=lpc[j]*aut[i-j];
r/=error;
for(j=0;j<i;j++)r-=lpc[j]*aut[i-j];
r/=error;
// Update LPC coefficients and total error
// Update LPC coefficients and total error
lpc[i]=r;
for(j=0;j<i/2;j++){
float tmp=lpc[j];
lpc[j]+=r*lpc[i-1-j];
lpc[i-1-j]+=r*tmp;
}
if(i%2!=0)lpc[j]+=lpc[j]*r;
lpc[i]=r;
for(j=0;j<i/2;j++)
{
float tmp=lpc[j];
lpc[j]+=r*lpc[i-1-j];
lpc[i-1-j]+=r*tmp;
}
if(i%2!=0)lpc[j]+=lpc[j]*r;
error*=1.0-r*r;
}
error*=(float)(1.0-r*r);
}
// we need the error value to know how big an impulse to hit the
// filter with later
// we need the error value to know how big an impulse to hit the
// filter with later
return error;
}
return error;
}
// Input : n element envelope spectral curve
// Output: m lpc coefficients, excitation energy
// Input : n element envelope spectral curve
// Output: m lpc coefficients, excitation energy
float lpc_from_curve(float[] curve, float[] lpc){
int n=ln;
float[] work=new float[n+n];
float fscale=(float)(.5/n);
int i,j;
float lpc_from_curve(float[] curve, float[] lpc)
{
int n=ln;
float[] work=new float[n+n];
float fscale=(float)(.5/n);
int i,j;
// input is a real curve. make it complex-real
// This mixes phase, but the LPC generation doesn't care.
for(i=0;i<n;i++){
work[i*2]=curve[i]*fscale;
work[i*2+1]=0;
}
work[n*2-1]=curve[n-1]*fscale;
// input is a real curve. make it complex-real
// This mixes phase, but the LPC generation doesn't care.
for(i=0;i<n;i++)
{
work[i*2]=curve[i]*fscale;
work[i*2+1]=0;
}
work[n*2-1]=curve[n-1]*fscale;
n*=2;
fft.backward(work);
n*=2;
fft.backward(work);
// The autocorrelation will not be circular. Shift, else we lose
// most of the power in the edges.
// The autocorrelation will not be circular. Shift, else we lose
// most of the power in the edges.
for(i=0,j=n/2;i<n/2;){
float temp=work[i];
work[i++]=work[j];
work[j++]=temp;
}
for(i=0,j=n/2;i<n/2;)
{
float temp=work[i];
work[i++]=work[j];
work[j++]=temp;
}
return(lpc_from_data(work,lpc,n,m));
}
return(lpc_from_data(work,lpc,n,m));
}
void init(int mapped, int m){
//memset(l,0,sizeof(lpc_lookup));
internal void init(int mapped, int m)
{
//memset(l,0,sizeof(lpc_lookup));
Console.Error.WriteLine("lpc::init");
ln=mapped;
this.m=m;
ln=mapped;
this.m=m;
// we cheat decoding the LPC spectrum via FFTs
Console.Error.WriteLine("Setting up FFT");
fft.init(mapped*2);
}
// we cheat decoding the LPC spectrum via FFTs
fft.init(mapped*2);
}
void clear()
{
fft.clear();
}
void clear(){
fft.clear();
}
static float FAST_HYPOT(float a, float b)
{
return (float)Math.Sqrt((a)*(a) + (b)*(b));
}
static float FAST_HYPOT(float a, float b){
return (float)Math.sqrt((a)*(a) + (b)*(b));
}
// One can do this the long way by generating the transfer function in
// the time domain and taking the forward FFT of the result. The
// results from direct calculation are cleaner and faster.
//
// This version does a linear curve generation and then later
// interpolates the log curve from the linear curve.
// One can do this the long way by generating the transfer function in
// the time domain and taking the forward FFT of the result. The
// results from direct calculation are cleaner and faster.
//
// This version does a linear curve generation and then later
// interpolates the log curve from the linear curve.
internal void lpc_to_curve(float[] curve, float[] lpc, float amp)
{
void lpc_to_curve(float[] curve, float[] lpc, float amp){
//memset(curve,0,sizeof(float)*l->ln*2);
for(int i=0; i<ln*2; i++)curve[i]=0.0f;
//memset(curve,0,sizeof(float)*l->ln*2);
for(int i=0; i<ln*2; i++)curve[i]=0.0f;
if(amp==0)return;
if(amp==0)return;
for(int i=0;i<m;i++)
{
curve[i*2+1]=lpc[i]/(4*amp);
curve[i*2+2]=-lpc[i]/(4*amp);
}
for(int i=0;i<m;i++){
curve[i*2+1]=lpc[i]/(4*amp);
curve[i*2+2]=-lpc[i]/(4*amp);
}
fft.backward(curve); // reappropriated ;-)
fft.backward(curve); // reappropriated ;-)
int l2=ln*2;
float unit=(float)(1.0/amp);
curve[0]=(float)(1.0/(curve[0]*2+unit));
for(int i=1;i<ln;i++)
{
float real=(curve[i]+curve[l2-i]);
float imag=(curve[i]-curve[l2-i]);
{
int l2=ln*2;
float unit=(float)(1.0/amp);
curve[0]=(float)(1.0/(curve[0]*2+unit));
for(int i=1;i<ln;i++){
float real=(curve[i]+curve[l2-i]);
float imag=(curve[i]-curve[l2-i]);
float a = real + unit;
curve[i] = (float)(1.0 / FAST_HYPOT(a, imag));
}
}
}
/*
// subtract or add an lpc filter to data. Vorbis doesn't actually use this.
static void lpc_residue(float[] coeff, float[] prime,int m,
float[] data, int n){
// in: coeff[0...m-1] LPC coefficients
// prime[0...m-1] initial values
// data[0...n-1] data samples
// out: data[0...n-1] residuals from LPC prediction
float[] work=new float[m+n];
float y;
if(prime==null){
for(int i=0;i<m;i++){
work[i]=0;
}
}
else{
for(int i=0;i<m;i++){
work[i]=prime[i];
}
}
for(int i=0;i<n;i++){
y=0;
for(int j=0;j<m;j++){
y-=work[i+j]*coeff[m-j-1];
}
work[i+m]=data[i];
data[i]-=y;
}
}
static void lpc_predict(float[] coeff, float[] prime,int m,
float[] data, int n){
// in: coeff[0...m-1] LPC coefficients
// prime[0...m-1] initial values (allocated size of n+m-1)
// data[0...n-1] residuals from LPC prediction
// out: data[0...n-1] data samples
int o,p;
float y;
float[] work=new float[m+n];
if(prime==null){
for(int i=0;i<m;i++){
work[i]=0.f;
}
}
else{
for(int i=0;i<m;i++){
work[i]=prime[i];
}
}
for(int i=0;i<n;i++){
y=data[i];
o=i;
p=m;
for(int j=0;j<m;j++){
y-=work[o++]*coeff[--p];
}
data[i]=work[o]=y;
}
}
*/
}
float a = real + unit;
curve[i] = (float)(1.0 / FAST_HYPOT(a, imag));
}
}
}
}

Просмотреть файл

@ -24,98 +24,110 @@
*/
using System;
using System.Runtime.InteropServices;
using csogg;
/*
function: LSP (also called LSF) conversion routines
The LSP generation code is taken (with minimal modification) from
"On the Computation of the LSP Frequencies" by Joseph Rothweiler
<rothwlr@altavista.net>, available at:
http://www2.xtdl.com/~rothwlr/lsfpaper/lsfpage.html
********************************************************************/
class Lsp
namespace csvorbis
{
/*
function: LSP (also called LSF) conversion routines
static float M_PI=(float)(3.1415926539);
The LSP generation code is taken (with minimal modification) from
"On the Computation of the LSP Frequencies" by Joseph Rothweiler
<rothwlr@altavista.net>, available at:
http://www2.xtdl.com/~rothwlr/lsfpaper/lsfpage.html
********************************************************************/
static void lsp_to_curve(float[] curve,
int[] map, int n, int ln,
float[] lsp, int m,
float amp, float ampoffset)
class Lsp
{
int i;
float wdel=M_PI/ln;
for(i=0;i<m;i++)lsp[i]=Lookup.coslook(lsp[i]);
int m2=(m/2)*2;
i=0;
while(i<n)
[StructLayout(LayoutKind.Explicit, Size=32, CharSet=CharSet.Ansi)]
class FloatHack
{
int k=map[i];
float p=.7071067812f;
float q=.7071067812f;
float w=Lookup.coslook(wdel*k);
int ftmp=0;
int c=(uint)m >> 1;
[FieldOffset(0)] public float fh_float;
[FieldOffset(0)] public int fh_int;
}
static float M_PI=(float)(3.1415926539);
for(int j=0;j<m2;j+=2)
{
q*=lsp[j]-w;
p*=lsp[j+1]-w;
}
internal static void lsp_to_curve(float[] curve,
int[] map, int n, int ln,
float[] lsp, int m,
float amp, float ampoffset)
{
int i;
float wdel=M_PI/ln;
for(i=0;i<m;i++)lsp[i]=Lookup.coslook(lsp[i]);
int m2=(m/2)*2;
if((m&1)!=0)
i=0;
while(i<n)
{
/* odd order filter; slightly assymetric */
/* the last coefficient */
q*=lsp[m-1]-w;
q*=q;
p*=p*(1.f-w*w);
}
else
{
/* even order filter; still symmetric */
q*=q*(1.f+w);
p*=p*(1.f-w);
}
FloatHack fh = new FloatHack();
int k=map[i];
float p=.7071067812f;
float q=.7071067812f;
float w=Lookup.coslook(wdel*k);
//int ftmp=0;
int c=(int)((uint)m >> 1);
// q=frexp(p+q,&qexp);
q=p+q;
int hx=Float.floatToIntBits(q);
int ix=0x7fffffff&hx;
int qexp=0;
if(ix>=0x7f800000||(ix==0))
{
// 0,inf,nan
}
else
{
if(ix<0x00800000)
{ // subnormal
q*=3.3554432000e+07; // 0x4c000000
hx=Float.floatToIntBits(q);
ix=0x7fffffff&hx;
qexp=-25;
for(int j=0;j<m2;j+=2)
{
q*=lsp[j]-w;
p*=lsp[j+1]-w;
}
qexp += (((uint)ix >> 23)-126);
hx=(hx&0x807fffff)|0x3f000000;
q=Float.intBitsToFloat(hx);
if((m&1)!=0)
{
/* odd order filter; slightly assymetric */
/* the last coefficient */
q*=lsp[m-1]-w;
q*=q;
p*=p*(1.0f-w*w);
}
else
{
/* even order filter; still symmetric */
q*=q*(1.0f+w);
p*=p*(1.0f-w);
}
// q=frexp(p+q,&qexp);
q=p+q;
fh.fh_float = q;
int hx=fh.fh_int;
int ix=0x7fffffff&hx;
int qexp=0;
if(ix>=0x7f800000||(ix==0))
{
// 0,inf,nan
}
else
{
if(ix<0x00800000)
{ // subnormal
q*=3.3554432000e+07F; // 0x4c000000
fh.fh_float = q;
hx=fh.fh_int;
ix=0x7fffffff&hx;
qexp=-25;
}
qexp += (int)(((uint)ix >> 23)-126);
hx=(int)((hx&0x807fffff)|0x3f000000);
fh.fh_int = hx;
q=fh.fh_float;
}
q=Lookup.fromdBlook(amp*
Lookup.invsqlook(q)*
Lookup.invsq2explook(qexp+m)-ampoffset);
do{curve[i++]*=q;}
// do{curve[i++]=q;}
while(i<n&&map[i]==k);
}
q=Lookup.fromdBlook(amp*
Lookup.invsqlook(q)*
Lookup.invsq2explook(qexp+m)-ampoffset);
do{curve[i++]*=q;}
// do{curve[i++]=q;}
while(i<n&&map[i]==k);
}
}
}
}

Просмотреть файл

@ -26,428 +26,437 @@
using System;
using csogg;
class Mapping0 : FuncMapping
namespace csvorbis
{
static int seq=0;
void free_info(Object imap){}
void free_look(Object imap){}
Object look(DspState vd, InfoMode vm, Object m)
class Mapping0 : FuncMapping
{
Info vi=vd.vi;
LookMapping0 look=new LookMapping0();
InfoMapping0 info=look.map=(InfoMapping0)m;
look.mode=vm;
look.time_look=new Object[info.submaps];
look.floor_look=new Object[info.submaps];
look.residue_look=new Object[info.submaps];
//static int seq=0;
override public void free_info(Object imap){}
override public void free_look(Object imap){}
look.time_func=new FuncTime[info.submaps];
look.floor_func=new FuncFloor[info.submaps];
look.residue_func=new FuncResidue[info.submaps];
for(int i=0;i<info.submaps;i++)
override public Object look(DspState vd, InfoMode vm, Object m)
{
int timenum=info.timesubmap[i];
int floornum=info.floorsubmap[i];
int resnum=info.residuesubmap[i];
look.time_func[i]=FuncTime.time_P[vi.time_type[timenum]];
look.time_look[i]=look.time_func[i].look(vd,vm,vi.time_param[timenum]);
look.floor_func[i]=FuncFloor.floor_P[vi.floor_type[floornum]];
look.floor_look[i]=look.floor_func[i].
look(vd,vm,vi.floor_param[floornum]);
look.residue_func[i]=FuncResidue.residue_P[vi.residue_type[resnum]];
look.residue_look[i]=look.residue_func[i].
look(vd,vm,vi.residue_param[resnum]);
}
if(vi.psys!=0 && vd.analysisp!=0)
{
}
look.ch=vi.channels;
return(look);
}
void pack(Info vi, Object imap, csBuffer opb)
{
InfoMapping0 info=(InfoMapping0)imap;
/* another 'we meant to do it this way' hack... up to beta 4, we
packed 4 binary zeros here to signify one submapping in use. We
now redefine that to mean four bitflags that indicate use of
deeper features; bit0:submappings, bit1:coupling,
bit2,3:reserved. This is backward compatable with all actual uses
of the beta code. */
if(info.submaps>1)
{
opb.write(1,1);
opb.write(info.submaps-1,4);
}
else
{
opb.write(0,1);
}
if(info.coupling_steps>0)
{
opb.write(1,1);
opb.write(info.coupling_steps-1,8);
for(int i=0;i<info.coupling_steps;i++)
{
opb.write(info.coupling_mag[i],ilog2(vi.channels));
opb.write(info.coupling_ang[i],ilog2(vi.channels));
}
}
else
{
opb.write(0,1);
}
opb.write(0,2); /* 2,3:reserved */
/* we don't write the channel submappings if we only have one... */
if(info.submaps>1)
{
for(int i=0;i<vi.channels;i++)
opb.write(info.chmuxlist[i],4);
}
for(int i=0;i<info.submaps;i++)
{
opb.write(info.timesubmap[i],8);
opb.write(info.floorsubmap[i],8);
opb.write(info.residuesubmap[i],8);
}
}
// also responsible for range checking
Object unpack(Info vi, csBuffer opb)
{
InfoMapping0 info=new InfoMapping0();
// !!!!
if(opb.read(1)!=0)
{
info.submaps=opb.read(4)+1;
}
else
{
info.submaps=1;
}
if(opb.read(1)!=0)
{
info.coupling_steps=opb.read(8)+1;
for(int i=0;i<info.coupling_steps;i++)
{
int testM=info.coupling_mag[i]=opb.read(ilog2(vi.channels));
int testA=info.coupling_ang[i]=opb.read(ilog2(vi.channels));
if(testM<0 ||
testA<0 ||
testM==testA ||
testM>=vi.channels ||
testA>=vi.channels)
{
//goto err_out;
info.free();
return(null);
}
}
}
if(opb.read(2)>0)
{ /* 2,3:reserved */
//goto err_out;
info.free();
return(null);
}
if(info.submaps>1)
{
for(int i=0;i<vi.channels;i++)
{
info.chmuxlist[i]=opb.read(4);
if(info.chmuxlist[i]>=info.submaps)
{
//goto err_out;
info.free();
return(null);
}
}
}
for(int i=0;i<info.submaps;i++)
{
info.timesubmap[i]=opb.read(8);
if(info.timesubmap[i]>=vi.times)
{
//goto err_out;
info.free();
return(null);
}
info.floorsubmap[i]=opb.read(8);
if(info.floorsubmap[i]>=vi.floors)
{
//goto err_out;
info.free();
return(null);
}
info.residuesubmap[i]=opb.read(8);
if(info.residuesubmap[i]>=vi.residues)
{
//goto err_out;
info.free();
return(null);
}
}
return info;
//err_out:
//free_info(info);
//return(NULL);
}
float[][] pcmbundle=null;
int[] zerobundle=null;
int[] nonzero=null;
Object[] floormemo=null;
int inverse(Block vb, Object l)
{
lock(this)
{
//System.err.println("Mapping0.inverse");
DspState vd=vb.vd;
Console.Error.WriteLine("Mapping0");
Info vi=vd.vi;
LookMapping0 look=(LookMapping0)l;
InfoMapping0 info=look.map;
InfoMode mode=look.mode;
int n=vb.pcmend=vi.blocksizes[vb.W];
LookMapping0 looks=new LookMapping0();
InfoMapping0 info=looks.map=(InfoMapping0)m;
looks.mode=vm;
looks.time_look=new Object[info.submaps];
looks.floor_look=new Object[info.submaps];
looks.residue_look=new Object[info.submaps];
float[] window=vd.window[vb.W][vb.lW][vb.nW][mode.windowtype];
// float[][] pcmbundle=new float[vi.channels][];
// int[] nonzero=new int[vi.channels];
if(pcmbundle==null || pcmbundle.length<vi.channels)
looks.time_func=new FuncTime[info.submaps];
looks.floor_func=new FuncFloor[info.submaps];
looks.residue_func=new FuncResidue[info.submaps];
Console.Error.WriteLine("info.submaps: "+info.submaps);
for(int i=0;i<info.submaps;i++)
{
pcmbundle=new float[vi.channels][];
nonzero=new int[vi.channels];
zerobundle=new int[vi.channels];
floormemo=new Object[vi.channels];
int timenum=info.timesubmap[i];
int floornum=info.floorsubmap[i];
int resnum=info.residuesubmap[i];
looks.time_func[i]=FuncTime.time_P[vi.time_type[timenum]];
looks.time_look[i]=looks.time_func[i].look(vd,vm,vi.time_param[timenum]);
Console.Error.WriteLine("TIME");
looks.floor_func[i]=FuncFloor.floor_P[vi.floor_type[floornum]];
Console.Error.WriteLine("FLO: floornum:" + floornum);
looks.floor_look[i]=looks.floor_func[i].
look(vd,vm,vi.floor_param[floornum]);
Console.Error.WriteLine("FLOOR");
looks.residue_func[i]=FuncResidue.residue_P[vi.residue_type[resnum]];
looks.residue_look[i]=looks.residue_func[i].
look(vd,vm,vi.residue_param[resnum]);
Console.Error.WriteLine("RESIDUE");
}
if(vi.psys!=0 && vd.analysisp!=0)
{
}
looks.ch=vi.channels;
return(looks);
}
override public void pack(Info vi, Object imap, csBuffer opb)
{
InfoMapping0 info=(InfoMapping0)imap;
/* another 'we meant to do it this way' hack... up to beta 4, we
packed 4 binary zeros here to signify one submapping in use. We
now redefine that to mean four bitflags that indicate use of
deeper features; bit0:submappings, bit1:coupling,
bit2,3:reserved. This is backward compatable with all actual uses
of the beta code. */
if(info.submaps>1)
{
opb.write(1,1);
opb.write(info.submaps-1,4);
}
else
{
opb.write(0,1);
}
if(info.coupling_steps>0)
{
opb.write(1,1);
opb.write(info.coupling_steps-1,8);
for(int i=0;i<info.coupling_steps;i++)
{
opb.write(info.coupling_mag[i],ilog2(vi.channels));
opb.write(info.coupling_ang[i],ilog2(vi.channels));
}
}
else
{
opb.write(0,1);
}
// time domain information decode (note that applying the
// information would have to happen later; we'll probably add a
// function entry to the harness for that later
// NOT IMPLEMENTED
opb.write(0,2); /* 2,3:reserved */
// recover the spectral envelope; store it in the PCM vector for now
for(int i=0;i<vi.channels;i++)
/* we don't write the channel submappings if we only have one... */
if(info.submaps>1)
{
float[] pcm=vb.pcm[i];
int submap=info.chmuxlist[i];
for(int i=0;i<vi.channels;i++)
opb.write(info.chmuxlist[i],4);
}
for(int i=0;i<info.submaps;i++)
{
opb.write(info.timesubmap[i],8);
opb.write(info.floorsubmap[i],8);
opb.write(info.residuesubmap[i],8);
}
}
floormemo[i]=look.floor_func[submap].inverse1(vb,look.
floor_look[submap],
floormemo[i]
);
if(floormemo[i]!=null){ nonzero[i]=1; }
else{ nonzero[i]=0; }
for(int j=0; j<n/2; j++)
{
pcm[j]=0;
}
override public Object unpack(Info vi, csBuffer opb)
{
// also responsible for range checking
InfoMapping0 info=new InfoMapping0();
//_analysis_output("ifloor",seq+i,pcm,n/2,0,1);
// !!!!
if(opb.read(1)!=0)
{
info.submaps=opb.read(4)+1;
}
else
{
info.submaps=1;
}
for(int i=0; i<info.coupling_steps; i++)
if(opb.read(1)!=0)
{
if(nonzero[info.coupling_mag[i]]!=0 ||
nonzero[info.coupling_ang[i]]!=0)
info.coupling_steps=opb.read(8)+1;
for(int i=0;i<info.coupling_steps;i++)
{
nonzero[info.coupling_mag[i]]=1;
nonzero[info.coupling_ang[i]]=1;
int testM=info.coupling_mag[i]=opb.read(ilog2(vi.channels));
int testA=info.coupling_ang[i]=opb.read(ilog2(vi.channels));
if(testM<0 ||
testA<0 ||
testM==testA ||
testM>=vi.channels ||
testA>=vi.channels)
{
//goto err_out;
info.free();
return(null);
}
}
}
// recover the residue, apply directly to the spectral envelope
if(opb.read(2)>0)
{ /* 2,3:reserved */
//goto err_out;
info.free();
return(null);
}
if(info.submaps>1)
{
for(int i=0;i<vi.channels;i++)
{
info.chmuxlist[i]=opb.read(4);
if(info.chmuxlist[i]>=info.submaps)
{
//goto err_out;
info.free();
return(null);
}
}
}
for(int i=0;i<info.submaps;i++)
{
int ch_in_bundle=0;
for(int j=0;j<vi.channels;j++)
info.timesubmap[i]=opb.read(8);
if(info.timesubmap[i]>=vi.times)
{
if(info.chmuxlist[j]==i)
//goto err_out;
info.free();
return(null);
}
info.floorsubmap[i]=opb.read(8);
if(info.floorsubmap[i]>=vi.floors)
{
//goto err_out;
info.free();
return(null);
}
info.residuesubmap[i]=opb.read(8);
if(info.residuesubmap[i]>=vi.residues)
{
//goto err_out;
info.free();
return(null);
}
}
return info;
//err_out:
//free_info(info);
//return(NULL);
}
float[][] pcmbundle=null;
int[] zerobundle=null;
int[] nonzero=null;
Object[] floormemo=null;
override public int inverse(Block vb, Object l)
{
lock(this)
{
//System.err.println("Mapping0.inverse");
DspState vd=vb.vd;
Info vi=vd.vi;
LookMapping0 look=(LookMapping0)l;
InfoMapping0 info=look.map;
InfoMode mode=look.mode;
int n=vb.pcmend=vi.blocksizes[vb.W];
float[] window=vd.wnd[vb.W][vb.lW][vb.nW][mode.windowtype];
// float[][] pcmbundle=new float[vi.channels][];
// int[] nonzero=new int[vi.channels];
if(pcmbundle==null || pcmbundle.Length<vi.channels)
{
pcmbundle=new float[vi.channels][];
nonzero=new int[vi.channels];
zerobundle=new int[vi.channels];
floormemo=new Object[vi.channels];
}
// time domain information decode (note that applying the
// information would have to happen later; we'll probably add a
// function entry to the harness for that later
// NOT IMPLEMENTED
// recover the spectral envelope; store it in the PCM vector for now
for(int i=0;i<vi.channels;i++)
{
float[] pcm=vb.pcm[i];
int submap=info.chmuxlist[i];
floormemo[i]=look.floor_func[submap].inverse1(vb,look.
floor_look[submap],
floormemo[i]
);
if(floormemo[i]!=null){ nonzero[i]=1; }
else{ nonzero[i]=0; }
for(int j=0; j<n/2; j++)
{
if(nonzero[j]!=0)
{
zerobundle[ch_in_bundle]=1;
}
else
{
zerobundle[ch_in_bundle]=0;
}
pcmbundle[ch_in_bundle++]=vb.pcm[j];
pcm[j]=0;
}
//_analysis_output("ifloor",seq+i,pcm,n/2,0,1);
}
for(int i=0; i<info.coupling_steps; i++)
{
if(nonzero[info.coupling_mag[i]]!=0 ||
nonzero[info.coupling_ang[i]]!=0)
{
nonzero[info.coupling_mag[i]]=1;
nonzero[info.coupling_ang[i]]=1;
}
}
look.residue_func[i].inverse(vb,look.residue_look[i],
pcmbundle,zerobundle,ch_in_bundle);
}
// recover the residue, apply directly to the spectral envelope
for(int i=info.coupling_steps-1;i>=0;i--)
{
float[] pcmM=vb.pcm[info.coupling_mag[i]];
float[] pcmA=vb.pcm[info.coupling_ang[i]];
for(int j=0;j<n/2;j++)
for(int i=0;i<info.submaps;i++)
{
float mag=pcmM[j];
float ang=pcmA[j];
if(mag>0)
int ch_in_bundle=0;
for(int j=0;j<vi.channels;j++)
{
if(ang>0)
if(info.chmuxlist[j]==i)
{
pcmM[j]=mag;
pcmA[j]=mag-ang;
if(nonzero[j]!=0)
{
zerobundle[ch_in_bundle]=1;
}
else
{
zerobundle[ch_in_bundle]=0;
}
pcmbundle[ch_in_bundle++]=vb.pcm[j];
}
}
look.residue_func[i].inverse(vb,look.residue_look[i],
pcmbundle,zerobundle,ch_in_bundle);
}
for(int i=info.coupling_steps-1;i>=0;i--)
{
float[] pcmM=vb.pcm[info.coupling_mag[i]];
float[] pcmA=vb.pcm[info.coupling_ang[i]];
for(int j=0;j<n/2;j++)
{
float mag=pcmM[j];
float ang=pcmA[j];
if(mag>0)
{
if(ang>0)
{
pcmM[j]=mag;
pcmA[j]=mag-ang;
}
else
{
pcmA[j]=mag;
pcmM[j]=mag+ang;
}
}
else
{
pcmA[j]=mag;
pcmM[j]=mag+ang;
if(ang>0)
{
pcmM[j]=mag;
pcmA[j]=mag+ang;
}
else
{
pcmA[j]=mag;
pcmM[j]=mag-ang;
}
}
}
}
// /* compute and apply spectral envelope */
for(int i=0;i<vi.channels;i++)
{
float[] pcm=vb.pcm[i];
int submap=info.chmuxlist[i];
look.floor_func[submap].inverse2(vb,look.floor_look[submap],floormemo[i],pcm);
}
// transform the PCM data; takes PCM vector, vb; modifies PCM vector
// only MDCT right now....
for(int i=0;i<vi.channels;i++)
{
float[] pcm=vb.pcm[i];
//_analysis_output("out",seq+i,pcm,n/2,0,0);
((Mdct)vd.transform[vb.W][0]).backward(pcm,pcm);
}
// now apply the decoded pre-window time information
// NOT IMPLEMENTED
// window the data
for(int i=0;i<vi.channels;i++)
{
float[] pcm=vb.pcm[i];
if(nonzero[i]!=0)
{
for(int j=0;j<n;j++)
{
pcm[j]*=window[j];
}
}
else
{
if(ang>0)
for(int j=0;j<n;j++)
{
pcmM[j]=mag;
pcmA[j]=mag+ang;
}
else
{
pcmA[j]=mag;
pcmM[j]=mag-ang;
pcm[j]=0.0f;
}
}
//_analysis_output("final",seq++,pcm,n,0,0);
}
}
// /* compute and apply spectral envelope */
for(int i=0;i<vi.channels;i++)
{
float[] pcm=vb.pcm[i];
int submap=info.chmuxlist[i];
look.floor_func[submap].inverse2(vb,look.floor_look[submap],floormemo[i],pcm);
}
// transform the PCM data; takes PCM vector, vb; modifies PCM vector
// only MDCT right now....
for(int i=0;i<vi.channels;i++)
{
float[] pcm=vb.pcm[i];
//_analysis_output("out",seq+i,pcm,n/2,0,0);
((Mdct)vd.transform[vb.W][0]).backward(pcm,pcm);
}
// now apply the decoded pre-window time information
// NOT IMPLEMENTED
// window the data
for(int i=0;i<vi.channels;i++)
{
float[] pcm=vb.pcm[i];
if(nonzero[i]!=0)
{
for(int j=0;j<n;j++)
{
pcm[j]*=window[j];
}
}
else
{
for(int j=0;j<n;j++)
{
pcm[j]=0.f;
}
}
//_analysis_output("final",seq++,pcm,n,0,0);
}
// now apply the decoded post-window time information
// NOT IMPLEMENTED
// all done!
return(0);
}
}
private static int ilog2(int v)
{
int ret=0;
while(v>1)
{
ret++;
(uint)v >>= 1;
// now apply the decoded post-window time information
// NOT IMPLEMENTED
// all done!
return(0);
}
}
private static int ilog2(int v)
{
int ret=0;
while(v>1)
{
ret++;
v = (int)((uint)v >> 1);
}
return(ret);
}
return(ret);
}
}
class InfoMapping0
{
int submaps; // <= 16
int[] chmuxlist=new int[256]; // up to 256 channels in a Vorbis stream
int[] timesubmap=new int[16]; // [mux]
int[] floorsubmap=new int[16]; // [mux] submap to floors
int[] residuesubmap=new int[16];// [mux] submap to residue
int[] psysubmap=new int[16]; // [mux]; encode only
int coupling_steps;
int[] coupling_mag=new int[256];
int[] coupling_ang=new int[256];
void free()
class InfoMapping0
{
chmuxlist=null;
timesubmap=null;
floorsubmap=null;
residuesubmap=null;
psysubmap=null;
internal int submaps; // <= 16
internal int[] chmuxlist=new int[256]; // up to 256 channels in a Vorbis stream
internal int[] timesubmap=new int[16]; // [mux]
internal int[] floorsubmap=new int[16]; // [mux] submap to floors
internal int[] residuesubmap=new int[16];// [mux] submap to residue
internal int[] psysubmap=new int[16]; // [mux]; encode only
coupling_mag=null;
coupling_ang=null;
internal int coupling_steps;
internal int[] coupling_mag=new int[256];
internal int[] coupling_ang=new int[256];
internal void free()
{
chmuxlist=null;
timesubmap=null;
floorsubmap=null;
residuesubmap=null;
psysubmap=null;
coupling_mag=null;
coupling_ang=null;
}
}
}
class LookMapping0
{
InfoMode mode;
InfoMapping0 map;
Object[] time_look;
Object[] floor_look;
Object[] floor_state;
Object[] residue_look;
PsyLook[] psy_look;
class LookMapping0
{
internal InfoMode mode;
internal InfoMapping0 map;
internal Object[] time_look;
internal Object[] floor_look;
//Object[] floor_state;
internal Object[] residue_look;
//PsyLook[] psy_look;
FuncTime[] time_func;
FuncFloor[] floor_func;
FuncResidue[] residue_func;
internal FuncTime[] time_func;
internal FuncFloor[] floor_func;
internal FuncResidue[] residue_func;
int ch;
float[][] decay;
int lastframe; // if a different mode is called, we need to
// invalidate decay and floor state
}
internal int ch;
//float[][] decay;
//int lastframe; // if a different mode is called, we need to
// invalidate decay and floor state
}
}

Просмотреть файл

@ -26,246 +26,249 @@
using System;
using csogg;
class Mdct
namespace csvorbis
{
class Mdct
{
static private float cPI3_8=0.38268343236508977175f;
static private float cPI2_8=0.70710678118654752441f;
static private float cPI1_8=0.92387953251128675613f;
//static private float cPI3_8=0.38268343236508977175f;
//static private float cPI2_8=0.70710678118654752441f;
//static private float cPI1_8=0.92387953251128675613f;
int n;
int log2n;
int n;
int log2n;
float[] trig;
int[] bitrev;
float[] trig;
int[] bitrev;
float scale;
float scale;
void init(int n)
{
bitrev=new int[n/4];
trig=new float[n+n/4];
int n2=(uint)n >> 1;
log2n=(int)Math.rint(Math.log(n)/Math.log(2));
this.n=n;
int AE=0;
int AO=1;
int BE=AE+n/2;
int BO=BE+1;
int CE=BE+n/2;
int CO=CE+1;
// trig lookups...
for(int i=0;i<n/4;i++)
internal void init(int n)
{
trig[AE+i*2]=(float)Math.cos((Math.PI/n)*(4*i));
trig[AO+i*2]=(float)-Math.sin((Math.PI/n)*(4*i));
trig[BE+i*2]=(float)Math.cos((Math.PI/(2*n))*(2*i+1));
trig[BO+i*2]=(float)Math.sin((Math.PI/(2*n))*(2*i+1));
bitrev=new int[n/4];
trig=new float[n+n/4];
int n2=(int)((uint)n >> 1);
log2n=(int)Math.Round(Math.Log(n)/Math.Log(2));
this.n=n;
int AE=0;
int AO=1;
int BE=AE+n/2;
int BO=BE+1;
int CE=BE+n/2;
int CO=CE+1;
// trig lookups...
for(int i=0;i<n/4;i++)
{
trig[AE+i*2]=(float)Math.Cos((Math.PI/n)*(4*i));
trig[AO+i*2]=(float)-Math.Sin((Math.PI/n)*(4*i));
trig[BE+i*2]=(float)Math.Cos((Math.PI/(2*n))*(2*i+1));
trig[BO+i*2]=(float)Math.Sin((Math.PI/(2*n))*(2*i+1));
}
for(int i=0;i<n/8;i++)
{
trig[CE+i*2]=(float)Math.Cos((Math.PI/n)*(4*i+2));
trig[CO+i*2]=(float)-Math.Sin((Math.PI/n)*(4*i+2));
}
{
int mask=(1<<(log2n-1))-1;
int msb=1<<(log2n-2);
for(int i=0;i<n/8;i++)
{
int acc=0;
for(int j=0; (((uint)msb) >> j) != 0; j++)
if(((((uint)msb>>j))&i) != 0)
acc |= 1 << j;
bitrev[i*2]=((~acc)&mask);
// bitrev[i*2]=((~acc)&mask)-1;
bitrev[i*2+1]=acc;
}
}
for(int i=0;i<n/8;i++)
{
trig[CE+i*2]=(float)Math.cos((Math.PI/n)*(4*i+2));
trig[CO+i*2]=(float)-Math.sin((Math.PI/n)*(4*i+2));
scale=4.0f/n;
}
{
int mask=(1<<(log2n-1))-1;
int msb=1<<(log2n-2);
for(int i=0;i<n/8;i++)
internal void clear()
{
int acc=0;
for(int j=0; (((uint)msb) >> j) != 0; j++)
if(((((uint)msb>>j))&i) != 0)
acc |= 1 << j;
bitrev[i*2]=((~acc)&mask);
// bitrev[i*2]=((~acc)&mask)-1;
bitrev[i*2+1]=acc;
}
}
scale=4.f/n;
}
void clear()
{
}
void forward(float[] fin, float[] fout)
{
}
float[] _x=new float[1024];
float[] _w=new float[1024];
void backward(float[] fin, float[] fout)
{
lock(this)
{
if(_x.length < n/2){_x=new float[n/2];}
if(_w.length < n/2){_w=new float[n/2];}
float[] x=_x;
float[] w=_w;
int n2=(uint)n >> 1;
int n4=(uint)n >> 2;
int n8=(uint)n >> 3;
// rotate + step 1
internal void forward(float[] fin, float[] fout)
{
int inO=1;
int xO=0;
}
float[] _x=new float[1024];
float[] _w=new float[1024];
internal void backward(float[] fin, float[] fout)
{
lock(this)
{
if(_x.Length < n/2){_x=new float[n/2];}
if(_w.Length < n/2){_w=new float[n/2];}
float[] x=_x;
float[] w=_w;
int n2=(int)((uint)n >> 1);
int n4=(int)((uint)n >> 2);
int n8=(int)((uint)n >> 3);
// rotate + step 1
{
int inO=1;
int xO=0;
int A=n2;
int i;
for(i=0;i<n8;i++)
{
A-=2;
x[xO++]=-fin[inO+2]*trig[A+1] - fin[inO]*trig[A];
x[xO++]= fin[inO]*trig[A+1] - fin[inO+2]*trig[A];
inO+=4;
}
inO=n2-4;
for(i=0;i<n8;i++)
{
A-=2;
x[xO++]=fin[inO]*trig[A+1] + fin[inO+2]*trig[A];
x[xO++]=fin[inO]*trig[A] - fin[inO+2]*trig[A+1];
inO-=4;
}
}
float[] xxx=mdct_kernel(x,w,n,n2,n4,n8);
int xx=0;
// step 8
{
int B=n2;
int o1=n4,o2=o1-1;
int o3=n4+n2,o4=o3-1;
for(int i=0;i<n4;i++)
{
float temp1= (xxx[xx] * trig[B+1] - xxx[xx+1] * trig[B]);
float temp2=-(xxx[xx] * trig[B] + xxx[xx+1] * trig[B+1]);
fout[o1]=-temp1;
fout[o2]= temp1;
fout[o3]= temp2;
fout[o4]= temp2;
o1++;
o2--;
o3++;
o4--;
xx+=2;
B+=2;
}
}
}
}
internal float[] mdct_kernel(float[] x, float[] w,
int n, int n2, int n4, int n8)
{
// step 2
int xA=n4;
int xB=0;
int w2=n4;
int A=n2;
int i;
for(i=0;i<n8;i++)
for(int i=0;i<n4;)
{
A-=2;
x[xO++]=-fin[inO+2]*trig[A+1] - fin[inO]*trig[A];
x[xO++]= fin[inO]*trig[A+1] - fin[inO+2]*trig[A];
inO+=4;
float x0=x[xA] - x[xB];
float x1;
w[w2+i]=x[xA++]+x[xB++];
x1=x[xA]-x[xB];
A-=4;
w[i++]= x0 * trig[A] + x1 * trig[A+1];
w[i]= x1 * trig[A] - x0 * trig[A+1];
w[w2+i]=x[xA++]+x[xB++];
i++;
}
inO=n2-4;
for(i=0;i<n8;i++)
{
A-=2;
x[xO++]=fin[inO]*trig[A+1] + fin[inO+2]*trig[A];
x[xO++]=fin[inO]*trig[A] - fin[inO+2]*trig[A+1];
inO-=4;
}
}
float[] xxx=mdct_kernel(x,w,n,n2,n4,n8);
int xx=0;
// step 8
// step 3
{
int B=n2;
int o1=n4,o2=o1-1;
int o3=n4+n2,o4=o3-1;
for(int i=0;i<n4;i++)
for(int i=0;i<log2n-3;i++)
{
float temp1= (xxx[xx] * trig[B+1] - xxx[xx+1] * trig[B]);
float temp2=-(xxx[xx] * trig[B] + xxx[xx+1] * trig[B+1]);
fout[o1]=-temp1;
fout[o2]= temp1;
fout[o3]= temp2;
fout[o4]= temp2;
int k0=(int)((uint)n >> (i+2));
int k1=1 << (i+3);
int wbase=n2-2;
o1++;
o2--;
o3++;
o4--;
xx+=2;
B+=2;
}
}
}
}
private float[] mdct_kernel(float[] x, float[] w,
int n, int n2, int n4, int n8)
{
// step 2
A=0;
float[] temp;
int xA=n4;
int xB=0;
int w2=n4;
int A=n2;
for(int i=0;i<n4;)
{
float x0=x[xA] - x[xB];
float x1;
w[w2+i]=x[xA++]+x[xB++];
x1=x[xA]-x[xB];
A-=4;
w[i++]= x0 * trig[A] + x1 * trig[A+1];
w[i]= x1 * trig[A] - x0 * trig[A+1];
w[w2+i]=x[xA++]+x[xB++];
i++;
}
// step 3
{
for(int i=0;i<log2n-3;i++)
{
int k0=(uint)n >> (i+2);
int k1=1 << (i+3);
int wbase=n2-2;
A=0;
float[] temp;
for(int r=0; r<((uint)k0>>2); r++)
{
int w1=wbase;
w2=w1-(k0>>1);
float AEv= trig[A],wA;
float AOv= trig[A+1],wB;
wbase-=2;
k0++;
for(int s=0;s<(2<<i);s++)
for(int r=0; r<((uint)k0>>2); r++)
{
wB =w[w1] -w[w2];
x[w1] =w[w1] +w[w2];
int w1=wbase;
w2=w1-(k0>>1);
float AEv= trig[A],wA;
float AOv= trig[A+1],wB;
wbase-=2;
k0++;
for(int s=0;s<(2<<i);s++)
{
wB =w[w1] -w[w2];
x[w1] =w[w1] +w[w2];
wA =w[++w1] -w[++w2];
x[w1] =w[w1] +w[w2];
wA =w[++w1] -w[++w2];
x[w1] =w[w1] +w[w2];
x[w2] =wA*AEv - wB*AOv;
x[w2-1]=wB*AEv + wA*AOv;
x[w2] =wA*AEv - wB*AOv;
x[w2-1]=wB*AEv + wA*AOv;
w1-=k0;
w2-=k0;
w1-=k0;
w2-=k0;
}
k0--;
A+=k1;
}
k0--;
A+=k1;
temp=w;
w=x;
x=temp;
}
temp=w;
w=x;
x=temp;
}
}
// step 4, 5, 6, 7
{
int C=n;
int bit=0;
int x1=0;
int x2=n2-1;
for(int i=0;i<n8;i++)
// step 4, 5, 6, 7
{
int t1=bitrev[bit++];
int t2=bitrev[bit++];
int C=n;
int bit=0;
int x1=0;
int x2=n2-1;
float wA=w[t1]-w[t2+1];
float wB=w[t1-1]+w[t2];
float wC=w[t1]+w[t2+1];
float wD=w[t1-1]-w[t2];
for(int i=0;i<n8;i++)
{
int t1=bitrev[bit++];
int t2=bitrev[bit++];
float wACE=wA* trig[C];
float wBCE=wB* trig[C++];
float wACO=wA* trig[C];
float wBCO=wB* trig[C++];
float wA=w[t1]-w[t2+1];
float wB=w[t1-1]+w[t2];
float wC=w[t1]+w[t2+1];
float wD=w[t1-1]-w[t2];
float wACE=wA* trig[C];
float wBCE=wB* trig[C++];
float wACO=wA* trig[C];
float wBCO=wB* trig[C++];
x[x1++]=( wC+wACO+wBCE)*.5f;
x[x2--]=(-wD+wBCO-wACE)*.5f;
x[x1++]=( wD+wBCO-wACE)*.5f;
x[x2--]=( wC-wACO-wBCE)*.5f;
x[x1++]=( wC+wACO+wBCE)*.5f;
x[x2--]=(-wD+wBCO-wACE)*.5f;
x[x1++]=( wD+wBCO-wACE)*.5f;
x[x2--]=( wC-wACO-wBCE)*.5f;
}
}
return(x);
}
}
return(x);
}
}
}

Просмотреть файл

@ -26,49 +26,52 @@
using System;
using csogg;
// psychoacoustic setup
class PsyInfo
{
int athp;
int decayp;
int smoothp;
int noisefitp;
int noisefit_subblock;
float noisefit_threshdB;
namespace csvorbis
{
// psychoacoustic setup
class PsyInfo
{
//int athp;
//int decayp;
//int smoothp;
//int noisefitp;
//int noisefit_subblock;
//float noisefit_threshdB;
float ath_att;
//float ath_att;
int tonemaskp;
float[] toneatt_125Hz=new float[5];
float[] toneatt_250Hz=new float[5];
float[] toneatt_500Hz=new float[5];
float[] toneatt_1000Hz=new float[5];
float[] toneatt_2000Hz=new float[5];
float[] toneatt_4000Hz=new float[5];
float[] toneatt_8000Hz=new float[5];
//int tonemaskp;
float[] toneatt_125Hz=new float[5];
float[] toneatt_250Hz=new float[5];
float[] toneatt_500Hz=new float[5];
float[] toneatt_1000Hz=new float[5];
float[] toneatt_2000Hz=new float[5];
float[] toneatt_4000Hz=new float[5];
float[] toneatt_8000Hz=new float[5];
int peakattp;
float[] peakatt_125Hz=new float[5];
float[] peakatt_250Hz=new float[5];
float[] peakatt_500Hz=new float[5];
float[] peakatt_1000Hz=new float[5];
float[] peakatt_2000Hz=new float[5];
float[] peakatt_4000Hz=new float[5];
float[] peakatt_8000Hz=new float[5];
//int peakattp;
float[] peakatt_125Hz=new float[5];
float[] peakatt_250Hz=new float[5];
float[] peakatt_500Hz=new float[5];
float[] peakatt_1000Hz=new float[5];
float[] peakatt_2000Hz=new float[5];
float[] peakatt_4000Hz=new float[5];
float[] peakatt_8000Hz=new float[5];
int noisemaskp;
float[] noiseatt_125Hz=new float[5];
float[] noiseatt_250Hz=new float[5];
float[] noiseatt_500Hz=new float[5];
float[] noiseatt_1000Hz=new float[5];
float[] noiseatt_2000Hz=new float[5];
float[] noiseatt_4000Hz=new float[5];
float[] noiseatt_8000Hz=new float[5];
//int noisemaskp;
float[] noiseatt_125Hz=new float[5];
float[] noiseatt_250Hz=new float[5];
float[] noiseatt_500Hz=new float[5];
float[] noiseatt_1000Hz=new float[5];
float[] noiseatt_2000Hz=new float[5];
float[] noiseatt_4000Hz=new float[5];
float[] noiseatt_8000Hz=new float[5];
float max_curve_dB;
//float max_curve_dB;
float attack_coeff;
float decay_coeff;
//float attack_coeff;
//float decay_coeff;
void free(){}
}
internal void free(){}
}
}

Просмотреть файл

@ -26,19 +26,22 @@
using System;
using csogg;
class PsyLook
namespace csvorbis
{
int n;
PsyInfo vi;
float[][][] tonecurves;
float[][] peakatt;
float[][][] noisecurves;
float[] ath;
int[] octave;
void init(PsyInfo vi, int n, int rate)
class PsyLook
{
//int n;
//PsyInfo vi;
//float[][][] tonecurves;
//float[][] peakatt;
//float[][][] noisecurves;
//float[] ath;
//int[] octave;
void init(PsyInfo vi, int n, int rate)
{
}
}
}
}

Просмотреть файл

@ -24,350 +24,393 @@
*/
using System;
using System.Runtime.CompilerServices;
using csogg;
class Residue0 : FuncResidue{
void pack(Object vr, csBuffer opb){
InfoResidue0 info=(InfoResidue0)vr;
int acc=0;
opb.write(info.begin,24);
opb.write(info.end,24);
opb.write(info.grouping-1,24); /* residue vectors to group and
code with a partitioned book */
opb.write(info.partitions-1,6); /* possible partition choices */
opb.write(info.groupbook,8); /* group huffman book */
/* secondstages is a bitmask; as encoding progresses pass by pass, a
bitmask of one indicates this partition class has bits to write
this pass */
for(int j=0;j<info.partitions;j++){
if(ilog(info.secondstages[j])>3){
/* yes, this is a minor hack due to not thinking ahead */
opb.write(info.secondstages[j],3);
opb.write(1,1);
opb.write(info.secondstages[j] >> 3,5);
}
else{
opb.write(info.secondstages[j],4); /* trailing zero */
}
acc+=icount(info.secondstages[j]);
}
for(int j=0;j<acc;j++){
opb.write(info.booklist[j],8);
}
}
Object unpack(Info vi, csBuffer opb){
int acc=0;
InfoResidue0 info=new InfoResidue0();
info.begin=opb.read(24);
info.end=opb.read(24);
info.grouping=opb.read(24)+1;
info.partitions=opb.read(6)+1;
info.groupbook=opb.read(8);
for(int j=0;j<info.partitions;j++){
int cascade=opb.read(3);
if(opb.read(1)!=0){
cascade|=(opb.read(5)<<3);
}
info.secondstages[j]=cascade;
acc+=icount(cascade);
}
for(int j=0;j<acc;j++){
info.booklist[j]=opb.read(8);
// if(info.booklist[j]==255)info.booklist[j]=-1;
}
if(info.groupbook>=vi.books){
free_info(info);
return(null);
}
for(int j=0;j<acc;j++){
if(info.booklist[j]>=vi.books){
free_info(info);
return(null);
}
}
return(info);
// errout:
// free_info(info);
// return(NULL);
}
Object look(DspState vd, InfoMode vm, Object vr){
InfoResidue0 info=(InfoResidue0)vr;
LookResidue0 look=new LookResidue0();
int acc=0;
int dim;
int maxstage=0;
look.info=info;
look.map=vm.mapping;
look.parts=info.partitions;
look.fullbooks=vd.fullbooks;
look.phrasebook=vd.fullbooks[info.groupbook];
dim=look.phrasebook.dim;
look.partbooks=new int[look.parts][];
for(int j=0;j<look.parts;j++){
int stages=ilog(info.secondstages[j]);
if(stages!=0){
if(stages>maxstage)maxstage=stages;
look.partbooks[j]=new int[stages];
for(int k=0; k<stages; k++){
if((info.secondstages[j]&(1<<k))!=0){
look.partbooks[j][k]=info.booklist[acc++];
}
}
}
}
look.partvals=(int)Math.rint(Math.pow(look.parts,dim));
look.stages=maxstage;
look.decodemap=new int[look.partvals][];
for(int j=0;j<look.partvals;j++){
int val=j;
int mult=look.partvals/look.parts;
look.decodemap[j]=new int[dim];
for(int k=0;k<dim;k++){
int deco=val/mult;
val-=deco*mult;
mult/=look.parts;
look.decodemap[j][k]=deco;
}
}
return(look);
}
void free_info(Object i){}
void free_look(Object i){}
int forward(Block vb,Object vl, float[][] fin, int ch){
System.err.println("Residue0.forward: not implemented");
return 0;
}
static int[][][] partword=new int[2][][]; // _01inverse is synchronized for
// re-using partword
static int _01inverse(Block vb, Object vl, float[][] fin, int ch, int decodepart)
namespace csvorbis
{
class Residue0 : FuncResidue
{
lock(this)
{
int i,j,k,l,s;
LookResidue0 look=(LookResidue0 )vl;
InfoResidue0 info=look.info;
override public void pack(Object vr, csBuffer opb)
{
InfoResidue0 info=(InfoResidue0)vr;
int acc=0;
opb.write(info.begin,24);
opb.write(info.end,24);
// move all this setup out later
int samples_per_partition=info.grouping;
int partitions_per_word=look.phrasebook.dim;
int n=info.end-info.begin;
opb.write(info.grouping-1,24); /* residue vectors to group and
code with a partitioned book */
opb.write(info.partitions-1,6); /* possible partition choices */
opb.write(info.groupbook,8); /* group huffman book */
/* secondstages is a bitmask; as encoding progresses pass by pass, a
bitmask of one indicates this partition class has bits to write
this pass */
for(int j=0;j<info.partitions;j++)
{
if(ilog(info.secondstages[j])>3)
{
/* yes, this is a minor hack due to not thinking ahead */
opb.write(info.secondstages[j],3);
opb.write(1,1);
opb.write(info.secondstages[j] >> 3,5);
}
else
{
opb.write(info.secondstages[j],4); /* trailing zero */
}
acc+=icount(info.secondstages[j]);
}
for(int j=0;j<acc;j++)
{
opb.write(info.booklist[j],8);
}
}
override public Object unpack(Info vi, csBuffer opb)
{
int acc=0;
InfoResidue0 info=new InfoResidue0();
info.begin=opb.read(24);
info.end=opb.read(24);
info.grouping=opb.read(24)+1;
info.partitions=opb.read(6)+1;
info.groupbook=opb.read(8);
for(int j=0;j<info.partitions;j++)
{
int cascade=opb.read(3);
if(opb.read(1)!=0)
{
cascade|=(opb.read(5)<<3);
}
info.secondstages[j]=cascade;
acc+=icount(cascade);
}
for(int j=0;j<acc;j++)
{
info.booklist[j]=opb.read(8);
// if(info.booklist[j]==255)info.booklist[j]=-1;
}
if(info.groupbook>=vi.books)
{
free_info(info);
return(null);
}
for(int j=0;j<acc;j++)
{
if(info.booklist[j]>=vi.books)
{
free_info(info);
return(null);
}
}
return(info);
// errout:
// free_info(info);
// return(NULL);
}
override public Object look(DspState vd, InfoMode vm, Object vr)
{
InfoResidue0 info=(InfoResidue0)vr;
LookResidue0 look=new LookResidue0();
int acc=0;
int dim;
int maxstage=0;
look.info=info;
look.map=vm.mapping;
look.parts=info.partitions;
look.fullbooks=vd.fullbooks;
look.phrasebook=vd.fullbooks[info.groupbook];
dim=look.phrasebook.dim;
look.partbooks=new int[look.parts][];
for(int j=0;j<look.parts;j++)
{
int stages=ilog(info.secondstages[j]);
if(stages!=0)
{
if(stages>maxstage)maxstage=stages;
look.partbooks[j]=new int[stages];
for(int k=0; k<stages; k++)
{
if((info.secondstages[j]&(1<<k))!=0)
{
look.partbooks[j][k]=info.booklist[acc++];
}
}
}
}
look.partvals=(int)Math.Round(Math.Pow(look.parts,dim));
look.stages=maxstage;
look.decodemap=new int[look.partvals][];
for(int j=0;j<look.partvals;j++)
{
int val=j;
int mult=look.partvals/look.parts;
look.decodemap[j]=new int[dim];
for(int k=0;k<dim;k++)
{
int deco=val/mult;
val-=deco*mult;
mult/=look.parts;
look.decodemap[j][k]=deco;
}
}
return(look);
}
override public void free_info(Object i){}
override public void free_look(Object i){}
override public int forward(Block vb,Object vl, float[][] fin, int ch)
{
return 0;
}
static int[][][] partword=new int[2][][]; // _01inverse is synchronized for
// re-using partword
[MethodImpl(MethodImplOptions.Synchronized)]
internal static int _01inverse(Block vb, Object vl, float[][] fin, int ch, int decodepart)
{
{
int i,j,k,l,s;
LookResidue0 look=(LookResidue0 )vl;
InfoResidue0 info=look.info;
// move all this setup out later
int samples_per_partition=info.grouping;
int partitions_per_word=look.phrasebook.dim;
int n=info.end-info.begin;
int partvals=n/samples_per_partition;
int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
int partvals=n/samples_per_partition;
int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
if(partword.length<ch)
{
partword=new int[ch][][];
for(j=0;j<ch;j++)
{
partword[j]=new int[partwords][];
}
}
else
{
for(j=0;j<ch;j++)
{
if(partword[j]==null || partword[j].length<partwords)
partword[j]=new int[partwords][];
}
}
if(partword.Length<ch)
{
partword=new int[ch][][];
for(j=0;j<ch;j++)
{
partword[j]=new int[partwords][];
}
}
else
{
for(j=0;j<ch;j++)
{
if(partword[j]==null || partword[j].Length<partwords)
partword[j]=new int[partwords][];
}
}
for(s=0;s<look.stages;s++)
{
// each loop decodes on partition codeword containing
// partitions_pre_word partitions
for(i=0,l=0;i<partvals;l++)
{
if(s==0)
{
// fetch the partition word for each channel
for(j=0;j<ch;j++)
{
int temp=look.phrasebook.decode(vb.opb);
if(temp==-1)
{
//goto eopbreak;
return(0);
}
partword[j][l]=look.decodemap[temp];
if(partword[j][l]==null)
{
// goto errout;
return(0);
}
}
}
for(s=0;s<look.stages;s++)
{
// each loop decodes on partition codeword containing
// partitions_pre_word partitions
for(i=0,l=0;i<partvals;l++)
{
if(s==0)
{
// fetch the partition word for each channel
for(j=0;j<ch;j++)
{
int temp=look.phrasebook.decode(vb.opb);
if(temp==-1)
{
//goto eopbreak;
return(0);
}
partword[j][l]=look.decodemap[temp];
if(partword[j][l]==null)
{
// goto errout;
return(0);
}
}
}
// now we decode residual values for the partitions
for(k=0;k<partitions_per_word && i<partvals;k++,i++)
for(j=0;j<ch;j++)
{
int offset=info.begin+i*samples_per_partition;
if((info.secondstages[partword[j][l][k]]&(1<<s))!=0)
{
CodeBook stagebook=look.fullbooks[look.partbooks[partword[j][l][k]][s]];
// CodeBook stagebook=look.partbooks[partword[j][l][k]][s];
if(stagebook!=null)
{
if(decodepart==0)
{
if(stagebook.decodevs_add(fin[j],offset,vb.opb,samples_per_partition)==-1)
{
// goto errout;
return(0);
}
}
else if(decodepart==1)
{
if(stagebook.decodev_add(fin[j], offset, vb.opb,samples_per_partition)==-1)
{
// goto errout;
return(0);
}
}
}
}
}
}
}
return(0);
}
}
// now we decode residual values for the partitions
for(k=0;k<partitions_per_word && i<partvals;k++,i++)
for(j=0;j<ch;j++)
{
int offset=info.begin+i*samples_per_partition;
if((info.secondstages[partword[j][l][k]]&(1<<s))!=0)
{
CodeBook stagebook=look.fullbooks[look.partbooks[partword[j][l][k]][s]];
// CodeBook stagebook=look.partbooks[partword[j][l][k]][s];
if(stagebook!=null)
{
if(decodepart==0)
{
if(stagebook.decodevs_add(fin[j],offset,vb.opb,samples_per_partition)==-1)
{
// goto errout;
return(0);
}
}
else if(decodepart==1)
{
if(stagebook.decodev_add(fin[j], offset, vb.opb,samples_per_partition)==-1)
{
// goto errout;
return(0);
}
}
}
}
}
}
}
return(0);
}
}
static int _2inverse(Block vb, Object vl, float[][] fin, int ch){
int i,j,k,l,s;
LookResidue0 look=(LookResidue0 )vl;
InfoResidue0 info=look.info;
internal static int _2inverse(Block vb, Object vl, float[][] fin, int ch)
{
int i,k,l,s;
LookResidue0 look=(LookResidue0 )vl;
InfoResidue0 info=look.info;
// move all this setup out later
int samples_per_partition=info.grouping;
int partitions_per_word=look.phrasebook.dim;
int n=info.end-info.begin;
// move all this setup out later
int samples_per_partition=info.grouping;
int partitions_per_word=look.phrasebook.dim;
int n=info.end-info.begin;
int partvals=n/samples_per_partition;
int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
int partvals=n/samples_per_partition;
int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
int[][] partword=new int[partwords][];
for(s=0;s<look.stages;s++){
for(i=0,l=0;i<partvals;l++){
if(s==0){
// fetch the partition word for each channel
int temp=look.phrasebook.decode(vb.opb);
if(temp==-1){
// goto eopbreak;
return(0);
}
partword[l]=look.decodemap[temp];
if(partword[l]==null){
// goto errout;
return(0);
}
int[][] partword=new int[partwords][];
for(s=0;s<look.stages;s++)
{
for(i=0,l=0;i<partvals;l++)
{
if(s==0)
{
// fetch the partition word for each channel
int temp=look.phrasebook.decode(vb.opb);
if(temp==-1)
{
// goto eopbreak;
return(0);
}
partword[l]=look.decodemap[temp];
if(partword[l]==null)
{
// goto errout;
return(0);
}
}
// now we decode residual values for the partitions
for(k=0;k<partitions_per_word && i<partvals;k++,i++)
{
int offset=info.begin+i*samples_per_partition;
if((info.secondstages[partword[l][k]]&(1<<s))!=0)
{
CodeBook stagebook=look.fullbooks[look.partbooks[partword[l][k]][s]];
if(stagebook!=null)
{
if(stagebook.decodevv_add(fin, offset, ch, vb.opb,samples_per_partition)==-1)
{
// goto errout;
return(0);
}
}
}
}
}
}
// errout:
// eopbreak:
return(0);
}
override public int inverse(Block vb, Object vl, float[][] fin, int[] nonzero, int ch)
{
//System.err.println("Residue0.inverse");
int used=0;
for(int i=0;i<ch;i++)
{
if(nonzero[i]!=0)
{
fin[used++]=fin[i];
}
}
if(used!=0)
return(_01inverse(vb, vl, fin, used, 0));
else
return(0);
}
internal static int ilog(int v)
{
int ret=0;
while(v!=0)
{
ret++;
v = (int)((uint)v >> 1);
}
return(ret);
}
internal static int icount(int v)
{
int ret=0;
while(v!=0)
{
ret+=(v&1);
v = (int)((uint)v >> 1);
}
return(ret);
}
}
// now we decode residual values for the partitions
for(k=0;k<partitions_per_word && i<partvals;k++,i++){
int offset=info.begin+i*samples_per_partition;
if((info.secondstages[partword[l][k]]&(1<<s))!=0){
CodeBook stagebook=look.fullbooks[look.partbooks[partword[l][k]][s]];
if(stagebook!=null){
if(stagebook.decodevv_add(fin, offset, ch, vb.opb,samples_per_partition)==-1){
// goto errout;
return(0);
}
}
}
}
}
}
// errout:
// eopbreak:
return(0);
}
int inverse(Block vb, Object vl, float[][] fin, int[] nonzero, int ch){
//System.err.println("Residue0.inverse");
int used=0;
for(int i=0;i<ch;i++){
if(nonzero[i]!=0){
fin[used++]=fin[i];
}
}
if(used!=0)
return(_01inverse(vb, vl, fin, used, 0));
else
return(0);
}
private static int ilog(int v){
int ret=0;
while(v!=0){
ret++;
(uint)v >>= 1;
}
return(ret);
}
private static int icount(int v){
int ret=0;
while(v!=0){
ret+=(v&1);
(uint)v >>= 1;
}
return(ret);
}
}
class LookResidue0 {
InfoResidue0 info;
int map;
class LookResidue0
{
internal InfoResidue0 info;
internal int map;
int parts;
int stages;
CodeBook[] fullbooks;
CodeBook phrasebook;
int[][] partbooks;
// CodeBook[][] partbooks;
internal int parts;
internal int stages;
internal CodeBook[] fullbooks;
internal CodeBook phrasebook;
internal int[][] partbooks;
// CodeBook[][] partbooks;
int partvals;
int[][] decodemap;
internal int partvals;
internal int[][] decodemap;
int postbits;
int phrasebits;
// int[][] frames;
int frames;
}
//internal int postbits;
//internal int phrasebits;
// int[][] frames;
//internal int frames;
}
class InfoResidue0{
// block-partitioned VQ coded straight residue
int begin;
int end;
class InfoResidue0
{
// block-partitioned VQ coded straight residue
internal int begin;
internal int end;
// first stage (lossless partitioning)
int grouping; // group n vectors per partition
int partitions; // possible codebooks for a partition
int groupbook; // huffbook for partitioning
int[] secondstages=new int[64]; // expanded out to pointers in lookup
int[] booklist=new int[256]; // list of second stage books
// first stage (lossless partitioning)
internal int grouping; // group n vectors per partition
internal int partitions; // possible codebooks for a partition
internal int groupbook; // huffbook for partitioning
internal int[] secondstages=new int[64]; // expanded out to pointers in lookup
internal int[] booklist=new int[256]; // list of second stage books
// encode-only heuristic settings
float[] entmax=new float[64]; // book entropy threshholds
float[] ampmax=new float[64]; // book amp threshholds
int[] subgrp=new int[64]; // book heuristic subgroup size
int[] blimit=new int[64]; // subgroup position limits
}
// encode-only heuristic settings
internal float[] entmax=new float[64]; // book entropy threshholds
internal float[] ampmax=new float[64]; // book amp threshholds
internal int[] subgrp=new int[64]; // book heuristic subgroup size
internal int[] blimit=new int[64]; // subgroup position limits
}
}

Просмотреть файл

@ -26,25 +26,34 @@
using System;
using csogg;
class Residue1 : Residue0{
int forward(Block vb,Object vl, float[][] fin, int ch){
System.err.println("Residue0.forward: not implemented");
return 0;
}
namespace csvorbis
{
class Residue1 : Residue0
{
new int forward(Block vb,Object vl, float[][] fin, int ch)
{
return 0;
}
int inverse(Block vb, Object vl, float[][] fin, int[] nonzero, int ch){
//System.err.println("Residue0.inverse");
int used=0;
for(int i=0; i<ch; i++){
if(nonzero[i]!=0){
fin[used++]=fin[i];
}
}
if(used!=0){
return(_01inverse(vb, vl, fin, used, 1));
}
else{
return 0;
}
}
}
override public int inverse(Block vb, Object vl, float[][] fin, int[] nonzero, int ch)
{
//System.err.println("Residue0.inverse");
int used=0;
for(int i=0; i<ch; i++)
{
if(nonzero[i]!=0)
{
fin[used++]=fin[i];
}
}
if(used!=0)
{
return(_01inverse(vb, vl, fin, used, 1));
}
else
{
return 0;
}
}
}
}

Просмотреть файл

@ -26,21 +26,23 @@
using System;
using csogg;
class Residue2 : Residue0
namespace csvorbis
{
int forward(Block vb,Object vl, float[][] fin, int ch)
class Residue2 : Residue0
{
System.err.println("Residue0.forward: not implemented");
return 0;
}
override public int forward(Block vb,Object vl, float[][] fin, int ch)
{
return 0;
}
int inverse(Block vb, Object vl, float[][] fin, int[] nonzero, int ch)
{
//System.err.println("Residue0.inverse");
int i=0;
for(i=0;i<ch;i++)if(nonzero[i]!=0)break;
if(i==ch)return(0); /* no nonzero vectors */
override public int inverse(Block vb, Object vl, float[][] fin, int[] nonzero, int ch)
{
//System.err.println("Residue0.inverse");
int i=0;
for(i=0;i<ch;i++)if(nonzero[i]!=0)break;
if(i==ch)return(0); /* no nonzero vectors */
return(_2inverse(vb, vl, fin, ch));
return(_2inverse(vb, vl, fin, ch));
}
}
}
}

Просмотреть файл

@ -26,512 +26,517 @@
using System;
using csogg;
class StaticCodeBook
namespace csvorbis
{
int dim; // codebook dimensions (elements per vector)
int entries; // codebook entries
int[] lengthlist; // codeword lengths in bits
// mapping
int maptype; // 0=none
// 1=implicitly populated values from map column
// 2=listed arbitrary values
// The below does a linear, single monotonic sequence mapping.
int q_min; // packed 32 bit float; quant value 0 maps to minval
int q_delta; // packed 32 bit float; val 1 - val 0 == delta
int q_quant; // bits: 0 < quant <= 16
int q_sequencep; // bitflag
// additional information for log (dB) mapping; the linear mapping
// is assumed to actually be values in dB. encodebias is used to
// assign an error weight to 0 dB. We have two additional flags:
// zeroflag indicates if entry zero is to represent -Inf dB; negflag
// indicates if we're to represent negative linear values in a
// mirror of the positive mapping.
int[] quantlist; // map == 1: (int)(entries/dim) element column map
// map == 2: list of dim*entries quantized entry vals
// encode helpers
EncodeAuxNearestMatch nearest_tree;
EncodeAuxThreshMatch thresh_tree;
StaticCodeBook(){}
StaticCodeBook(int dim, int entries, int[] lengthlist,
int maptype, int q_min, int q_delta,
int q_quant, int q_sequencep, int[] quantlist,
//EncodeAuxNearestmatch nearest_tree,
Object nearest_tree,
// EncodeAuxThreshmatch thresh_tree,
Object thresh_tree
)
class StaticCodeBook
{
this();
this.dim=dim; this.entries=entries; this.lengthlist=lengthlist;
this.maptype=maptype; this.q_min=q_min; this.q_delta=q_delta;
this.q_quant=q_quant; this.q_sequencep=q_sequencep;
this.quantlist=quantlist;
}
internal int dim; // codebook dimensions (elements per vector)
internal int entries; // codebook entries
internal int[] lengthlist; // codeword lengths in bits
int pack(csBuffer opb)
{
int i;
boolean ordered=false;
// mapping
internal int maptype; // 0=none
// 1=implicitly populated values from map column
// 2=listed arbitrary values
opb.write(0x564342,24);
opb.write(dim, 16);
opb.write(entries, 24);
// The below does a linear, single monotonic sequence mapping.
internal int q_min; // packed 32 bit float; quant value 0 maps to minval
internal int q_delta; // packed 32 bit float; val 1 - val 0 == delta
internal int q_quant; // bits: 0 < quant <= 16
internal int q_sequencep; // bitflag
// pack the codewords. There are two packings; length ordered and
// length random. Decide between the two now.
for(i=1;i<entries;i++)
// additional information for log (dB) mapping; the linear mapping
// is assumed to actually be values in dB. encodebias is used to
// assign an error weight to 0 dB. We have two additional flags:
// zeroflag indicates if entry zero is to represent -Inf dB; negflag
// indicates if we're to represent negative linear values in a
// mirror of the positive mapping.
internal int[] quantlist; // map == 1: (int)(entries/dim) element column map
// map == 2: list of dim*entries quantized entry vals
// encode helpers
internal EncodeAuxNearestMatch nearest_tree;
internal EncodeAuxThreshMatch thresh_tree;
internal StaticCodeBook(){}
internal StaticCodeBook(int dim, int entries, int[] lengthlist,
int maptype, int q_min, int q_delta,
int q_quant, int q_sequencep, int[] quantlist,
//EncodeAuxNearestmatch nearest_tree,
Object nearest_tree,
// EncodeAuxThreshmatch thresh_tree,
Object thresh_tree
) : this()
{
if(lengthlist[i]<lengthlist[i-1])break;
this.dim=dim; this.entries=entries; this.lengthlist=lengthlist;
this.maptype=maptype; this.q_min=q_min; this.q_delta=q_delta;
this.q_quant=q_quant; this.q_sequencep=q_sequencep;
this.quantlist=quantlist;
}
if(i==entries)ordered=true;
if(ordered)
internal int pack(csBuffer opb)
{
// length ordered. We only need to say how many codewords of
// each length. The actual codewords are generated
// deterministically
int i;
bool ordered=false;
int count=0;
opb.write(1,1); // ordered
opb.write(lengthlist[0]-1,5); // 1 to 32
opb.write(0x564342,24);
opb.write(dim, 16);
opb.write(entries, 24);
// pack the codewords. There are two packings; length ordered and
// length random. Decide between the two now.
for(i=1;i<entries;i++)
{
int _this=lengthlist[i];
int _last=lengthlist[i-1];
if(_this>_last)
if(lengthlist[i]<lengthlist[i-1])break;
}
if(i==entries)ordered=true;
if(ordered)
{
// length ordered. We only need to say how many codewords of
// each length. The actual codewords are generated
// deterministically
int count=0;
opb.write(1,1); // ordered
opb.write(lengthlist[0]-1,5); // 1 to 32
for(i=1;i<entries;i++)
{
for(int j=_last;j<_this;j++)
int _this=lengthlist[i];
int _last=lengthlist[i-1];
if(_this>_last)
{
opb.write(i-count,ilog(entries-count));
count=i;
for(int j=_last;j<_this;j++)
{
opb.write(i-count,ilog(entries-count));
count=i;
}
}
}
}
opb.write(i-count,ilog(entries-count));
}
else
{
// length random. Again, we don't code the codeword itself, just
// the length. This time, though, we have to encode each length
opb.write(0,1); // unordered
// algortihmic mapping has use for 'unused entries', which we tag
// here. The algorithmic mapping happens as usual, but the unused
// entry has no codeword.
for(i=0;i<entries;i++)
{
if(lengthlist[i]==0)break;
}
if(i==entries)
{
opb.write(0,1); // no unused entries
for(i=0;i<entries;i++)
{
opb.write(lengthlist[i]-1,5);
}
opb.write(i-count,ilog(entries-count));
}
else
{
opb.write(1,1); // we have unused entries; thus we tag
// length random. Again, we don't code the codeword itself, just
// the length. This time, though, we have to encode each length
opb.write(0,1); // unordered
// algortihmic mapping has use for 'unused entries', which we tag
// here. The algorithmic mapping happens as usual, but the unused
// entry has no codeword.
for(i=0;i<entries;i++)
{
if(lengthlist[i]==0)
if(lengthlist[i]==0)break;
}
if(i==entries)
{
opb.write(0,1); // no unused entries
for(i=0;i<entries;i++)
{
opb.write(0,1);
}
else
{
opb.write(1,1);
opb.write(lengthlist[i]-1,5);
}
}
}
}
// is the entry number the desired return value, or do we have a
// mapping? If we have a mapping, what type?
opb.write(maptype,4);
switch(maptype)
{
case 0:
// no mapping
break;
case 1:
case 2:
// implicitly populated value mapping
// explicitly populated value mapping
if(quantlist==null)
else
{
// no quantlist? error
return(-1);
}
// values that define the dequantization
opb.write(q_min,32);
opb.write(q_delta,32);
opb.write(q_quant-1,4);
opb.write(q_sequencep,1);
{
int quantvals=0;
switch(maptype)
{
case 1:
// a single column of (c->entries/c->dim) quantized values for
// building a full value list algorithmically (square lattice)
quantvals=maptype1_quantvals();
break;
case 2:
// every value (c->entries*c->dim total) specified explicitly
quantvals=entries*dim;
break;
}
// quantized values
for(i=0;i<quantvals;i++)
{
opb.write(Math.abs(quantlist[i]),q_quant);
}
}
break;
default:
// error case; we don't have any other map types now
return(-1);
}
return(0);
}
/*
*/
// unpacks a codebook from the packet buffer into the codebook struct,
// readies the codebook auxiliary structures for decode
int unpack(csBuffer opb)
{
int i;
//memset(s,0,sizeof(static_codebook));
// make sure alignment is correct
if(opb.read(24)!=0x564342)
{
// goto _eofout;
clear();
return(-1);
}
// first the basic parameters
dim=opb.read(16);
entries=opb.read(24);
if(entries==-1)
{
// goto _eofout;
clear();
return(-1);
}
// codeword ordering.... length ordered or unordered?
switch(opb.read(1))
{
case 0:
// unordered
lengthlist=new int[entries];
// allocated but unused entries?
if(opb.read(1)!=0)
{
// yes, unused entries
opb.write(1,1); // we have unused entries; thus we tag
for(i=0;i<entries;i++)
{
if(opb.read(1)!=0)
if(lengthlist[i]==0)
{
opb.write(0,1);
}
else
{
opb.write(1,1);
opb.write(lengthlist[i]-1,5);
}
}
}
}
// is the entry number the desired return value, or do we have a
// mapping? If we have a mapping, what type?
opb.write(maptype,4);
switch(maptype)
{
case 0:
// no mapping
break;
case 1:
case 2:
// implicitly populated value mapping
// explicitly populated value mapping
if(quantlist==null)
{
// no quantlist? error
return(-1);
}
// values that define the dequantization
opb.write(q_min,32);
opb.write(q_delta,32);
opb.write(q_quant-1,4);
opb.write(q_sequencep,1);
{
int quantvals=0;
switch(maptype)
{
case 1:
// a single column of (c->entries/c->dim) quantized values for
// building a full value list algorithmically (square lattice)
quantvals=maptype1_quantvals();
break;
case 2:
// every value (c->entries*c->dim total) specified explicitly
quantvals=entries*dim;
break;
}
// quantized values
for(i=0;i<quantvals;i++)
{
opb.write(Math.Abs(quantlist[i]),q_quant);
}
}
break;
default:
// error case; we don't have any other map types now
return(-1);
}
return(0);
}
/*
*/
// unpacks a codebook from the packet buffer into the codebook struct,
// readies the codebook auxiliary structures for decode
internal int unpack(csBuffer opb)
{
int i;
//memset(s,0,sizeof(static_codebook));
// make sure alignment is correct
if(opb.read(24)!=0x564342)
{
// goto _eofout;
clear();
return(-1);
}
// first the basic parameters
dim=opb.read(16);
entries=opb.read(24);
if(entries==-1)
{
// goto _eofout;
clear();
return(-1);
}
// codeword ordering.... length ordered or unordered?
switch(opb.read(1))
{
case 0:
// unordered
lengthlist=new int[entries];
// allocated but unused entries?
if(opb.read(1)!=0)
{
// yes, unused entries
for(i=0;i<entries;i++)
{
if(opb.read(1)!=0)
{
int num=opb.read(5);
if(num==-1)
{
// goto _eofout;
clear();
return(-1);
}
lengthlist[i]=num+1;
}
else
{
lengthlist[i]=0;
}
}
}
else
{
// all entries used; no tagging
for(i=0;i<entries;i++)
{
int num=opb.read(5);
if(num==-1)
{
// goto _eofout;
// goto _eofout;
clear();
return(-1);
}
lengthlist[i]=num+1;
}
else
{
lengthlist[i]=0;
}
}
}
else
break;
case 1:
// ordered
{
// all entries used; no tagging
for(i=0;i<entries;i++)
int length=opb.read(5)+1;
lengthlist=new int[entries];
for(i=0;i<entries;)
{
int num=opb.read(5);
int num=opb.read(ilog(entries-i));
if(num==-1)
{
// goto _eofout;
clear();
return(-1);
}
lengthlist[i]=num+1;
for(int j=0;j<num;j++,i++)
{
lengthlist[i]=length;
}
length++;
}
}
break;
case 1:
// ordered
break;
default:
// EOF
return(-1);
}
// Do we have a mapping to unpack?
switch((maptype=opb.read(4)))
{
int length=opb.read(5)+1;
lengthlist=new int[entries];
case 0:
// no mapping
break;
case 1:
case 2:
// implicitly populated value mapping
// explicitly populated value mapping
q_min=opb.read(32);
q_delta=opb.read(32);
q_quant=opb.read(4)+1;
q_sequencep=opb.read(1);
for(i=0;i<entries;)
{
int num=opb.read(ilog(entries-i));
if(num==-1)
int quantvals=0;
switch(maptype)
{
// goto _eofout;
case 1:
quantvals=maptype1_quantvals();
break;
case 2:
quantvals=entries*dim;
break;
}
// quantized values
quantlist=new int[quantvals];
for(i=0;i<quantvals;i++)
{
quantlist[i]=opb.read(q_quant);
}
if(quantlist[quantvals-1]==-1)
{
// goto _eofout;
clear();
return(-1);
}
for(int j=0;j<num;j++,i++)
{
lengthlist[i]=length;
}
length++;
}
break;
default:
// goto _eofout;
clear();
return(-1);
}
// all set
return(0);
// _errout:
// _eofout:
// vorbis_staticbook_clear(s);
// return(-1);
}
// there might be a straightforward one-line way to do the below
// that's portable and totally safe against roundoff, but I haven't
// thought of it. Therefore, we opt on the side of caution
internal int maptype1_quantvals()
{
int vals=(int)(Math.Floor(Math.Pow(entries,1.0/dim)));
// the above *should* be reliable, but we'll not assume that FP is
// ever reliable when bitstream sync is at stake; verify via integer
// means that vals really is the greatest value of dim for which
// vals^b->bim <= b->entries
// treat the above as an initial guess
while(true)
{
int acc=1;
int acc1=1;
for(int i=0;i<dim;i++)
{
acc*=vals;
acc1*=vals+1;
}
if(acc<=entries && acc1>entries){ return(vals); }
else
{
if(acc>entries){ vals--; }
else{ vals++; }
}
}
break;
default:
// EOF
return(-1);
}
// Do we have a mapping to unpack?
switch((maptype=opb.read(4)))
internal void clear()
{
case 0:
// no mapping
break;
case 1:
case 2:
// implicitly populated value mapping
// explicitly populated value mapping
q_min=opb.read(32);
q_delta=opb.read(32);
q_quant=opb.read(4)+1;
q_sequencep=opb.read(1);
// if(quantlist!=null)free(b->quantlist);
// if(lengthlist!=null)free(b->lengthlist);
// if(nearest_tree!=null){
// free(b->nearest_tree->ptr0);
// free(b->nearest_tree->ptr1);
// free(b->nearest_tree->p);
// free(b->nearest_tree->q);
// memset(b->nearest_tree,0,sizeof(encode_aux_nearestmatch));
// free(b->nearest_tree);
// }
// if(thresh_tree!=null){
// free(b->thresh_tree->quantthresh);
// free(b->thresh_tree->quantmap);
// memset(b->thresh_tree,0,sizeof(encode_aux_threshmatch));
// free(b->thresh_tree);
// }
// memset(b,0,sizeof(static_codebook));
}
// unpack the quantized list of values for encode/decode
// we need to deal with two map types: in map type 1, the values are
// generated algorithmically (each column of the vector counts through
// the values in the quant vector). in map type 2, all the values came
// in in an explicit list. Both value lists must be unpacked
internal float[] unquantize()
{
if(maptype==1 || maptype==2)
{
int quantvals=0;
int quantvals;
float mindel=float32_unpack(q_min);
float delta=float32_unpack(q_delta);
float[] r=new float[entries*dim];
//System.err.println("q_min="+q_min+", mindel="+mindel);
// maptype 1 and 2 both use a quantized value vector, but
// different sizes
switch(maptype)
{
case 1:
// most of the time, entries%dimensions == 0, but we need to be
// well defined. We define that the possible vales at each
// scalar is values == entries/dim. If entries%dim != 0, we'll
// have 'too few' values (values*dim<entries), which means that
// we'll have 'left over' entries; left over entries use zeroed
// values (and are wasted). So don't generate codebooks like that
quantvals=maptype1_quantvals();
for(int j=0;j<entries;j++)
{
float last=0.0f;
int indexdiv=1;
for(int k=0;k<dim;k++)
{
int index=(j/indexdiv)%quantvals;
float val=quantlist[index];
val=Math.Abs(val)*delta+mindel+last;
if(q_sequencep!=0)last=val;
r[j*dim+k]=val;
indexdiv*=quantvals;
}
}
break;
case 2:
quantvals=entries*dim;
for(int j=0;j<entries;j++)
{
float last=0.0f;
for(int k=0;k<dim;k++)
{
float val=quantlist[j*dim+k];
//if((j*dim+k)==0){System.err.println(" | 0 -> "+val+" | ");}
val=Math.Abs(val)*delta+mindel+last;
if(q_sequencep!=0)last=val;
r[j*dim+k]=val;
//if((j*dim+k)==0){System.err.println(" $ r[0] -> "+r[0]+" | ");}
}
}
//System.err.println("\nr[0]="+r[0]);
break;
default:
break;
}
// quantized values
quantlist=new int[quantvals];
for(i=0;i<quantvals;i++)
{
quantlist[i]=opb.read(q_quant);
}
if(quantlist[quantvals-1]==-1)
{
// goto _eofout;
clear();
return(-1);
}
return(r);
}
break;
default:
// goto _eofout;
clear();
return(-1);
return(null);
}
// all set
return(0);
// _errout:
// _eofout:
// vorbis_staticbook_clear(s);
// return(-1);
}
// there might be a straightforward one-line way to do the below
// that's portable and totally safe against roundoff, but I haven't
// thought of it. Therefore, we opt on the side of caution
private int maptype1_quantvals()
{
int vals=(int)(Math.floor(Math.pow(entries,1.0/dim)));
// the above *should* be reliable, but we'll not assume that FP is
// ever reliable when bitstream sync is at stake; verify via integer
// means that vals really is the greatest value of dim for which
// vals^b->bim <= b->entries
// treat the above as an initial guess
while(true)
internal static int ilog(int v)
{
int acc=1;
int acc1=1;
for(int i=0;i<dim;i++)
int ret=0;
while(v!=0)
{
acc*=vals;
acc1*=vals+1;
ret++;
v = (int)((uint)v >> 1);
}
if(acc<=entries && acc1>entries){ return(vals); }
else
return(ret);
}
// 32 bit float (not IEEE; nonnormalized mantissa +
// biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
// Why not IEEE? It's just not that important here.
//static int VQ_FEXP=10;
static int VQ_FMAN=21;
static int VQ_FEXP_BIAS=768; // bias toward values smaller than 1.
// doesn't currently guard under/overflow
internal static long float32_pack(float val)
{
uint sign=0;
int exp;
int mant;
if(val<0)
{
if(acc>entries){ vals--; }
else{ vals++; }
sign = 0x80000000;
val = -val;
}
exp=(int)Math.Floor(Math.Log(val)/Math.Log(2));
mant=(int)Math.Round(Math.Pow(val,(VQ_FMAN-1)-exp));
exp=(exp+VQ_FEXP_BIAS)<<VQ_FMAN;
return((int)sign | exp | mant);
}
}
void clear()
{
// if(quantlist!=null)free(b->quantlist);
// if(lengthlist!=null)free(b->lengthlist);
// if(nearest_tree!=null){
// free(b->nearest_tree->ptr0);
// free(b->nearest_tree->ptr1);
// free(b->nearest_tree->p);
// free(b->nearest_tree->q);
// memset(b->nearest_tree,0,sizeof(encode_aux_nearestmatch));
// free(b->nearest_tree);
// }
// if(thresh_tree!=null){
// free(b->thresh_tree->quantthresh);
// free(b->thresh_tree->quantmap);
// memset(b->thresh_tree,0,sizeof(encode_aux_threshmatch));
// free(b->thresh_tree);
// }
// memset(b,0,sizeof(static_codebook));
}
// unpack the quantized list of values for encode/decode
// we need to deal with two map types: in map type 1, the values are
// generated algorithmically (each column of the vector counts through
// the values in the quant vector). in map type 2, all the values came
// in in an explicit list. Both value lists must be unpacked
float[] unquantize()
{
if(maptype==1 || maptype==2)
internal static float float32_unpack(int val)
{
int quantvals;
float mindel=float32_unpack(q_min);
float delta=float32_unpack(q_delta);
float[] r=new float[entries*dim];
//System.err.println("q_min="+q_min+", mindel="+mindel);
// maptype 1 and 2 both use a quantized value vector, but
// different sizes
switch(maptype)
{
case 1:
// most of the time, entries%dimensions == 0, but we need to be
// well defined. We define that the possible vales at each
// scalar is values == entries/dim. If entries%dim != 0, we'll
// have 'too few' values (values*dim<entries), which means that
// we'll have 'left over' entries; left over entries use zeroed
// values (and are wasted). So don't generate codebooks like that
quantvals=maptype1_quantvals();
for(int j=0;j<entries;j++)
{
float last=0.f;
int indexdiv=1;
for(int k=0;k<dim;k++)
{
int index=(j/indexdiv)%quantvals;
float val=quantlist[index];
val=Math.abs(val)*delta+mindel+last;
if(q_sequencep!=0)last=val;
r[j*dim+k]=val;
indexdiv*=quantvals;
}
}
break;
case 2:
for(int j=0;j<entries;j++)
{
float last=0.f;
for(int k=0;k<dim;k++)
{
float val=quantlist[j*dim+k];
//if((j*dim+k)==0){System.err.println(" | 0 -> "+val+" | ");}
val=Math.abs(val)*delta+mindel+last;
if(q_sequencep!=0)last=val;
r[j*dim+k]=val;
//if((j*dim+k)==0){System.err.println(" $ r[0] -> "+r[0]+" | ");}
}
}
//System.err.println("\nr[0]="+r[0]);
}
return(r);
float mant=val&0x1fffff;
float sign=val&0x80000000;
float exp =(uint)(val&0x7fe00000) >> VQ_FMAN;
//System.err.println("mant="+mant+", sign="+sign+", exp="+exp);
//if(sign!=0.0)mant= -mant;
if((val&0x80000000)!=0)mant= -mant;
//System.err.println("mant="+mant);
return(ldexp(mant,((int)exp)-(VQ_FMAN-1)-VQ_FEXP_BIAS));
}
return(null);
}
private static int ilog(int v)
{
int ret=0;
while(v!=0)
internal static float ldexp(float foo, int e)
{
ret++;
(uint)v >>= 1;
return (float)(foo*Math.Pow(2, e));
}
return(ret);
}
// 32 bit float (not IEEE; nonnormalized mantissa +
// biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
// Why not IEEE? It's just not that important here.
static int VQ_FEXP=10;
static int VQ_FMAN=21;
static int VQ_FEXP_BIAS=768; // bias toward values smaller than 1.
// doesn't currently guard under/overflow
static long float32_pack(float val)
{
int sign=0;
int exp;
int mant;
if(val<0)
{
sign=0x80000000;
val= -val;
}
exp=(int)Math.floor(Math.log(val)/Math.log(2));
mant=(int)Math.rint(Math.pow(val,(VQ_FMAN-1)-exp));
exp=(exp+VQ_FEXP_BIAS)<<VQ_FMAN;
return(sign|exp|mant);
}
static float float32_unpack(int val)
{
float mant=val&0x1fffff;
float sign=val&0x80000000;
float exp =(uint)(val&0x7fe00000) >> VQ_FMAN;
//System.err.println("mant="+mant+", sign="+sign+", exp="+exp);
//if(sign!=0.0)mant= -mant;
if((val&0x80000000)!=0)mant= -mant;
//System.err.println("mant="+mant);
return(ldexp(mant,((int)exp)-(VQ_FMAN-1)-VQ_FEXP_BIAS));
}
static float ldexp(float foo, int e)
{
return (float)(foo*Math.pow(2, e));
}
}

Просмотреть файл

@ -26,13 +26,16 @@
using System;
using csogg;
class Time0 : FuncTime
namespace csvorbis
{
void pack(Object i, csBuffer opb){}
Object unpack(Info vi , csBuffer opb){return "";}
Object look(DspState vd, InfoMode mi, Object i){return "";}
void free_info(Object i){}
void free_look(Object i){}
int forward(Block vb, Object i){return 0;}
int inverse(Block vb, Object i, float[] fin, float[] fout){return 0;}
class Time0 : FuncTime
{
override public void pack(Object i, csBuffer opb){}
override public Object unpack(Info vi , csBuffer opb){return "";}
override public Object look(DspState vd, InfoMode mi, Object i){return "";}
override public void free_info(Object i){}
override public void free_look(Object i){}
override public int forward(Block vb, Object i){return 0;}
override public int inverse(Block vb, Object i, float[] fin, float[] fout){return 0;}
}
}

Просмотреть файл

@ -25,10 +25,13 @@
using System;
public class csorbisException : Exception
namespace csvorbis
{
public csorbisException ()
:base(){}
public csorbisException (String s)
:base("csorbis: "+s){}
public class csorbisException : Exception
{
public csorbisException ()
:base(){}
public csorbisException (String s)
:base("csorbis: "+s){}
}
}