[WM][VB][Voice Mail]
在手機上打字是一件很痛苦的事情,如果用說的可能會來得比較快樂點,現在就來跟各位說如何發一封語音郵件,那在手機上要如何錄音呢,我們可以利用 Recording and Playing Sound with the Waveform Audio Interface參考http://msdn.microsoft.com/en-us/library/aa446573.aspx
Step1:開啟vs2008 新增一個vb 智慧型裝置專案,在表單上產生ListBox元件來顯示整個操作過程訊息, Button按鍵用來開始錄音及結束發送mail
Step2:將滑鼠移到方案總管到SmartDeviceProject1下的參考,按下滑鼠右鍵加入參考
Step3:選擇Microsoft.WindowsMobile.PocketOutlook按下確定
Step4:插入Class Memory
01 Imports ...System
02 Imports System.Runtime.InteropServices
03
04 Public Class Memory
05
06
07 Public Const LMEM_FIXED As Integer = &H0
08
09 Public Const LMEM_ZEROINIT As Integer = &H40
10
11 Public Const LMEM_MOVEABLE As Integer = &H2
12
13 Public Const LMEM_MODIFY As Integer = &H80
14
15
16 <DllImport("coredll.dll")> _
17 Public Shared Function LocalAlloc() Shared Function LocalAlloc(ByVal uFlags As Integer, ByVal uBytes As Integer) As IntPtr
18 End Function
19
20 <DllImport("coredll.dll")> _
21 Public Shared Function LocalFree() Shared Function LocalFree(ByVal hMem As IntPtr) As IntPtr
22 End Function
23
24 <DllImport("coredll.dll")> _
25 Public Shared Function LocalReAlloc() Shared Function LocalReAlloc(ByVal hMem As IntPtr, ByVal uBytes As Integer, ByVal fuFlags As Integer) As IntPtr
26 End Function
27
28 End Class
Step5:插入Class Wave
001 Imports ...System
002 Imports System.IO
003 Imports System.Runtime.InteropServices
004
005
006 Public Class Wave
007
008
009 Public Const WAVE_MAPPER As Integer = -1
010
011 Public Const CALLBACK_WINDOW As Integer = &H10000
012
013 Private Const WAVERR_BASE As Integer = 32
014 Private Const MMSYSERR_BASE As Integer = 0
015
016
017 Public Enum MMSYSERR
018 NOERROR = 0
019 GENERROR = (MMSYSERR_BASE + 1)
020 BADDEVICEID = (MMSYSERR_BASE + 2)
021 NOTENABLED = (MMSYSERR_BASE + 3)
022 ALLOCATED = (MMSYSERR_BASE + 4)
023 INVALHANDLE = (MMSYSERR_BASE + 5)
024 NODRIVER = (MMSYSERR_BASE + 6)
025 NOMEM = (MMSYSERR_BASE + 7)
026 NOTSUPPORTED = (MMSYSERR_BASE + 8)
027 BADERRNUM = (MMSYSERR_BASE + 9)
028 INVALFLAG = (MMSYSERR_BASE + 10)
029 INVALPARAM = (MMSYSERR_BASE + 11)
030 HANDLEBUSY = (MMSYSERR_BASE + 12)
031 INVALIDALIAS = (MMSYSERR_BASE + 13)
032 BADDB = (MMSYSERR_BASE + 14)
033 KEYNOTFOUND = (MMSYSERR_BASE + 15)
034 READERROR = (MMSYSERR_BASE + 16)
035 WRITEERROR = (MMSYSERR_BASE + 17)
036 DELETEERROR = (MMSYSERR_BASE + 18)
037 VALNOTFOUND = (MMSYSERR_BASE + 19)
038 NODRIVERCB = (MMSYSERR_BASE + 20)
039 LASTERROR = (MMSYSERR_BASE + 20)
040 End Enum
041
042 ' Enum equivalent to WAVERR_*
043 Private Enum WAVERR
044 NONE = 0
045 BADFORMAT = WAVERR_BASE + 0
046 STILLPLAYING = WAVERR_BASE + 1
047 UNPREPARED = WAVERR_BASE + 2
048 SYNC = WAVERR_BASE + 3
049 LASTERROR = WAVERR_BASE + 3
050 End Enum
051
052
053 Public Const WAVE_INVALIDFORMAT As Integer = &H0
054
055 Public Const WAVE_FORMAT_1M08 As Integer = &H1
056
057 Public Const WAVE_FORMAT_1S08 As Integer = &H2
058
059 Public Const WAVE_FORMAT_1M16 As Integer = &H4
060
061 Public Const WAVE_FORMAT_1S16 As Integer = &H8
062
063 Public Const WAVE_FORMAT_2M08 As Integer = &H10
064
065 Public Const WAVE_FORMAT_2S08 As Integer = &H20
066
067 Public Const WAVE_FORMAT_2M16 As Integer = &H40
068
069 Public Const WAVE_FORMAT_2S16 As Integer = &H80
070
071 Public Const WAVE_FORMAT_4M08 As Integer = &H100
072
073 Public Const WAVE_FORMAT_4S08 As Integer = &H200
074
075 Public Const WAVE_FORMAT_4M16 As Integer = &H400
076
077 Public Const WAVE_FORMAT_4S16 As Integer = &H800
078
079 Public Class WAVEFORMATEX
080
081 Protected Const WF_OFFSET_FORMATTAG As Integer = 20
082 Protected Const WF_OFFSET_CHANNELS As Integer = 22
083 Protected Const WF_OFFSET_SAMPLESPERSEC As Integer = 24
084 Protected Const WF_OFFSET_AVGBYTESPERSEC As Integer = 28
085 Protected Const WF_OFFSET_BLOCKALIGN As Integer = 32
086 Protected Const WF_OFFSET_BITSPERSAMPLE As Integer = 34
087 Public Const WF_OFFSET_DATA As Integer = 44
088
089 Public Property wFormatTag() Property wFormatTag()
090 Get
091 Return Convert.ToInt32(m_wFormatTag)
092 End Get
093 Set(ByVal Value)
094 m_wFormatTag = Convert.ToUInt16(Value)
095 End Set
096 End Property
097 Protected m_wFormatTag As UInt16 = Convert.ToUInt16() m_wFormatTag As UInt16 = Convert.ToUInt16(0)
098
099 Public Property nChannels() Property nChannels()
100 Get
101 Return Convert.ToInt32(m_nChannels)
102 End Get
103 Set(ByVal Value)
104 m_nChannels = Convert.ToUInt16(Value)
105 End Set
106 End Property
107 Protected m_nChannels As UInt16 = Convert.ToUInt16() m_nChannels As UInt16 = Convert.ToUInt16(0)
108
109 Public Property nSamplesPerSec() Property nSamplesPerSec()
110 Get
111 Return Convert.ToInt32(m_nSamplesPerSec)
112 End Get
113 Set(ByVal Value)
114 m_nSamplesPerSec = Convert.ToUInt32(Value)
115 End Set
116 End Property
117 Protected m_nSamplesPerSec As UInt32 = Convert.ToUInt32() m_nSamplesPerSec As UInt32 = Convert.ToUInt32(0)
118
119 Public Property nAvgBytesPerSec() Property nAvgBytesPerSec()
120 Get
121 Return Convert.ToInt32(m_nAvgBytesPerSec)
122 End Get
123 Set(ByVal Value)
124 m_nAvgBytesPerSec = Convert.ToUInt32(Value)
125 End Set
126 End Property
127 Protected m_nAvgBytesPerSec As UInt32 = Convert.ToUInt32() m_nAvgBytesPerSec As UInt32 = Convert.ToUInt32(0)
128
129 Public Property nBlockAlign() Property nBlockAlign()
130 Get
131 Return Convert.ToInt32(m_nBlockAlign)
132 End Get
133 Set(ByVal Value)
134 m_nBlockAlign = Convert.ToUInt16(Value)
135 End Set
136 End Property
137 Protected m_nBlockAlign As UInt16 = Convert.ToUInt16() m_nBlockAlign As UInt16 = Convert.ToUInt16(0)
138
139 Public Property wBitsPerSample() Property wBitsPerSample()
140 Get
141 Return Convert.ToInt32(m_wBitsPerSample)
142 End Get
143 Set(ByVal Value)
144 m_wBitsPerSample = Convert.ToUInt16(Value)
145 End Set
146 End Property
147 Protected m_wBitsPerSample As UInt16 = Convert.ToUInt16() m_wBitsPerSample As UInt16 = Convert.ToUInt16(0)
148
149 Public Sub SeekTo() Sub SeekTo(ByVal fs As Stream)
150 fs.Seek(WF_OFFSET_FORMATTAG, SeekOrigin.Begin)
151 End Sub
152
153 Public Sub Skip() Sub Skip(ByVal fs As Stream)
154 fs.Seek(WF_OFFSET_DATA, SeekOrigin.Begin)
155 End Sub
156
157 Public Sub Read() Sub Read(ByVal rdr As BinaryReader)
158
159 m_wFormatTag = rdr.ReadUInt16()
160 m_nChannels = rdr.ReadUInt16()
161 m_nSamplesPerSec = rdr.ReadUInt32()
162 m_nAvgBytesPerSec = rdr.ReadUInt32()
163 m_nBlockAlign = rdr.ReadUInt16()
164 m_wBitsPerSample = rdr.ReadUInt16()
165
166 Dim dataId As UInt32 = rdr.ReadUInt32()
167 Dim dataLength As UInt32 = rdr.ReadUInt32()
168
169 End Sub
170
171 Public Sub Write() Sub Write(ByVal wrtr As BinaryWriter)
172
173 wrtr.Write(Convert.ToUInt16(m_wFormatTag))
174 wrtr.Write(Convert.ToUInt16(m_nChannels))
175 wrtr.Write(Convert.ToUInt32(m_nSamplesPerSec))
176 wrtr.Write(Convert.ToUInt32(m_nAvgBytesPerSec))
177 wrtr.Write(Convert.ToUInt16(m_nBlockAlign))
178 wrtr.Write(Convert.ToUInt16(m_wBitsPerSample))
179
180 End Sub
181 End Class
182
183 Public Class WAVEHDR
184 Implements IDisposable
185
186 Public Const WHDR_DONE As Integer = &H1
187
188 Public Const WHDR_PREPARED As Integer = &H2
189
190 Public Const WHDR_BEGINLOOP As Integer = &H4
191
192 Public Const WHDR_ENDLOOP As Integer = &H8
193
194 Public Const WHDR_INQUEUE As Integer = &H10
195
196 Public Const WAVE_FORMAT_PCM As Integer = 1
197
198 Public lpData As IntPtr = IntPtr.Zero
199
200 Public dwBufferLength As Integer = 0
201
202 Public dwBytesRecorded As Integer = 0
203
204 Public dwUser As Integer = 0
205
206 Public dwFlags As Integer = 0
207
208 Public dwLoops As Integer = 0
209
210 Public lpNext As IntPtr = IntPtr.Zero
211
212 Public reserved As Integer = 0
213
214 Public Function Read() Function Read(ByVal rdr As BinaryReader, ByVal readLength As Integer, ByVal align As Integer) As MMSYSERR
215
216 Dim bufferLength As Integer = readLength
217
218 If bufferLength Mod align <> 0 Then
219 bufferLength += (align - (bufferLength Mod align))
220 End If
221
222 dwBufferLength = bufferLength
223 Dim data(readLength - 1) As Byte
224 rdr.Read(data, 0, data.Length)
225
226 If lpData.ToInt32() = IntPtr.Zero.ToInt32() Then
227 lpData = Memory.LocalAlloc(Memory.LMEM_FIXED, bufferLength)
228 End If
229
230 If lpData.ToInt32() = IntPtr.Zero.ToInt32() Then
231 Return MMSYSERR.NOMEM
232 End If
233
234 Marshal.Copy(data, 0, lpData, data.Length)
235
236 Return MMSYSERR.NOERROR
237
238 End Function
239
240 Public Function Write() Function Write(ByVal wrtr As BinaryWriter) As MMSYSERR
241
242 If lpData.ToInt32() = IntPtr.Zero.ToInt32() Then
243 Return Wave.MMSYSERR.NOMEM
244 End If
245
246 Dim data(dwBytesRecorded - 1) As Byte
247 Marshal.Copy(lpData, data, 0, data.Length)
248 wrtr.Write(data)
249
250 Return Wave.MMSYSERR.NOERROR
251
252 End Function
253
254 Public Function Init() Function Init(ByVal bufferLength As Integer, ByVal initData As Boolean) As MMSYSERR
255
256 If lpData.ToInt32() <> IntPtr.Zero.ToInt32() AndAlso dwBufferLength < bufferLength Then
257 Memory.LocalFree(lpData)
258 lpData = IntPtr.Zero
259 End If
260
261 If lpData.ToInt32() = IntPtr.Zero.ToInt32() Then
262 lpData = Memory.LocalAlloc(Memory.LMEM_FIXED, bufferLength)
263 End If
264
265 dwBufferLength = bufferLength
266
267 If lpData.ToInt32() = IntPtr.Zero.ToInt32() Then
268 Return MMSYSERR.NOMEM
269 End If
270
271 If initData Then
272 Dim i As Integer
273 For i = 0 To bufferLength - 1
274 Marshal.WriteByte(lpData, i, 0)
275 Next
276 End If
277
278 Return MMSYSERR.NOERROR
279
280 End Function
281
282 Public Sub Dispose() Sub Dispose() Implements IDisposable.Dispose
283 If lpData.ToInt32() <> IntPtr.Zero.ToInt32() Then
284 Memory.LocalFree(lpData)
285 End If
286 End Sub
287 End Class
288 End Class
Step6:插入Class WaveIn
001 Imports ...System
002 Imports System.Runtime.InteropServices
003 Imports System.IO
004 Imports Microsoft.WindowsCE.Forms
005 Imports System.Text
006 Imports System.Threading
007 Imports System.Windows.Forms
008 Imports System.Diagnostics
009
010
011 Public Class WaveIn
012
013 Protected Class WaveFile
014 Implements IDisposable
015
016 Protected m_hwi As IntPtr = IntPtr.Zero
017
018
019 Protected m_wfmt As Wave.WAVEFORMATEX = Nothing
020
021
022 Protected m_whdr() m_whdr() As Wave.WAVEHDR = Nothing
023
024
025 Protected m_inited As Boolean = False
026
027
028 Protected m_curBlock As Integer
029
030
031 Protected m_numBlocks As Integer
032
033
034 Protected m_bufferSize As Integer
035
036 Protected m_maxDataLength As Integer
037
038 Public ReadOnly Property Done() ReadOnly Property Done()
039 Get
040 Return Not m_recording
041 End Get
042 End Property
043 Protected m_recording As Boolean = False
044
045
046 Public Function Preload() Function Preload(ByVal curDevice As Integer, ByVal hwnd As IntPtr, ByVal maxRecordLength_ms As Integer, ByVal bufferSize As Integer) As Wave.MMSYSERR
047
048 ' Do not allow recording to be interrupted
049 If m_recording Then
050 Return Wave.MMSYSERR.GENERROR
051 End If
052
053 ' If this file is already initialized then start over
054 If m_inited Then
055 StopRecord()
056 FreeWaveBuffers()
057 End If
058
059 ' Create an instance of WAVEINCAPS to check if our desired
060 ' format is supported
061 Dim caps As WAVEINCAPS = New WAVEINCAPS
062 waveInGetDevCaps(0, caps.Data, caps.Size)
063 If (caps.dwFormats And Wave.WAVE_FORMAT_2S16) = 0 Then
064 Return Wave.MMSYSERR.NOTSUPPORTED
065 End If
066
067 ' Initialize a WAVEFORMATEX structure specifying the desired
068 ' format
069 m_wfmt = New Wave.WAVEFORMATEX
070 m_wfmt.wFormatTag = Wave.WAVEHDR.WAVE_FORMAT_PCM
071 m_wfmt.wBitsPerSample = 16
072 m_wfmt.nChannels = 2
073 m_wfmt.nSamplesPerSec = 22050
074 m_wfmt.nAvgBytesPerSec = Fix((m_wfmt.nSamplesPerSec * m_wfmt.nChannels * m_wfmt.wBitsPerSample) / 8)
075 m_wfmt.nBlockAlign = Fix((m_wfmt.wBitsPerSample * m_wfmt.nChannels) / 8)
076
077 ' Attempt to open the specified device with the desired wave format
078 Dim result As Wave.MMSYSERR = waveInOpen(m_hwi, curDevice, m_wfmt, hwnd, 0, Wave.CALLBACK_WINDOW)
079 If result <> Wave.MMSYSERR.NOERROR Then
080 Return result
081 End If
082
083 If bufferSize = 0 Then
084 Return Wave.MMSYSERR.GENERROR
085 End If
086
087 m_bufferSize = bufferSize
088
089 ' Force the buffers to align to nBlockAlign
090 If (m_bufferSize Mod m_wfmt.nBlockAlign) <> 0 Then
091 m_bufferSize += m_wfmt.nBlockAlign - (m_bufferSize Mod m_wfmt.nBlockAlign)
092 End If
093
094 ' Determine the number of buffers needed to record the maximum length
095 m_maxDataLength = (m_wfmt.nAvgBytesPerSec * maxRecordLength_ms) / 1000
096 m_numBlocks = Fix(m_maxDataLength / m_bufferSize)
097 If (m_numBlocks * m_bufferSize) < m_maxDataLength Then
098 m_numBlocks += 1
099 End If
100
101 ' Allocate the list of buffers
102 m_whdr = New Wave.WAVEHDR(m_numBlocks) {}
103
104
105 ' Allocate and initialize two buffers to start with
106 m_whdr(0) = New Wave.WAVEHDR
107 m_whdr(1) = New Wave.WAVEHDR
108
109 result = InitBuffer(0)
110 If result <> Wave.MMSYSERR.NOERROR Then
111 Return result
112 End If
113
114 result = InitBuffer(1)
115 If result <> Wave.MMSYSERR.NOERROR Then
116 Return result
117 End If
118
119 m_curBlock = 0
120 m_inited = True
121
122 Return Wave.MMSYSERR.NOERROR
123
124 End Function
125
126
127 Public Sub BlockDone() Sub BlockDone()
128
129 m_curBlock += 1
130
131 ' If the next block is not the padding buffer at the end of the
132 ' recording then initialize another buffer, otherwise stop recording
133 If m_curBlock < m_numBlocks Then
134 InitBuffer(m_curBlock + 1)
135 ElseIf m_curBlock = m_numBlocks Then
136 StopRecord()
137 End If
138
139 End Sub
140
141
142 Public Function InitBuffer() Function InitBuffer(ByVal bufIndex As Integer) As Wave.MMSYSERR
143
144 ' Determine the size of the buffer to create
145 Dim writeLength As Integer = m_bufferSize
146
147 If bufIndex < m_numBlocks Then
148 Dim remainingDataLength As Integer = m_maxDataLength - (bufIndex * m_bufferSize)
149 If m_bufferSize > remainingDataLength Then
150 writeLength = remainingDataLength
151 End If
152 End If
153
154 ' If the header is not already instanced then instance it
155 If m_whdr(bufIndex) Is Nothing Then
156 m_whdr(bufIndex) = New Wave.WAVEHDR
157 End If
158
159 ' Allocate memory if not already allocated
160 Dim result As Wave.MMSYSERR = m_whdr(bufIndex).Init(writeLength, False)
161 If result <> Wave.MMSYSERR.NOERROR Then
162 Return result
163 End If
164
165 ' Prepare the header
166 result = waveInPrepareHeader(m_hwi, m_whdr(bufIndex), Marshal.SizeOf(m_whdr(bufIndex)))
167 If result <> Wave.MMSYSERR.NOERROR Then
168 Return result
169 End If
170
171 ' Put the buffer in the queue
172 Return waveInAddBuffer(m_hwi, m_whdr(bufIndex), Marshal.SizeOf(m_whdr(bufIndex)))
173
174 End Function
175
176 Public Function Start() Function Start() As Wave.MMSYSERR
177
178 If Not m_inited OrElse m_recording Then
179 Return Wave.MMSYSERR.GENERROR
180 End If
181
182 Dim result As Wave.MMSYSERR = waveInStart(m_hwi)
183 If result <> Wave.MMSYSERR.NOERROR Then
184 Return result
185 End If
186
187 m_recording = True
188
189 Return Wave.MMSYSERR.NOERROR
190
191 End Function
192
193 Private Sub FreeWaveBuffers() Sub FreeWaveBuffers()
194
195 m_inited = False
196
197 If Not (m_whdr Is Nothing) Then
198
199 Dim i As Integer
200 For i = 0 To m_whdr.Length - 1
201 If Not (m_whdr(i) Is Nothing) Then
202 waveInUnprepareHeader(m_hwi, m_whdr(i), Marshal.SizeOf(m_whdr(i)))
203
204 m_whdr(i).Dispose()
205 m_whdr(i) = Nothing
206 End If
207 Next
208
209 m_whdr = Nothing
210
211 End If
212
213 waveInClose(m_hwi)
214
215 m_hwi = IntPtr.Zero
216
217 End Sub
218
219 Private Sub WriteChars() Sub WriteChars(ByVal wrtr As BinaryWriter, ByVal txt As String)
220
221 Dim i As Integer
222 For i = 0 To txt.Length - 1
223 Dim c As Char = txt.Chars(i)
224 wrtr.Write(c)
225 Next
226
227 End Sub
228
229 Public Function Save() Function Save(ByVal fileName As String) As Wave.MMSYSERR
230
231 If Not m_inited Then
232 Return Wave.MMSYSERR.GENERROR
233 End If
234
235 If m_recording Then
236 StopRecord()
237 End If
238
239 Dim strm As FileStream = Nothing
240 Dim wrtr As BinaryWriter = Nothing
241
242 Try
243
244 If File.Exists(fileName) Then
245
246 Dim fi As FileInfo = New FileInfo(fileName)
247 If (fi.Attributes And FileAttributes.ReadOnly) <> 0 Then
248 fi.Attributes -= FileAttributes.ReadOnly
249 End If
250
251 strm = New FileStream(fileName, FileMode.Truncate)
252 Else
253 strm = New FileStream(fileName, FileMode.Create)
254 End If
255
256 If strm Is Nothing Then
257 Return Wave.MMSYSERR.GENERROR
258 End If
259
260 wrtr = New BinaryWriter(strm)
261 If wrtr Is Nothing Then
262 Return Wave.MMSYSERR.GENERROR
263 End If
264
265 ' Determine the size of the data, as the total number of bytes
266 ' recorded by each buffer
267 Dim totalSize As Integer = 0
268 Dim i As Integer
269 For i = 0 To m_numBlocks - 1
270 If Not (m_whdr(i) Is Nothing) Then
271 totalSize += m_whdr(i).dwBytesRecorded
272 End If
273 Next
274
275
276 Dim chunkSize As Integer = 36 + totalSize
277
278 ' Write out the header information
279 WriteChars(wrtr, "RIFF")
280 wrtr.Write(chunkSize)
281 WriteChars(wrtr, "WAVEfmt ")
282 wrtr.Write(Convert.ToInt32(16))
283 m_wfmt.Write(wrtr)
284 WriteChars(wrtr, "data")
285 wrtr.Write(totalSize)
286
287 ' Write the data recorded to each buffer
288 For i = 0 To m_numBlocks - 1
289 If Not (m_whdr(i) Is Nothing) Then
290 Dim result As Wave.MMSYSERR = m_whdr(i).Write(wrtr)
291 If result <> Wave.MMSYSERR.NOERROR Then
292 Return result
293 End If
294 End If
295 Next
296
297 Return Wave.MMSYSERR.NOERROR
298
299 Finally
300 FreeWaveBuffers()
301
302 If Not (strm Is Nothing) Then
303 strm.Close()
304 End If
305
306 If Not (wrtr Is Nothing) Then
307 wrtr.Close()
308 End If
309
310 End Try
311
312 End Function
313
314 Public Sub StopRecord() Sub StopRecord()
315
316 waveInReset(m_hwi)
317 m_recording = False
318
319 End Sub
320
321
322 Public Sub Dispose() Sub Dispose() Implements IDisposable.Dispose
323
324 StopRecord()
325 FreeWaveBuffers()
326
327 End Sub
328
329 End Class
330
331
332 Protected Class SoundMessageWindow
333 Inherits MessageWindow
334
335 Public Const MM_WIM_OPEN As Integer = &H3BE
336 Public Const MM_WIM_CLOSE As Integer = &H3BF
337 Public Const MM_WIM_DATA As Integer = &H3C0
338
339 ' Instance of a recording interface
340 Protected m_wi As WaveIn = Nothing
341
342 Public Sub New() Sub New(ByVal wi As WaveIn)
343 m_wi = wi
344 End Sub
345
346 Protected Overrides Sub WndProc() Overrides Sub WndProc(ByRef msg As Message)
347
348 Select Case (msg.Msg)
349 ' When this message is encountered, a block is
350 ' done recording, so notify the WaveIn instance.
351 Case MM_WIM_DATA
352 If Not (m_wi Is Nothing) Then
353 m_wi.BlockDone()
354 End If
355 End Select
356
357 MyBase.WndProc(msg)
358
359 End Sub
360
361 End Class
362
363
364 Protected m_msgWindow As SoundMessageWindow = Nothing
365
366 Protected m_file As WaveFile = Nothing
367
368 Public Sub New() Sub New()
369 m_msgWindow = New SoundMessageWindow(Me)
370 m_file = New WaveFile
371 End Sub
372
373
374 Public Function NumDevices() Function NumDevices() As Integer
375 Return waveInGetNumDevs()
376 End Function
377
378
379 Public Function GetDeviceName() Function GetDeviceName(ByVal deviceId As Integer, ByRef prodName As String) As Wave.MMSYSERR
380 Dim caps As WAVEINCAPS = New WAVEINCAPS
381 Dim result As Wave.MMSYSERR = waveInGetDevCaps(deviceId, caps.Data, caps.Size)
382
383 If result <> Wave.MMSYSERR.NOERROR Then
384 Return result
385 End If
386
387 prodName = caps.szPname
388
389 Return Wave.MMSYSERR.NOERROR
390
391 End Function
392
393
394 Public Sub BlockDone() Sub BlockDone()
395 m_file.BlockDone()
396 End Sub
397
398
399 Public Function Preload() Function Preload(ByVal maxRecordLength_ms As Integer, ByVal bufferSize As Integer) As Wave.MMSYSERR
400
401 If Not (m_file Is Nothing) Then
402 Return m_file.Preload(0, m_msgWindow.Hwnd, maxRecordLength_ms, bufferSize)
403 End If
404
405 Return Wave.MMSYSERR.NOERROR
406
407 End Function
408
409 Public Sub StopRecord() Sub StopRecord()
410
411 If Not (m_file Is Nothing) Then
412 m_file.StopRecord()
413 End If
414
415 End Sub
416
417 ' <summary>
418 ' Start recording.
419 ' </summary>
420 ' <returns>MMSYSERR.NOERROR if successful</returns>
421 Public Function Start() Function Start() As Wave.MMSYSERR
422
423 If Not (m_file Is Nothing) Then
424 Return m_file.Start()
425 End If
426
427 Return Wave.MMSYSERR.NOERROR
428
429 End Function
430 >
431 Public Function Done() Function Done() As Boolean
432 Return m_file.Done
433 End Function
434
435 Public Function Save() Function Save(ByVal fileName As String) As Wave.MMSYSERR
436
437 If Not (m_file Is Nothing) Then
438 Return m_file.Save(fileName)
439 End If
440
441 Return Wave.MMSYSERR.NOERROR
442
443 End Function
444
445 Public Sub Dispose() Sub Dispose()
446
447 m_msgWindow.Dispose()
448
449 If Not (m_file Is Nothing) Then
450 m_file.Dispose()
451 End If
452
453 End Sub
454
455
456 <DllImport("coredll.dll")> _
457 Protected Shared Function waveInGetNumDevs() Shared Function waveInGetNumDevs() As Integer
458 End Function
459
460
461 <DllImport("coredll.dll")> _
462 Private Shared Function waveInOpen() Shared Function waveInOpen(ByRef phwi As IntPtr, ByVal uDeviceID As Integer, ByVal pwfx As Wave.WAVEFORMATEX, ByVal dwCallback As IntPtr, ByVal dwInstance As Integer, ByVal fdwOpen As Integer) As Wave.MMSYSERR
463 End Function
464
465
466 <DllImport("coredll.dll")> _
467 Private Shared Function waveInPrepareHeader() Shared Function waveInPrepareHeader(ByVal hwi As IntPtr, ByVal pwh As Wave.WAVEHDR, ByVal cbwh As Integer) As Wave.MMSYSERR
468 End Function
469
470 <DllImport("coredll.dll")> _
471 Private Shared Function waveInUnprepareHeader() Shared Function waveInUnprepareHeader(ByVal hwi As IntPtr, ByVal pwh As Wave.WAVEHDR, ByVal cbwh As Integer) As Wave.MMSYSERR
472 End Function
473
474 <DllImport("coredll.dll")> _
475 Protected Shared Function waveInClose() Shared Function waveInClose(ByVal hwi As IntPtr) As Wave.MMSYSERR
476 End Function
477
478 <DllImport("coredll.dll")> _
479 Protected Shared Function waveInReset() Shared Function waveInReset(ByVal hwi As IntPtr) As Wave.MMSYSERR
480 End Function
481
482 <DllImport("coredll.dll")> _
483 Protected Shared Function waveInStart() Shared Function waveInStart(ByVal hwi As IntPtr) As Wave.MMSYSERR
484 End Function
485
486 <DllImport("coredll.dll")> _
487 Protected Shared Function waveInStop() Shared Function waveInStop(ByVal hwi As IntPtr) As Wave.MMSYSERR
488 End Function
489
490 <DllImport("coredll.dll")> _
491 Private Shared Function waveInAddBuffer() Shared Function waveInAddBuffer(ByVal hwi As IntPtr, ByVal pwh As Wave.WAVEHDR, ByVal cbwh As Integer) As Wave.MMSYSERR
492 End Function
493
494
495 Protected Class WAVEINCAPS
496
497 Const WAVEINCAPS_SIZE As Integer = 80
498
499 Private m_data() m_data() As Byte = Nothing
500
501 Public ReadOnly Property Size() ReadOnly Property Size()
502 Get
503 Return WAVEINCAPS_SIZE
504 End Get
505 End Property
506
507 Public ReadOnly Property wMid() ReadOnly Property wMid()
508 Get
509 Return Convert.ToInt32(BitConverter.ToUInt16(m_data, 0))
510 End Get
511 End Property
512
513 Public ReadOnly Property wPid() ReadOnly Property wPid()
514 Get
515 Return Convert.ToInt32(BitConverter.ToUInt16(m_data, 2))
516 End Get
517 End Property
518
519 Public ReadOnly Property vDriverVersion() ReadOnly Property vDriverVersion()
520 Get
521 Return Convert.ToInt32(BitConverter.ToUInt32(m_data, 4))
522 End Get
523 End Property
524
525 Public ReadOnly Property dwFormats() ReadOnly Property dwFormats()
526 Get
527 Return Convert.ToInt32(BitConverter.ToUInt32(m_data, 72))
528 End Get
529 End Property
530
531 Public ReadOnly Property wChannels() ReadOnly Property wChannels()
532 Get
533 Return Convert.ToInt32(BitConverter.ToUInt16(m_data, 76))
534 End Get
535 End Property
536
537 Public ReadOnly Property wReserved1() ReadOnly Property wReserved1()
538 Get
539 Return Convert.ToInt32(BitConverter.ToUInt16(m_data, 78))
540 End Get
541 End Property
542
543 Public ReadOnly Property szPname() ReadOnly Property szPname()
544 Get
545 Dim bytes(31) As Char
546 Dim i As Integer
547 For i = 0 To 31
548 bytes(i) = Convert.ToChar(BitConverter.ToUInt16(m_data, i * 2 + 8))
549 Next
550
551 Return New String(bytes)
552
553 End Get
554 End Property
555
556 Public Sub New() Sub New()
557 m_data = New Byte(WAVEINCAPS_SIZE - 1) {}
558 End Sub
559
560 Public ReadOnly Property Data() ReadOnly Property Data()
561 Get
562 Return m_data
563 End Get
564 End Property
565
566 End Class
567
568
569 <DllImport("coredll.dll")> _
570 Protected Shared Function waveInGetDevCaps() Shared Function waveInGetDevCaps(ByVal uDeviceID As Integer, ByVal pwic() As Byte, ByVal cbwic As Integer) As Wave.MMSYSERR
571 End Function
572
573 Public Shared Sub TestProc() Shared Sub TestProc(ByVal showLine As ListBox)
574
575 Dim wi As WaveIn = Nothing
576
577 Try
578 wi = New WaveIn
579
580 Dim numDevices As Integer = wi.NumDevices()
581 If numDevices < 1 Then
582 showLine.Items.Add("FAILURE: No valid sound drivers detected")
583 Return
584 End If
585
586 showLine.Items.Add(String.Format("{0} device{1} detected:", numDevices, IIf(numDevices <> 1, "s", "")))
587 Dim i As Integer
588 For i = 0 To numDevices - 1
589 Dim prodName As String = ""
590 If Wave.MMSYSERR.NOERROR <> wi.GetDeviceName(i, prodName) Then
591 showLine.Items.Add(String.Format(" {0}: Failed to get name", i))
592 Else
593 showLine.Items.Add(String.Format(" {0}: {1}", i, prodName))
594 End If
595 Next
596
597
598 showLine.Items.Add("Setting max time to 3 seconds")
599 showLine.Items.Add("Using 256KB buffers")
600 If Wave.MMSYSERR.NOERROR <> wi.Preload(3000, 256 * 1024) Then
601 showLine.Items.Add("FAILURE: Failed to preload buffers")
602 End If
603
604 showLine.Items.Add("Starting recording...")
605 If Wave.MMSYSERR.NOERROR <> wi.Start() Then
606 showLine.Items.Add("FAILURE: Failed to start recording")
607 End If
608
609 showLine.Items.Add("Waiting for 2 seconds...")
610 Thread.Sleep(2000)
611
612 showLine.Items.Add("Stopping recording early")
613 wi.StopRecord()
614
615 Dim fileName As String = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase
616 fileName = Path.GetDirectoryName(fileName)
617 fileName = Path.Combine(fileName, "test.wav")
618 showLine.Items.Add("Saving file test.wav")
619
620 If Wave.MMSYSERR.NOERROR <> wi.Save(fileName) Then
621 showLine.Items.Add("FAILURE: Failed to save file")
622 End If
623
624 Finally
625
626 If Not (wi Is Nothing) Then
627 wi.Dispose()
628 End If
629
630 End Try
631
632 End Sub
633
634 End Class
Step7:插入表單程式碼
Imports ...System.IO
Imports System.Threading
Public Class Form1
Dim wi As New WaveIn
Private Sub Button1_Click() Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try
If Button1.Text = "開始" Then
ListBox1.Items.Clear()
Dim numDevices As Integer = wi.NumDevices()
If numDevices < 1 Then
ListBox1.Items.Add("FAILURE: No valid sound drivers detected")
Return
End If
ListBox1.Items.Add(String.Format("{0} device{1} detected:", numDevices, IIf(numDevices <> 1, "s", "")))
Dim i As Integer
For i = 0 To numDevices - 1
Dim prodName As String = ""
If Wave.MMSYSERR.NOERROR <> wi.GetDeviceName(i, prodName) Then
ListBox1.Items.Add(String.Format(" {0}: Failed to get name", i))
Else
ListBox1.Items.Add(String.Format(" {0}: {1}", i, prodName))
End If
Next
ListBox1.Items.Add("Setting max time to 3 seconds")
ListBox1.Items.Add("Using 256KB buffers")
If Wave.MMSYSERR.NOERROR <> wi.Preload(3000, 256 * 1024) Then
ListBox1.Items.Add("FAILURE: Failed to preload buffers")
End If
ListBox1.Items.Add("Starting recording...")
If Wave.MMSYSERR.NOERROR <> wi.Start() Then
ListBox1.Items.Add("FAILURE: Failed to start recording")
End If
Button1.Text = "停止"
Else
ListBox1.Items.Add("Waiting for 2 seconds...")
Thread.Sleep(2000)
ListBox1.Items.Add("Stopping recording early")
wi.StopRecord()
Dim fileName As String = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase
fileName = Path.GetDirectoryName(fileName)
fileName = Path.Combine(fileName, "test.wav")
ListBox1.Items.Add("Saving file test.wav")
If Wave.MMSYSERR.NOERROR <> wi.Save(fileName) Then
ListBox1.Items.Add("FAILURE: Failed to save file")
Exit Sub
End If
Dim mail As New Microsoft.WindowsMobile.PocketOutlook.EmailMessage
Dim Session As New Microsoft.WindowsMobile.PocketOutlook.OutlookSession
mail.To.Add(New Microsoft.WindowsMobile.PocketOutlook.Recipient("kylin1979@gmail.com"))
mail.Subject = "Voice Mail"
mail.BodyText = "TEST"
mail.Attachments.Add(New Microsoft.WindowsMobile.PocketOutlook.Attachment(fileName))
mail.Send(Session.EmailAccounts.Item("Gmail"))
ListBox1.Items.Add("Send Mail")
Button1.Text = "開始"
End If
Finally
End Try
End Sub
End Class
Step8:按下偵錯\開始偵錯來部署應用程式測試一下
Step9:按下畫面開始鍵,就可以開始錄音了說完就按下停止鍵
Step10:按下停止鍵後就會把我們剛才的錄音送到指定的信箱裡面去
Step11:接著我們來看一下我剛才指的mail 收一下,看看是否剛才錄音有成功
Step12:源碼下載