-
Notifications
You must be signed in to change notification settings - Fork 1
/
AudioStream.cs
124 lines (106 loc) · 4.24 KB
/
AudioStream.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/* This class has been written by
* Corinna John (Hannover, Germany)
*
* 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 AviFile
{
public class AudioStream : AviStream{
public int CountBitsPerSample{
get{ return waveFormat.wBitsPerSample; }
}
public int CountSamplesPerSecond{
get{ return waveFormat.nSamplesPerSec; }
}
public int CountChannels{
get{ return waveFormat.nChannels; }
}
/// <summary>the stream's format</summary>
private Avi.PCMWAVEFORMAT waveFormat = new Avi.PCMWAVEFORMAT();
/// <summary>Initialize an AudioStream for an existing stream</summary>
/// <param name="aviFile">The file that contains the stream</param>
/// <param name="aviStream">An IAVISTREAM from [aviFile]</param>
public AudioStream(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);
}
/// <summary>Read the stream's header information</summary>
/// <param name="aviStream">The IAVISTREAM to read from</param>
/// <returns>AVISTREAMINFO</returns>
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;
}
/// <summary>Read the stream's header information</summary>
/// <returns>AVISTREAMINFO</returns>
public Avi.AVISTREAMINFO GetStreamInfo(){
if(writeCompressed){
return GetStreamInfo(compressedStream);
}else{
return GetStreamInfo(aviStream);
}
}
/// <summary>Read the stream's format information</summary>
/// <returns>PCMWAVEFORMAT</returns>
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;
}
/// <summary>Returns all data needed to copy the stream</summary>
/// <remarks>Do not forget to call Marshal.FreeHGlobal and release the raw data pointer</remarks>
/// <param name="streamInfo">Receives the header information</param>
/// <param name="format">Receives the format</param>
/// <param name="streamLength">Receives the length of the stream</param>
/// <returns>Pointer to the wave data</returns>
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;
}
/// <summary>Copy the stream into a new file</summary>
/// <param name="fileName">Name of the new file</param>
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);
}
}
}