/* This class has been written by
* Corinna John (Hannover, Germany)
* cj@binary-universe.net
*
* You may do with this code whatever you like,
* except selling it or claiming any rights/ownership.
*
* Please send me a little feedback about what you're
* using this code for and what changes you'd like to
* see in later versions. (And please excuse my bad english.)
*
* WARNING: This is experimental code.
* Please do not expect "Release Quality".
* */
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Scurvy.Media.Avi
{
internal sealed class AviAudioStream : AviStream{
public int CountBitsPerSample{
get{ return waveFormat.wBitsPerSample; }
}
public int CountSamplesPerSecond{
get{ return waveFormat.nSamplesPerSec; }
}
public int CountChannels{
get{ return waveFormat.nChannels; }
}
/// the stream's format
private Avi.PCMWAVEFORMAT waveFormat = new Avi.PCMWAVEFORMAT();
/// Initialize an AudioStream for an existing stream
/// The file that contains the stream
/// An IAVISTREAM from [aviFile]
public AviAudioStream(int aviFile, IntPtr aviStream){
this.aviFile = aviFile;
this.aviStream = aviStream;
int size = Marshal.SizeOf(waveFormat);
Avi.AVIStreamReadFormat(aviStream, 0, ref waveFormat, ref size);
Avi.AVISTREAMINFO streamInfo = GetStreamInfo(aviStream);
}
/// Read the stream's header information
/// The IAVISTREAM to read from
/// AVISTREAMINFO
private Avi.AVISTREAMINFO GetStreamInfo(IntPtr aviStream){
Avi.AVISTREAMINFO streamInfo = new Avi.AVISTREAMINFO();
int result = Avi.AVIStreamInfo(aviStream, ref streamInfo, Marshal.SizeOf(streamInfo));
if(result != 0) {
throw new Exception("Exception in AVIStreamInfo: "+result.ToString());
}
return streamInfo;
}
/// Read the stream's header information
/// AVISTREAMINFO
public Avi.AVISTREAMINFO GetStreamInfo(){
if(writeCompressed){
return GetStreamInfo(compressedStream);
}else{
return GetStreamInfo(aviStream);
}
}
/// Read the stream's format information
/// PCMWAVEFORMAT
public Avi.PCMWAVEFORMAT GetFormat(){
Avi.PCMWAVEFORMAT format = new Avi.PCMWAVEFORMAT();
int size = Marshal.SizeOf(format);
int result = Avi.AVIStreamReadFormat(aviStream, 0, ref format, ref size);
return format;
}
/// Returns all data needed to copy the stream
/// Do not forget to call Marshal.FreeHGlobal and release the raw data pointer
/// Receives the header information
/// Receives the format
/// Receives the length of the stream
/// Pointer to the wave data
public IntPtr GetStreamData(ref Avi.AVISTREAMINFO streamInfo, ref Avi.PCMWAVEFORMAT format, ref int streamLength){
streamInfo = GetStreamInfo();
format = GetFormat();
//length in bytes = length in samples * length of a sample
streamLength = Avi.AVIStreamLength(aviStream.ToInt32()) * streamInfo.dwSampleSize;
IntPtr waveData = Marshal.AllocHGlobal(streamLength);
int result = Avi.AVIStreamRead(aviStream, 0, streamLength, waveData, streamLength, 0, 0);
if(result != 0){
throw new Exception("Exception in AVIStreamRead: "+result.ToString());
}
return waveData;
}
/// Copy the stream into a new file
/// Name of the new file
public override void ExportStream(String fileName){
Avi.AVICOMPRESSOPTIONS_CLASS opts = new Avi.AVICOMPRESSOPTIONS_CLASS();
opts.fccType = (UInt32)Avi.mmioStringToFOURCC("auds", 0);
opts.fccHandler = (UInt32)Avi.mmioStringToFOURCC("CAUD", 0);
opts.dwKeyFrameEvery = 0;
opts.dwQuality = 0;
opts.dwFlags = 0;
opts.dwBytesPerSecond= 0;
opts.lpFormat = new IntPtr(0);
opts.cbFormat = 0;
opts.lpParms = new IntPtr(0);
opts.cbParms = 0;
opts.dwInterleaveEvery = 0;
Avi.AVISaveV(fileName, 0, 0, 1, ref aviStream, ref opts);
}
}
}