J'aimerai à partir de la classe ci-dessous enregistrer le son provenant du micro.
Pouvez-vous me dire ce que je dois mettre dans le boutton REC.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
 private void button4_Click(object sender, EventArgs e)
        {
      ??????
        }
Merci d'avance


Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
 
using System;
using System.Runtime.InteropServices;	// To use DLLImport	
using System.Text;						// To use SrtingBuilders
using System.Threading;					// To use threads
using System.IO;						// To use files
 
// Other classes
 
 
namespace VoiceStreamsFunctions 
{
	/// <summary>
	/// VoiceStreamsFunctions = it containes the functions related to retrieve the voice and saves it in a wave file to test the signal quality
	/// </summary>
 
	#region Aliases
		using HWAVEIN	= System.IntPtr;	// Handler on Input Wave
		// using HWAVEOUT	= System.IntPtr;	// Handler on Output Wave, not used up to now
		using WAVEHDR	= System.IntPtr;	// Pointer on a structure of a Wave file
	#endregion
 
	#region Wave Format Tag
	public enum WaveFormatTag : ushort
	{
		UNKNOWN                    = 0x0000, /* Microsoft Corporation */
		PCM						   = 0x0001, /* Microsoft Corporation */
		ADPCM                      = 0x0002, /* Microsoft Corporation */
		IEEE_FLOAT                 = 0x0003, /* Microsoft Corporation */
		VSELP                      = 0x0004, /* Compaq Computer Corp. */
		IBM_CVSD                   = 0x0005, /* IBM Corporation */
		ALAW                       = 0x0006, /* Microsoft Corporation */
		MULAW                      = 0x0007, /* Microsoft Corporation */
		DTS                        = 0x0008, /* Microsoft Corporation */
		DRM                        = 0x0009, /* Microsoft Corporation */
		OKI_ADPCM                  = 0x0010, /* OKI */
		DVI_ADPCM                  = 0x0011, /* Intel Corporation */
		IMA_ADPCM                  = (DVI_ADPCM), /*  Intel Corporation */
		MEDIASPACE_ADPCM           = 0x0012, /* Videologic */
		SIERRA_ADPCM               = 0x0013, /* Sierra Semiconductor Corp */
		G723_ADPCM                 = 0x0014, /* Antex Electronics Corporation */
		DIGISTD                    = 0x0015, /* DSP Solutions, Inc. */
		DIGIFIX                    = 0x0016, /* DSP Solutions, Inc. */
		DIALOGIC_OKI_ADPCM         = 0x0017, /* Dialogic Corporation */
		MEDIAVISION_ADPCM          = 0x0018, /* Media Vision, Inc. */
		CU_CODEC                   = 0x0019, /* Hewlett-Packard Company */
		YAMAHA_ADPCM               = 0x0020, /* Yamaha Corporation of America */
		SONARC                     = 0x0021, /* Speech Compression */
		DSPGROUP_TRUESPEECH        = 0x0022, /* DSP Group, Inc */
		ECHOSC1                    = 0x0023, /* Echo Speech Corporation */
		AUDIOFILE_AF36             = 0x0024, /* Virtual Music, Inc. */
		APTX                       = 0x0025, /* Audio Processing Technology */
		AUDIOFILE_AF10             = 0x0026, /* Virtual Music, Inc. */
		PROSODY_1612               = 0x0027, /* Aculab plc */
		LRC                        = 0x0028, /* Merging Technologies S.A. */
		DOLBY_AC2                  = 0x0030, /* Dolby Laboratories */
		GSM610                     = 0x0031, /* Microsoft Corporation */
		MSNAUDIO                   = 0x0032, /* Microsoft Corporation */
		ANTEX_ADPCME               = 0x0033, /* Antex Electronics Corporation */
		CONTROL_RES_VQLPC          = 0x0034, /* Control Resources Limited */
		DIGIREAL                   = 0x0035, /* DSP Solutions, Inc. */
		DIGIADPCM                  = 0x0036, /* DSP Solutions, Inc. */
		CONTROL_RES_CR10           = 0x0037, /* Control Resources Limited */
		NMS_VBXADPCM               = 0x0038, /* Natural MicroSystems */
		CS_IMAADPCM                = 0x0039, /* Crystal Semiconductor IMA ADPCM */
		ECHOSC3                    = 0x003A, /* Echo Speech Corporation */
		ROCKWELL_ADPCM             = 0x003B, /* Rockwell International */
		ROCKWELL_DIGITALK          = 0x003C, /* Rockwell International */
		XEBEC                      = 0x003D, /* Xebec Multimedia Solutions Limited */
		G721_ADPCM                 = 0x0040, /* Antex Electronics Corporation */
		G728_CELP                  = 0x0041, /* Antex Electronics Corporation */
		MSG723                     = 0x0042, /* Microsoft Corporation */
		MPEG                       = 0x0050, /* Microsoft Corporation */
		RT24                       = 0x0052, /* InSoft, Inc. */
		PAC                        = 0x0053, /* InSoft, Inc. */
		MPEGLAYER3                 = 0x0055, /* ISO/MPEG Layer3 Format Tag */
		LUCENT_G723                = 0x0059, /* Lucent Technologies */
		CIRRUS                     = 0x0060, /* Cirrus Logic */
		ESPCM                      = 0x0061, /* ESS Technology */
		VOXWARE                    = 0x0062, /* Voxware Inc */
		CANOPUS_ATRAC              = 0x0063, /* Canopus, co., Ltd. */
		G726_ADPCM                 = 0x0064, /* APICOM */
		G722_ADPCM                 = 0x0065, /* APICOM */
		DSAT_DISPLAY               = 0x0067, /* Microsoft Corporation */
		VOXWARE_BYTE_ALIGNED       = 0x0069, /* Voxware Inc */
		VOXWARE_AC8                = 0x0070, /* Voxware Inc */
		VOXWARE_AC10               = 0x0071, /* Voxware Inc */
		VOXWARE_AC16               = 0x0072, /* Voxware Inc */
		VOXWARE_AC20               = 0x0073, /* Voxware Inc */
		VOXWARE_RT24               = 0x0074, /* Voxware Inc */
		VOXWARE_RT29               = 0x0075, /* Voxware Inc */
		VOXWARE_RT29HW             = 0x0076, /* Voxware Inc */
		VOXWARE_VR12               = 0x0077, /* Voxware Inc */
		VOXWARE_VR18               = 0x0078, /* Voxware Inc */
		VOXWARE_TQ40               = 0x0079, /* Voxware Inc */
		SOFTSOUND                  = 0x0080, /* Softsound, Ltd. */
		VOXWARE_TQ60               = 0x0081, /* Voxware Inc */
		MSRT24                     = 0x0082, /* Microsoft Corporation */
		G729A                      = 0x0083, /* AT&T Labs, Inc. */
		MVI_MVI2                   = 0x0084, /* Motion Pixels */
		DF_G726                    = 0x0085, /* DataFusion Systems (Pty) (Ltd) */
		DF_GSM610                  = 0x0086, /* DataFusion Systems (Pty) (Ltd) */
		ISIAUDIO                   = 0x0088, /* Iterated Systems, Inc. */
		ONLIVE                     = 0x0089, /* OnLive! Technologies, Inc. */
		SBC24                      = 0x0091, /* Siemens Business Communications Sys */
		DOLBY_AC3_SPDIF            = 0x0092, /* Sonic Foundry */
		MEDIASONIC_G723            = 0x0093, /* MediaSonic */
		PROSODY_8KBPS              = 0x0094, /* Aculab plc */
		ZYXEL_ADPCM                = 0x0097, /* ZyXEL Communications, Inc. */
		PHILIPS_LPCBB              = 0x0098, /* Philips Speech Processing */
		PACKED                     = 0x0099, /* Studer Professional Audio AG */
		MALDEN_PHONYTALK           = 0x00A0, /* Malden Electronics Ltd. */
		RHETOREX_ADPCM             = 0x0100, /* Rhetorex Inc. */
		IRAT                       = 0x0101, /* BeCubed Software Inc. */
		VIVO_G723                  = 0x0111, /* Vivo Software */
		VIVO_SIREN                 = 0x0112, /* Vivo Software */
		DIGITAL_G723               = 0x0123, /* Digital Equipment Corporation */
		SANYO_LD_ADPCM             = 0x0125, /* Sanyo Electric Co., Ltd. */
		SIPROLAB_ACEPLNET          = 0x0130, /* Sipro Lab Telecom Inc. */
		SIPROLAB_ACELP4800         = 0x0131, /* Sipro Lab Telecom Inc. */
		SIPROLAB_ACELP8V3          = 0x0132, /* Sipro Lab Telecom Inc. */
		SIPROLAB_G729              = 0x0133, /* Sipro Lab Telecom Inc. */
		SIPROLAB_G729A             = 0x0134, /* Sipro Lab Telecom Inc. */
		SIPROLAB_KELVIN            = 0x0135, /* Sipro Lab Telecom Inc. */
		G726ADPCM                  = 0x0140, /* Dictaphone Corporation */
		QUALCOMM_PUREVOICE         = 0x0150, /* Qualcomm, Inc. */
		QUALCOMM_HALFRATE          = 0x0151, /* Qualcomm, Inc. */
		TUBGSM                     = 0x0155, /* Ring Zero Systems, Inc. */
		MSAUDIO1                   = 0x0160, /* Microsoft Corporation */
		UNISYS_NAP_ADPCM           = 0x0170, /* Unisys Corp. */
		UNISYS_NAP_ULAW            = 0x0171, /* Unisys Corp. */
		UNISYS_NAP_ALAW            = 0x0172, /* Unisys Corp. */
		UNISYS_NAP_16K             = 0x0173, /* Unisys Corp. */
		CREATIVE_ADPCM             = 0x0200, /* Creative Labs, Inc */
		CREATIVE_FASTSPEECH8       = 0x0202, /* Creative Labs, Inc */
		CREATIVE_FASTSPEECH10      = 0x0203, /* Creative Labs, Inc */
		UHER_ADPCM                 = 0x0210, /* UHER informatic GmbH */
		QUARTERDECK                = 0x0220, /* Quarterdeck Corporation */
		ILINK_VC                   = 0x0230, /* I-link Worldwide */
		RAW_SPORT                  = 0x0240, /* Aureal Semiconductor */
		ESST_AC3                   = 0x0241, /* ESS Technology, Inc. */
		IPI_HSX                    = 0x0250, /* Interactive Products, Inc. */
		IPI_RPELP                  = 0x0251, /* Interactive Products, Inc. */
		CS2                        = 0x0260, /* Consistent Software */
		SONY_SCX                   = 0x0270, /* Sony Corp. */
		FM_TOWNS_SND               = 0x0300, /* Fujitsu Corp. */
		BTV_DIGITAL                = 0x0400, /* Brooktree Corporation */
		QDESIGN_MUSIC              = 0x0450, /* QDesign Corporation */
		VME_VMPCM                  = 0x0680, /* AT&T Labs, Inc. */
		TPC                        = 0x0681, /* AT&T Labs, Inc. */
		OLIGSM                     = 0x1000, /* Ing C. Olivetti & C., S.p.A. */
		OLIADPCM                   = 0x1001, /* Ing C. Olivetti & C., S.p.A. */
		OLICELP                    = 0x1002, /* Ing C. Olivetti & C., S.p.A. */
		OLISBC                     = 0x1003, /* Ing C. Olivetti & C., S.p.A. */
		OLIOPR                     = 0x1004, /* Ing C. Olivetti & C., S.p.A. */
		LH_CODEC                   = 0x1100, /* Lernout & Hauspie */
		NORRIS                     = 0x1400, /* Norris Communications, Inc. */
		SOUNDSPACE_MUSICOMPRESS    = 0x1500, /* AT&T Labs, Inc. */
		DVM                        = 0x2000, /* FAST Multimedia AG */
 
		EXTENSIBLE                 = 0xFFFE /* Microsoft */
	}
	#endregion
 
	public class VoiceFunction 
	{
		#region DLL Import
		/// <summary>
		/// DLL Import :
		/// There are many because we use the CLS Multimedia functions.
		/// </summary>
 
		[DllImport ("winmm.dll")]		
		public static extern int mciSendString(String s1, StringBuilder s2, int l1, int l2);		// Multimedia Control Interface : Command Line
		[DllImport ("winmm.dll")]		
		public static extern int mciGetErrorString(int l1, StringBuilder s1, int l2);				// Error Handler
 
		[DllImport ("winmm.dll")]																	// Open the communication with the MIC
		public static extern int waveInOpen(out IntPtr hWaveIn, int uDeviceID, ref WAVEFORMATEX lpFormat, FunctionDelegate dwCallback, IntPtr dwInstance, int dwFlags);
		// hWaveIn is a pointer to the handler
		// lpFormat is a pointer to WAVEFORMATEX structure
		// dwCallback specifies the address of the callback function
		// dwInstance specifies user-instance data passed to the callback mechanism
		// dwFlags is a flag for opening the device
 
		[DllImport ("winmm.dll")]
		public static extern int waveInStart( IntPtr hWaveIn );										// Starts recording
		[DllImport ("winmm.dll")]	
		public static extern int waveInAddBuffer (IntPtr hWaveIn, ref WAVEHDR pWaveHDR, uint cbwh);	// Buffer Handler
		[DllImport ("winmm.dll")]	
		public static extern int waveInStop( IntPtr hWaveIn );										// Stop recording
		[DllImport ("winmm.dll")]	
		public static extern int waveInClose(IntPtr hWaveIn);										// Close the communication with the MIC
		[DllImport ("winmm.dll")]	
		public static extern int waveInPrepareHeader(IntPtr hWaveIn, ref WAVEHDR pWaveHDR, uint cbwh );		// Prepare the header to create a wave file
		[DllImport ("winmm.dll")]	
		public static extern int waveInUnprepareHeader( IntPtr hWaveIn, ref WAVEHDR pWaveHDR, uint cbwh );	 // Cleans up the header
		#endregion
 
		// Variables
		private string WorkingDir;					// Working directory
		private HWAVEIN hWaveIn;					// Handler to WAVEIN device
		private IntPtr dwInstance;					// Pointeur on callback instance
		private int dwFlags;						// Openning Flag : it will state that we use a callback function
		private WAVEFORMATEX StrcutWaveFMT;			// Wave format
		private WAVEHDR StructWaveHeader;			// Buffer handle
		private StringBuilder errorBuffer;			// Error Buffer
		private bool StillRecording;				// To check if we are currently recording or not
		private object MyLock;						// Lock for variable access in multi threads environment
		private GCHandle HeaderDataHandle;			// To recover data from unmanaged memory
		private int BufSize;						// Recording buffer
		private System.Windows.Forms.TextBox textBoxVFunct;	// I use the TextBox for debug
		private byte[] ByteArray;					// Array which contains A DATA CHUNK sent by the MIC
		private byte[] TempArray;					// Array which contains ALL THE DATA sent by the MIC
		private int n;								// index for storing in TempArray
		private int Index;							// index for storing in TempArray
		private char FileSize1;						// Variables to set the size of the recorded WAVE file
		private char FileSize2;
		private char FileSize3;
		private char FileSize4;
 
		// Callback
		public delegate void FunctionDelegate(IntPtr hWaveIn, uint Msg, int dwInstance, ref WAVEHDR dwParam1, int dwParam2);
		private FunctionDelegate dwCallback;
 
		#region ThreadHandle
			Thread RecordingThread;			// Thread which handles the recording
			Thread RecordHandleThread;		// It launches the record functions
		#endregion
 
		#region Constants
			private const int	WAVE_MAPPER			= -1;			// ID of the default MIC
			private const int	WHDR_PREPARED		= 0;			// States that buffers are prepared by windows multimedia function
			private const int	MM_WIM_OPEN			= 0x3BE;		// Message send by the audio device when it is opened by the application
			private const int	MM_WIM_CLOSE		= 0x3BF;		// Message send by the audio device when it is closed by the application
			private const int	MM_WIM_DATA			= 0x3C0;		// Message send by the audio device when a buffer is full
			private const int	CALLBACK_FUNCTION	= 0x30000;		// I specify that the callback is handled by a function (and not by a thread or whatever else)
			private const int	MaxRecord			= 5120000;		// FOR DEBUG ONLY !
		#endregion
 
		/// <summary>
		/// This structure is used to handle the recording buffers
		/// </summary>
		#region Struct WAVEHDR	
		public struct WAVEHDR
		{
			public IntPtr		lpData;					// Pointer to ByteArray, which is the array where a buffer of data is stored
			public int			dwBufferLength;			// Buffer length
			public int			dwBytesRecorded;		// Number of byte recorded, usually = Buffer length but the last one will be less
			public IntPtr  		dwUser;					// Not used
			public int			dwFlags;				// Specify the callback method, here a function
			public int			dwLoops;				// Only for output buffers
			public IntPtr		lpNext;					// Reserved
			public IntPtr		reserved;				// Reserved
 
			public static WAVEHDR Empty
			{
				get{return new WAVEHDR();}
			}
			public static int SizeOfEmptyWAVEHDR ()
			{
				return 28;
			}
		}
		#endregion 
 
		/// <summary>
		/// This structure is used to handle WAVE format
		/// </summary>
		#region Struct WAVEFORMATEX
		public struct WAVEFORMATEX
		{
			public WaveFormatTag	formatTag;			// here PCM
			public short			nChannels;			// here 1 >> mono
			public int				nSamplesPerSec;		// Here 11025, that's enougth
			public int				nAvgBytesPerSec;	// = nSamplesPerSec * nBlockAlign
			public short			nBlockAlign;		// = channels * (bits / 8)
			public short			wBitsPerSample;		// here 8
			public short			cbSize;				// 0, that represents the extra information size
			public byte				extraInfo;
 
			public WAVEFORMATEX(int rate, int bits, int channels)
			{
				formatTag		= WaveFormatTag.PCM;
				nChannels		= (short)channels;
				nSamplesPerSec	= rate;
				wBitsPerSample	= (short)bits;
				cbSize			= 0;
				nBlockAlign		= (short)(channels * (bits / 8));
				nAvgBytesPerSec = nSamplesPerSec * nBlockAlign;
				extraInfo		= 0;
			}
 
			public static WAVEFORMATEX Empty
			{
				get{return new WAVEFORMATEX();}
			}
 
			public static int SizeOfEmpty
			{
				get{return 18;}
			}
 
			public int SizeOf
			{
				get{return (SizeOfEmpty + cbSize);}
			}
		}
		#endregion
 
		// Initialise
		public VoiceFunction(string wdir, int BufferSize, System.Windows.Forms.TextBox textBox) 
		{
			this.WorkingDir						 = wdir;								// I set the working directory for my functions
			this.errorBuffer					 = new StringBuilder(128,128);			// Juste in case ;)
			this.hWaveIn						 = IntPtr.Zero;							// Handler to my audio device
			this.dwCallback						 = new FunctionDelegate(waveInProc);	// Pointeur on callback function
			this.dwInstance						 = IntPtr.Zero;							// not used
			this.dwFlags						 = CALLBACK_FUNCTION;					// constant value to express that the callback is made by a function 
			this.RecordingThread				 = new Thread(new ThreadStart( StartRec ));
			this.RecordingThread.Name			 = "PickUpSound";
			this.RecordHandleThread				 = new Thread(new ThreadStart( RecordHandle ));
			this.RecordHandleThread.Name		 = "RecordManager";
			this.StillRecording					 = false;
			this.BufSize						 = BufferSize;
			this.MyLock							 = new object();						// Lock for variable access in mutlithread environment
			this.TempArray						 = new byte[MaxRecord];					// I store everything and I will write in a file afterwards
			this.n								 = -1;									// index for recording
			this.Index							 = 0;									// index for recording
			this.textBoxVFunct					 = textBox;								// for debug
					// handle to the display class
		}
 
		// Record Launcher, called by the main
		public void RecordLauncher()
		{
			this.RecordHandleThread.Start();	// I launch the thread which will handle all the recording process from the preparation end of recording
		}
 
 
		// Record Handle
		private void RecordHandle()
		{
			int RetVal = 0;
 
			PrepareFormat();		// prepare the recording
			RetVal = OpenComm();	// Open the communication with the MIC
			if(RetVal ==1)
			{
				Record();			//	starts recording
			}
 
			// The end of the recording is handled by the user, when he clicks on the appropriate button
		}
 
 
		// Prepare the format
		private void PrepareFormat()
		{
			this.StrcutWaveFMT					= WAVEFORMATEX.Empty;
 
			// Init wave format
			this.StrcutWaveFMT.formatTag		= WaveFormatTag.PCM;	// I work with PCM format, because then we will process a codec and encapsulate the data in RTP streams
			this.StrcutWaveFMT.nChannels		= 1;					// MONO
			this.StrcutWaveFMT.nSamplesPerSec	= 11025;				// Samples per Second		
			this.StrcutWaveFMT.wBitsPerSample	= 8;					// Bits per Sample
			this.StrcutWaveFMT.nBlockAlign		= (short)(StrcutWaveFMT.nChannels * (StrcutWaveFMT.wBitsPerSample/8));
			this.StrcutWaveFMT.nAvgBytesPerSec	= StrcutWaveFMT.nSamplesPerSec * StrcutWaveFMT.nBlockAlign;
			this.StrcutWaveFMT.cbSize			= 0;
		}
 
		// Open the communication with the audio input device, error ID N°1
		private int OpenComm ()
		{
			int ReturnVal = 0;
 
			// WAVE_MAPPER is a constant defined in mmsystem.h at -1, it take the default MIC
			int err = waveInOpen(out this.hWaveIn, WAVE_MAPPER, ref this.StrcutWaveFMT, this.dwCallback, this.dwInstance, this.dwFlags);
			if (err != 0) 
			{				
				int retval = mciGetErrorString(err, errorBuffer, 128);
				this.textBoxVFunct.Text = "WaveIn error 1";
			}	
			else ReturnVal = 1;
			return(ReturnVal);
		}
 
		// Record, error ID N°3, 4 and 5
		private void Record ()
		{
			int RetVal = 0;
 
			Monitor.Enter(MyLock);
			RetVal = PrepareHeader ();		// Prepare the header of the first buffer; Error 3
			if(RetVal == 1)
			{
				PrepareBuffer ();			// Prepare the first buffer; Error 4
			}	
			Monitor.Exit(MyLock);
 
			// We create a thread to handle all the recording
			this.StillRecording = true;
			this.RecordingThread.Priority = ThreadPriority.Highest;
			this.RecordingThread.Start();	// Error 5
			this.RecordingThread.Join();
		} 
 
		// Prepare Header
		private int PrepareHeader ()
		{
			int RetVal = 0;
 
			this.StructWaveHeader				 = WAVEHDR.Empty;
			this.StructWaveHeader.dwBufferLength = BufSize;
			this.StructWaveHeader.dwFlags		 = WHDR_PREPARED;
 
			this.ByteArray = new byte[BufSize];		//This array will get all the data recorded by the MIC
			// Now I prepare the fact that we will deal with unmanaged data!
			// lpData is a pointer to this.ByteArray
			HeaderDataHandle = GCHandle.Alloc(this.ByteArray, GCHandleType.Pinned);
			this.StructWaveHeader.lpData = HeaderDataHandle.AddrOfPinnedObject();
			this.StructWaveHeader.dwUser = (IntPtr)GCHandle.Alloc(this);
 
			int IntTmp = Marshal.SizeOf(this.StructWaveHeader);
			uint UIntTmp = Convert.ToUInt32(IntTmp);
			int err = waveInPrepareHeader(this.hWaveIn, ref this.StructWaveHeader, UIntTmp);
			if (err != 0) 
			{				
				int retval = mciGetErrorString(err, errorBuffer, 128);
				this.textBoxVFunct.Text = "WaveIn error 3";
			}
			else RetVal = 1;		// Header prepared :)
			return(RetVal);
		}
 
		// Unprepare Header
		private void UnPrepareHeader()
		{
			// This functions has to be called once the data has been properly retrieved by the MIC and handled by the WaveInProc function
			// It cleans up everything
			int IntTmp = BufSize + WAVEHDR.SizeOfEmptyWAVEHDR();
			uint UIntTmp = Convert.ToUInt32(IntTmp);
			int err = waveInUnprepareHeader(this.hWaveIn, ref this.StructWaveHeader, UIntTmp);
			if (err != 0) 
			{				
				int retval = mciGetErrorString(err, errorBuffer, 128);
				this.textBoxVFunct.Text = "WaveIn error 6";
			}
		}
 
		// Prepare Buffer
		private void PrepareBuffer ()
		{
			// This function sends the buffer to the MIC
			int IntTmp = BufSize + WAVEHDR.SizeOfEmptyWAVEHDR();
			uint UIntTmp = Convert.ToUInt32(IntTmp);
			int err = waveInAddBuffer(this.hWaveIn, ref this.StructWaveHeader, UIntTmp);
			if (err != 0) 
			{				
				int retval = mciGetErrorString(err, errorBuffer, 128);
				this.textBoxVFunct.Text = "WaveIn error 4";
			}
		}
 
		// Start Recording
		private void StartRec ()
		{
			Monitor.Enter(MyLock);
				int err = waveInStart(this.hWaveIn);
				if (err != 0) 
				{				
					int retval = mciGetErrorString(err, errorBuffer, 128);
					this.textBoxVFunct.Text = "WaveIn error 5";
				}
			Monitor.Exit(MyLock);
		}
 
 
		// Listens to the message that the audio device sends
		// It enables to retreive the data when a buffer has been filled
		//
		// hWaveIn is the handle on the open MIC
		// dwInstance is the instance on the communication, not used
		// dwParam1 is pointer to teh WAVEHDR structure which is returned by the MIC
		// dwParam2 has to be 0, it is only used by the system
		private void waveInProc(IntPtr hWaveIn, uint Msg, int dwInstance, ref WAVEHDR dwParam1, int dwParam2)
		{
			/*
				ATTENTION:
				Don't call any system-function in waveInProc
			*/
			int correcting_factor = 0;
 
			switch(Msg)
			{
				case MM_WIM_DATA:
					if (this.StillRecording == true)	// we are still recording
					{
						this.n++;
						for (int i = 0; i<dwParam1.dwBytesRecorded; i++)
						{
							this.Index = (BufSize*this.n)+i;						// Current index on the TempArray
							correcting_factor = (int)this.ByteArray[i];				// I have to modify the value to improve the signal quality
							correcting_factor = (int)(correcting_factor/2);			// To improve voice quality
							this.TempArray[this.Index] = (byte)correcting_factor;	// I save the data
 
						}								
 
						// Prepare the next stage of recording
						UnPrepareHeader();
						dwParam1.lpData = IntPtr.Zero;
						dwParam1.dwBytesRecorded = 0;
						HeaderDataHandle.Free();
 
						// We now sent another buffer to capture more data chunks
						PrepareHeader ();
						PrepareBuffer ();												
					}
					break;
 
				case MM_WIM_OPEN:					// Message sent when the device has been opened
					break;
 
				case MM_WIM_CLOSE:					// Message sent when the device has been closed
					this.HeaderDataHandle.Free();	// I free the handle
					break;
 
				default:							// I never saw that happening ...
					this.textBoxVFunct.Text = "Unknonw message sent by the MIC";
					break;
			}	
		}
 
 
		// Close communication, error ID N°2 and 6
		public int CloseComm ()
		{
			int RetVal = 0;
 
			// Stop Recording
			this.StillRecording = false;
			this.RecordHandleThread.Abort();
 
 
			// We Stop the recording, error ID N°6
			int err = waveInStop(this.hWaveIn);
			if (err != 0) 
			{				
				int retval = mciGetErrorString(err, errorBuffer, 128);
				this.textBoxVFunct.Text = "WaveIn error 7";
			}
			else
			{
				// We close the communication with the MIC, error ID N°2
				err = waveInClose(this.hWaveIn);
				if (err != 0) 
				{				
					int retval = mciGetErrorString(err, errorBuffer, 128);
					this.textBoxVFunct.Text = "WaveIn error 2";
				}
				else
				{
					RetVal = 1;
					// free the allocated memory
					this.errorBuffer			= null;
					this.dwCallback				= null;
					this.MyLock					= null;
 
					// Now I write the file with the data I have just recorded
					PrepareFile();
				}
			}
 
			return(RetVal);
		}
 
		/// <summary>
		///  When you record a WAVE file you have to enter its lenght in the header
		///  This lenght has to be writen in Hexadecimal values and in the reverse order ...
		///  This function takes as input the INT value to convert
		///  It converts in in hexa and then prepare the variables to write into the file
		/// </summary>
		#region ConvertToHexa
		private void ConvertToHexa(int IntToConvert)
		{
			int Current = IntToConvert;
			char[] rank = new char[8];
			int i = 0;
			char temp;
			int b = 0;
 
			do
			{
				rank[i] = (char)(Current%16);	// it returns the rest of the division Current/16 and multiply it by 16, it will always be an integer
				Current = (int)(Current/16);
				i++;
			}while(Current>16);
			rank[i] = (char)(Current);
			if (i<7)
			{
				do{
					rank[i] = (char)0;			// I fill the table
				}while(i==7);
			}
 
			// invert the values in rank[] to prepare the variable to write into the file
			for(int a=i;a>=b;a--)
			{
				temp = rank[a];
				rank[a] = rank[b];
				rank[b] = temp;
				b++;
			}
 
			// I had F and A I want FA, so I merge my variables 2 by 2
			this.FileSize1 = (char)(rank[6]*16 + rank[7]);
			this.FileSize2 = (char)(rank[4]*16 + rank[5]);
			this.FileSize3 = (char)(rank[2]*16 + rank[3]);
			this.FileSize4 = (char)(rank[0]*16 + rank[1]);
		}
		#endregion
 
		#region Write the recorded WAVE
		private void PrepareFile()
		{
			// File handling
			Directory.CreateDirectory(this.WorkingDir);
			string FileToCreate		= this.WorkingDir + "/AudioFile.wav";	
			StreamWriter AudioFile	= new StreamWriter(FileToCreate,false,ASCIIEncoding.Default,1024);	
			this.WorkingDir			= null;
 
			char FormatLen1 = (char)0x10;			// size of the header chunk
			char FormatLen2 = (char)0x0;
			char FormatLen3 = (char)0x0;
			char FormatLen4 = (char)0x0;
			char AudioFormat1 = (char)0x1;			// PCM
			char AudioFormat2 = (char)0x0;
			char channel1 = (char)0x1;				// channel
			char channel2 = (char)0x0;
			char SampleRate1 = (char)0x11;			// sample rate
			char SampleRate2 = (char)0x2B;
			char SampleRate3 = (char)0x0;			
			char SampleRate4 = (char)0x0;
			char BlockAlign1 = (char)0x1;
			char BlockAlign2 = (char)0x0;
			char BitsPerSample1 = (char)0x8;
			char BitsPerSample2 = (char)0x0;
 
			// copy of the header
			//RIFF CHUNK
			AudioFile.Write("RIFF");				// RIFF
			ConvertToHexa(this.Index+44);
			AudioFile.Write(this.FileSize1);		// size of the entire WAVE file
			AudioFile.Write(this.FileSize2);
			AudioFile.Write(this.FileSize3);
			AudioFile.Write(this.FileSize4);
 
 
			AudioFile.Write("WAVE");				// WAVE
			// Format Chunk
			AudioFile.Write("fmt ");				// fmt_
			AudioFile.Write(FormatLen1);			// 16 : subchunk size
			AudioFile.Write(FormatLen2);
			AudioFile.Write(FormatLen3);
			AudioFile.Write(FormatLen4);
			AudioFile.Write(AudioFormat1);			// PCM
			AudioFile.Write(AudioFormat2);
			AudioFile.Write(channel1);				// MONO
			AudioFile.Write(channel2);
			AudioFile.Write(SampleRate1);			// 11025 Hz
			AudioFile.Write(SampleRate2);
			AudioFile.Write(SampleRate3);
			AudioFile.Write(SampleRate4);
			AudioFile.Write(SampleRate1);			// Byte rate, here is the same as sample rate
			AudioFile.Write(SampleRate2);
			AudioFile.Write(SampleRate3);
			AudioFile.Write(SampleRate4);
			AudioFile.Write(BlockAlign1);			// block align 
			AudioFile.Write(BlockAlign2);
			AudioFile.Write(BitsPerSample1);		// 8 bits per sample
			AudioFile.Write(BitsPerSample2);
			// data chunk
			AudioFile.Write("data");				// data
			ConvertToHexa(this.Index);
			AudioFile.Write(this.FileSize1);		// size of the data
			AudioFile.Write(this.FileSize2);
			AudioFile.Write(this.FileSize3);
			AudioFile.Write(this.FileSize4);
 
			// data
			for(int i=0; i<this.Index;i++)
			{
				AudioFile.Write((char)this.TempArray[i]);		// file writing
			}
 
			AudioFile.Close();
 
		}
		#endregion
 
		// destructor
		~VoiceFunction()
		{			
				// job's done
		}
	} // End of class VoiceFunction 
} // End of namespace