С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/48: Рейтинг темы: голосов - 48, средняя оценка - 4.54
7 / 7 / 1
Регистрация: 16.01.2012
Сообщений: 95

Передача звука по сети по протоколу UDP (FullDuplex)

05.04.2012, 20:35. Показов 10116. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.
Пишется программа по передачи различной информации по сети.
Вот дошло дело до звука...
Сначала был написан пробный код на Borland С++, вот он :

Клиент - воспроизводит полученный звук на динамик
C++
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
#include <vcl.h>
#include <stdio.h>
#pragma hdrstop
 
#include "FormMain.h"
//-----------------
#include <mmsystem.h>
#include <mmreg.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------
WAVEFORMATEX WavFormat;
WAVEHDR      WavHdr[16];
HWAVEOUT     Out;
 
unsigned int BufferSize;
short        CurrentBufferNum = 0;
short        BuffersCount = 8;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
        : TForm(Owner)
{
}
//================================================================================
void SaveExceptionToFile(char *msg, ... )
{
AnsiString      asErrorLogFileName = "MicServer.dat"; 
HANDLE          hErrorLogFile;
DWORD           SendBytes;
AnsiString      asFileName = ExtractFilePath(ParamStr(0)) + asErrorLogFileName;
char            ErrorStr[1024];
va_list ap;
 
   memset(ErrorStr,0,sizeof(ErrorStr));
   va_start( ap, msg ); vsprintf( ErrorStr, msg, ap ); va_end( ap );
   if( strlen(ErrorStr) == 0 )
     return;
   hErrorLogFile = CreateFile(asFileName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS , 0, NULL );
   SetFilePointer(hErrorLogFile,0,NULL,FILE_END);
   WriteFile(hErrorLogFile,ErrorStr,StrLen(ErrorStr),&SendBytes,NULL);
   CloseHandle(hErrorLogFile);
 
return;
}
//================================================================================
void PlayBuffer(TStream &Stream)
{
  while(CurrentBufferNum != BuffersCount)
   {
    if(WavHdr[CurrentBufferNum].dwUser == 0)
     {
      Stream.Read(WavHdr[CurrentBufferNum].lpData,BufferSize);
      waveOutPrepareHeader(Out,&WavHdr[CurrentBufferNum],sizeof(WavHdr));
      waveOutWrite(Out,&WavHdr[CurrentBufferNum],sizeof(WavHdr));
      WavHdr[CurrentBufferNum].dwFlags = 0;
      WavHdr[CurrentBufferNum].dwBufferLength = BufferSize;
      WavHdr[CurrentBufferNum].dwBytesRecorded = 0;
      WavHdr[CurrentBufferNum].dwUser = 0;
      WavHdr[CurrentBufferNum].dwLoops = 1;
      WavHdr[CurrentBufferNum].dwFlags = WHDR_INQUEUE;
      CurrentBufferNum ++;
      return;
     }
   }
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
int i;
int Res;
 
  WavFormat.wFormatTag = WAVE_FORMAT_PCM;
  WavFormat.nChannels = 1;
  WavFormat.wBitsPerSample = 8;
  WavFormat.nBlockAlign = 1;
  WavFormat.nSamplesPerSec = 8000;
  WavFormat.nAvgBytesPerSec = WavFormat.nSamplesPerSec * WavFormat.nBlockAlign;
  WavFormat.cbSize = 0;
 
  BufferSize = (WavFormat.nAvgBytesPerSec*2)/16;
 
  for(i=0;i<BuffersCount;i++)
   {
    WavHdr[i].dwFlags = WHDR_INQUEUE;
    WavHdr[i].dwBufferLength = BufferSize;
    WavHdr[i].dwBytesRecorded = 0;
    WavHdr[i].dwUser = 0;
    WavHdr[i].dwLoops = 1;
    WavHdr[i].lpData = StrAlloc(BufferSize);//(char *)GlobalAlloc(GMEM_FIXED,BufferSize);
   }
  Res = waveOutOpen(&Out,0/*WAVE_MAPPER*/,&WavFormat,(DWORD)MainForm->Handle,0,CALLBACK_WINDOW);
  if(Res != MMSYSERR_NOERROR)
   {
    Application->MessageBoxA("Error OutOpen", 0);
   }
  IdUDPServer->BufferSize = BufferSize;
  IdUDPServer->DefaultPort = 10090;
  IdUDPServer->Active = false;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
{
  IdUDPServer->Active = false;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::Button1Click(TObject *Sender)
{
  IdUDPServer->Active = !IdUDPServer->Active;
  if(IdUDPServer->Active == false)
   Button1->Caption = "Off";
  else
   Button1->Caption = "On";
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::IdUDPServerUDPRead(TObject *Sender, TStream *AData, TIdSocketHandle *ABinding)
{
  if(CurrentBufferNum == BuffersCount)
    CurrentBufferNum = 0;
 
  PlayBuffer(*AData);
}
//---------------------------------------------------------------------------
Сервер - снимает звук с микрофона и передает клиенту

C++
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
#include <vcl.h>
#include <stdio.h>
//-----------------
#include <mmsystem.h>
#include <mmreg.h>
//-----------------
#pragma hdrstop
 
#include "FormMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
//----------------------------------
WAVEFORMATEX WavFormat;
WAVEHDR WavHdr;
HWAVEIN In;
 
unsigned int BufferSize;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
        : TForm(Owner)
{
}
//================================================================================
void SaveExceptionToFile(char *msg, ... )
{
AnsiString      asErrorLogFileName = "MicServer.dat"; 
HANDLE          hErrorLogFile;
DWORD           SendBytes;
AnsiString      asFileName = ExtractFilePath(ParamStr(0)) + asErrorLogFileName;
char            ErrorStr[1024];
va_list ap;
 
   memset(ErrorStr,0,sizeof(ErrorStr));
   va_start( ap, msg ); vsprintf( ErrorStr, msg, ap ); va_end( ap );
   if( strlen(ErrorStr) == 0 )
     return;
   hErrorLogFile = CreateFile(asFileName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS , 0, NULL );
   SetFilePointer(hErrorLogFile,0,NULL,FILE_END);
   WriteFile(hErrorLogFile,ErrorStr,StrLen(ErrorStr),&SendBytes,NULL);
   CloseHandle(hErrorLogFile);
 
return;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
int Res;
 
  
  WavFormat.wFormatTag = WAVE_FORMAT_PCM;
  WavFormat.nChannels = 1;
  WavFormat.wBitsPerSample = 8;
  WavFormat.nBlockAlign = 1;
  WavFormat.nSamplesPerSec = 8000;
  WavFormat.nAvgBytesPerSec = WavFormat.nSamplesPerSec * WavFormat.nBlockAlign;
  WavFormat.cbSize = 0;
 
  BufferSize = (WavFormat.nAvgBytesPerSec*2)/16;
 
  Res = waveInOpen(&In,0/*WAVE_MAPPER*/,&WavFormat,(DWORD)MainForm->Handle,0,CALLBACK_WINDOW);
  if(Res != MMSYSERR_NOERROR)
   {
    Application->MessageBoxA("Error InOpen", 0);
   }
 
  WavHdr.lpData = (char *)GlobalAlloc(GMEM_FIXED,BufferSize);
  WavHdr.dwBufferLength = BufferSize;
  WavHdr.dwFlags = 0;
 
  IdUDPClient->BufferSize = BufferSize;
  IdUDPClient->Port = 10090;
  IdUDPClient->Active = false;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
{
  IdUDPClient->Active = false;
  waveInClose(In);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::WavMessage(TMessage &Msg)
{
  waveInPrepareHeader(In,&WavHdr,sizeof(WavHdr));
  waveInAddBuffer(In,&WavHdr,sizeof(WavHdr));
 
  IdUDPClient->SendBuffer(WavHdr.lpData,WavHdr.dwBufferLength);
 
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::Button1Click(TObject *Sender)
{
  if(IdUDPClient->Active == false)
   {
    Button1->Caption = "Stop";
    IdUDPClient->Host = Edit1->Text;
    waveInPrepareHeader(In,&WavHdr,sizeof(WavHdr));
    waveInAddBuffer(In,&WavHdr,sizeof(WavHdr));
 
    IdUDPClient->Active = true;
 
    waveInStart(In);
   }
  else
   {
    Button1->Caption = "Start";
 
    IdUDPClient->Active = false;
 
    waveInUnprepareHeader(In,&WavHdr,sizeof(WavHdr));
    waveInStop(In);
   }
}
Все прекрасно работает.
Но так как основная программа пишется на С# был вынужден написать следующие:

Библbотека SoundLib
C#
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
//----------------------------------------------
//using Microsoft.DirectX;
using Microsoft.DirectX.AudioVideoPlayback;
//----------------------------------------------
using System.Runtime.InteropServices;
//----------------------------------------------
 
namespace SoundLib
{
    public class Sound : IDisposable
    {
        #region ----- Constant -----
        public const uint WAVE_MAPPER = unchecked((uint)(-1));
        public const int MMSYSERR_NOERROR = 0;
        public const int MM_WOM_OPEN = 0x3BB;
        public const int MM_WOM_CLOSE = 0x3BC;
        public const int MM_WOM_DONE = 0x3BD;
        public const int MM_WIM_OPEN = 0x3BE;
        public const int MM_WIM_CLOSE = 0x3BF;
        public const int MM_WIM_DATA = 0x3C0;
        public const int CALLBACK_FUNCTION = 0x00030000;
        public const int CALLBACK_WINDOW = 0x00010000;
        public const int CALLBACK_TASK = 0x00020000;
        public const int CALLBACK_EVENT = 0x00050000;
        public const int TIME_MS = 0x0001;
        public const int TIME_SAMPLES = 0x0002;
        public const int TIME_BYTES = 0x0004;
        #endregion
 
        #region ----- Validation ------
        // ---------------------- Кулбак --------------------------------------
        public delegate void WaveCallbackProc(IntPtr hwi, WimMessageType uMsg, IntPtr dwInstance, IntPtr dwParam1, IntPtr dwParam2);
        //--------------------------
        public static Audio AudioPlayer;
        public static string[] InDeviceName;
        public static string[] OutDeviceName;
        public static byte InDeviceCount;
        public static byte OutDeviceCount;
        public static IntPtr hWaveIn;
        public static IntPtr hWaveOut;
        public static WAVEFORMATEX waveFormat;
        public static WAVEHDR waveInHeader;
        public static WAVEHDR[] waveOutHeader = new WAVEHDR[16];
        public static int BufferSize = 0;
        //----------------
        public static short CurrentBufferNum = 0;
        public static short BuffersCount = 8;
 
        #endregion
 
        #region ----- Enums -----
        public enum WimMessageType : uint
        {
            OpenIn = 0x3BE,  
            CloseIn = 0x3BF,
            DataIn = 0x3C0,
 
            OpenOut = 0x3BB,
            CloseOut = 0x3BC,
            DataOut = 0x3BD
        }
        public enum SoundState : byte
        {
            None = 1,
            Present,
            Ring,
            Call,
            WaitAnswerOnCommand,
            Start,
            Stop
        }
        #endregion
        
        #region ----- Struct ------
        [StructLayout( LayoutKind.Sequential )]
        public struct WAVEHDR
        {
            public IntPtr lpData;
            public int    dwBufferLength;
            public int    dwBytesRecorded;
            public IntPtr dwUser;
            public int    dwFlags;
            public int    dwLoops;
            public IntPtr lpNext;
            public IntPtr reserved;
        }
 
        [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Unicode )]
        public struct WAVEINCAPS
        {
            public short  wMid;
            public short  wPid;
            public uint   vDriverVersion;
            [MarshalAs( UnmanagedType.ByValTStr, SizeConst = 128 )]
            public string szPname;
            public uint   dwFormats;
            public short  wChannels;
            public short  wReserved1;
            public uint   dwSupport;
        }
 
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct WAVEOUTCAPS
        {
            public short wMid;
            public short wPid;
            public uint vDriverVersion;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
            public string szPname;
            public uint dwFormats;
            public short wChannels;
            public short wReserved1;
            public uint dwSupport;
        }
 
        [StructLayout( LayoutKind.Sequential, Pack = 1 )] 
        public struct WAVEFORMATEX
        {
            public ushort FormatTag;
            public ushort Channels;
            public uint   SamplesPerSecond;
            public uint   AverageBytesPerSecond;
            public ushort BlockAlign;
            public ushort BitsPerSample;
            public ushort Size;                
        }
 
        [StructLayout(LayoutKind.Sequential)]
        public struct smpte
        {
            public byte hour;       /* hours */
            public byte min;        /* minutes */
            public byte sec;        /* seconds */
            public byte frame;      /* frames  */
            public byte fps;        /* frames per second */
            public byte dummy;      /* pad */
            public ushort pad;
        }
 
        [StructLayout(LayoutKind.Explicit)]
        public struct MMTIME
        {
            [FieldOffset(0)]
            public uint wType;      /* indicates the contents of the union */
            [FieldOffset(4)]
            public uint ms;         /* milliseconds */
            [FieldOffset(4)]
            public uint sample;     /* samples */
            [FieldOffset(4)]
            public uint cb;         /* byte count */
            [FieldOffset(4)]
            public uint ticks;      /* ticks in MIDI stream */
            [FieldOffset(4)]
            public smpte smpte;
            [FieldOffset(4)]
            public uint songptrpos; /* song pointer position */
        }
        #endregion
        
        #region ----- Share API from winmm.dll -----
        const string WINMM = "winmm.dll";
        #region ----- WaveOut -----
        [DllImport(WINMM, SetLastError = true)] public static extern int waveOutGetNumDevs();
        [DllImport(WINMM, SetLastError = true, CharSet = CharSet.Unicode)] public static extern int waveOutGetDevCaps(UIntPtr uDeviceID, out WAVEOUTCAPS lpCaps, int uSize);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveOutPrepareHeader(IntPtr hWaveOut, ref WAVEHDR lpWaveOutHdr, int uSize);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveOutUnprepareHeader(IntPtr hWaveOut, ref WAVEHDR lpWaveOutHdr, int uSize);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveOutWrite(IntPtr hWaveOut, ref WAVEHDR lpWaveOutHdr, int uSize);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveOutOpen(ref IntPtr hWaveOut, int DeviceID, ref WAVEFORMATEX lpFormat, IntPtr dwCallback, IntPtr dwInstance, uint dwFlags);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveOutReset(IntPtr hWaveOut);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveOutClose(IntPtr hWaveOut);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveOutPause(IntPtr hWaveOut);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveOutRestart(IntPtr hWaveOut);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveOutGetPosition(IntPtr hWaveOut, out MMTIME lpInfo, int uSize);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveOutSetVolume(IntPtr hWaveOut, uint dwVolume);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveOutGetVolume(IntPtr hWaveOut, out uint dwVolume);
        #endregion
 
        #region ----- WaveIn -----
        [DllImport(WINMM, SetLastError = true)] public static extern int waveInGetNumDevs();
        [DllImport(WINMM, SetLastError = true, CharSet = CharSet.Unicode)] public static extern int waveInGetDevCaps(UIntPtr uDeviceID, out WAVEINCAPS lpCaps, int uSize);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveInAddBuffer(IntPtr hwi, ref WAVEHDR pwh, int cbwh);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveInClose(IntPtr hwi);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveInOpen(ref IntPtr hWaveIn, int deviceId, ref WAVEFORMATEX wfx, IntPtr dwCallback, IntPtr dwInstance, uint dwFlags);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveInPrepareHeader(IntPtr hWaveIn, ref WAVEHDR lpWaveInHdr, int uSize);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveInUnprepareHeader(IntPtr hWaveIn, ref WAVEHDR lpWaveInHdr, int uSize);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveInReset(IntPtr hwi);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveInStart(IntPtr hwi);
        [DllImport(WINMM, SetLastError = true)] public static extern int waveInStop(IntPtr hwi);
        #endregion
        #endregion
 
        #region -------------------------- Main Init Sound Function -------------------------------
        public static void InitSound()
        {
         int i;
 
             try
            {
                //------------------ In
                if ((InDeviceCount = (byte)waveInGetNumDevs()) > 0)
                {
                    InDeviceName = new string[InDeviceCount];
                    var waveInCaps = new WAVEINCAPS();
                    int size = Marshal.SizeOf(waveInCaps);
 
                    for (i = 0; i < InDeviceCount; i++)
                    {
                        if (waveInGetDevCaps((UIntPtr)i, out waveInCaps, size) == MMSYSERR_NOERROR)
                            InDeviceName[i] = waveInCaps.szPname;
                    }
                }
                 //---------------- Out
                if ((OutDeviceCount = (byte)waveOutGetNumDevs()) > 0)
                {
                    OutDeviceName = new string[OutDeviceCount];
                    var waveOutCaps = new WAVEOUTCAPS();
                    int size = Marshal.SizeOf(waveOutCaps);
 
                    for (i = 0; i < OutDeviceCount; i++)
                    {
                        if (waveOutGetDevCaps((UIntPtr)i, out waveOutCaps, size) == MMSYSERR_NOERROR)
                            OutDeviceName[i] = waveOutCaps.szPname;
                    }
                }
                waveFormat.FormatTag = 1;
                waveFormat.Channels = 1;
                waveFormat.BitsPerSample = 8;
                waveFormat.SamplesPerSecond = 8000;
                waveFormat.BlockAlign = 1;
                waveFormat.AverageBytesPerSecond = waveFormat.SamplesPerSecond * waveFormat.BlockAlign;
                waveFormat.Size = 0;/* (ushort)Marshal.SizeOf(waveFormat);*/
 
                BufferSize = (int)(waveFormat.AverageBytesPerSecond * 2) / 16;
                //----------- Буферы --------------------
                for (i = 0; i < BuffersCount; i++)
                {
                    waveOutHeader[i].dwFlags = 0x10;//WHDR_INQUEUE;
                    waveOutHeader[i].dwBufferLength = BufferSize;
                    waveOutHeader[i].dwBytesRecorded = 0;
                    waveOutHeader[i].dwUser = IntPtr.Zero;
                    waveOutHeader[i].dwLoops = 1;
                    waveOutHeader[i].lpData = Marshal.AllocHGlobal(BufferSize);
                }
            }
            catch (ApplicationException)
            {
            }
        }
        //---------------------------------------------------------------
        public static void PlayWavFile(string FileName)
        {
            try
            {
                  if (!File.Exists(FileName)) return;
 
                  AudioPlayer = new Audio(FileName);
                  AudioPlayer.Play();
            }
            catch (ApplicationException) { }       
        }
        //----------------------------------------------------------------
        public static void StopPlayWavFile()
        {
            try
            {
                AudioPlayer.Stop();
                AudioPlayer.Dispose();
            }
            catch (ApplicationException) { }       
        
        }
        #endregion
 
        #region -------------------------- WavOut Function -----------------------------------------------
        public static int StartOutAudioDevice(int DeviceID, WaveCallbackProc OutCallBackFun)
        {
            if (waveOutOpen(ref hWaveOut, DeviceID, ref waveFormat, Marshal.GetFunctionPointerForDelegate(OutCallBackFun), IntPtr.Zero, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
                return -1;
 
         return 0;
        }
        //----------------------------------------------------
        public static void PlayBuffer(MemoryStream Stream)
        {
            while (CurrentBufferNum != BuffersCount)
            {
                if (waveOutHeader[CurrentBufferNum].dwUser == IntPtr.Zero)
                {
                    byte[] Buff = new byte[BufferSize+1];
                    Stream.Read(Buff,0,BufferSize);
                    Marshal.Copy(waveOutHeader[CurrentBufferNum].lpData, Buff, 0, BufferSize);
                    
                    waveOutPrepareHeader(hWaveOut, ref waveOutHeader[CurrentBufferNum], Marshal.SizeOf(typeof(WAVEHDR)));
                    waveOutWrite(hWaveOut, ref waveOutHeader[CurrentBufferNum], Marshal.SizeOf(typeof(WAVEHDR)));
                    waveOutHeader[CurrentBufferNum].dwFlags = 0;
                    waveOutHeader[CurrentBufferNum].dwBufferLength = BufferSize;
                    waveOutHeader[CurrentBufferNum].dwBytesRecorded = 0;
                    waveOutHeader[CurrentBufferNum].dwUser = IntPtr.Zero;
                    waveOutHeader[CurrentBufferNum].dwLoops = 1;
                    waveOutHeader[CurrentBufferNum].dwFlags = 0x10;//WHDR_INQUEUE;
 
                    //waveOutWrite(hWaveOut, ref waveInHeader, BufferSize);
 
                    CurrentBufferNum++;
                    return;
                }
            }
        }
        //-------------------------------------------------------
        public static int StopOutAudioDevice()
        {
            if (hWaveOut == IntPtr.Zero)
                return -1;
 
            waveOutClose(hWaveOut);
            return 0;
        }
        #endregion
 
        #region -------------------------- WavIn Function -----------------------------------------------
 
        public static int StartInAudioDevice(int DeviceID, WaveCallbackProc InCallBackFun)
        {
            if (waveInOpen(ref hWaveIn, DeviceID, ref waveFormat, Marshal.GetFunctionPointerForDelegate(InCallBackFun), IntPtr.Zero, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
                return -1; 
 
            if (PrepareInBuffer() != 0)
                return -2;
 
            if (waveInStart(hWaveIn) != MMSYSERR_NOERROR)
            {
                Marshal.FreeHGlobal(waveInHeader.lpData);
                return -3;
            }
 
            return 0;
        }
        //-------------------------------------------------------
        public static int StopInAudioDevice()
        {
            if (hWaveIn == IntPtr.Zero)
                return -1;
 
            waveInStop(hWaveIn);
 
            waveInUnprepareHeader(hWaveIn, ref waveInHeader, Marshal.SizeOf(waveInHeader));
            waveInClose(hWaveIn);
            hWaveIn = IntPtr.Zero;
 
            return 0;
        }
        //-------------------------------------------------------
        public static int PrepareInBuffer()
        {
            waveInHeader.lpData = Marshal.AllocHGlobal(BufferSize);
            waveInHeader.dwBufferLength = BufferSize;
            waveInHeader.dwBytesRecorded = waveInHeader.dwBufferLength;
            waveInHeader.dwFlags = 0;
 
            if (waveInPrepareHeader(hWaveIn, ref waveInHeader, Marshal.SizeOf(typeof(WAVEHDR))) != MMSYSERR_NOERROR)
            {
                Marshal.FreeHGlobal(waveInHeader.lpData);
                return -1;
            }
 
            if (waveInAddBuffer(hWaveIn, ref waveInHeader, Marshal.SizeOf(typeof(WAVEHDR))) != MMSYSERR_NOERROR)
            {
                Marshal.FreeHGlobal(waveInHeader.lpData);
                return -1;
            }
 
            return 0;
        }
        #endregion
 
        //----------------------------------------------------------------------------
        public void Dispose()
        {
            StopInAudioDevice();
            StopOutAudioDevice();
        }
        //----------------------------------------------------------------------------
   }
}
За помощь, огромное спасибо SSTREGG
Теперь основная программа:
Клиент:
Инициализация
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
           #region ------------------------ Звук ------------------------------------------
            Sound.InitSound();
            for (i = 0; i < Sound.InDeviceCount; i++)
                if (InAudioDeviceName == Sound.InDeviceName[i])
                    InAudioDeviceID = (byte)i;
            //--------------------
            if (Sound.StartInAudioDevice((int)InAudioDeviceID, InCallBackFun) != 0)
                InSoundState = Sound.SoundState.None;
            else
            {
                InSoundState = Sound.SoundState.Present; 
            }
            //================================================================================
            for (i = 0; i < Sound.OutDeviceCount; i++)
                if (OutAudioDeviceName == Sound.OutDeviceName[i])
                    OutAudioDeviceID = (byte)i;
            //--------------------
            if (Sound.StartOutAudioDevice((int)OutAudioDeviceID, OutCallBackFun) != 0)
                OutSoundState = Sound.SoundState.None;
            else
            {
                OutSoundState = Sound.SoundState.Present;
            }
            #endregion
КулБаки
C#
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
        #region ------ CallBack Audio -------
        public static void InCallBackFunction(IntPtr hwi, Sound.WimMessageType uMsg, IntPtr dwInstance, IntPtr dwParam1, IntPtr dwParam2)
        {
            switch (uMsg)
            {
                case Sound.WimMessageType.OpenIn:
                    break;
                case Sound.WimMessageType.CloseIn:
                    break;
                case Sound.WimMessageType.DataIn:
                    Sound.PrepareInBuffer();
                    
                    switch(InSoundState)
                    {
                        case Sound.SoundState.None:
                            break;
                        case Sound.SoundState.Ring:
                            InSoundState = Sound.SoundState.WaitAnswerOnCommand;
                            break;
                        case Sound.SoundState.Start:
                            NetFunClassAudio.SendToNetworkUDP(Sound.waveInHeader.lpData, Sound.waveInHeader.dwBufferLength);
                            break;
                        default:
                            break;
                    }
                    break;
            }
        }
        //================================================================================
        public static void OutCallBackFunction(IntPtr hwi, Sound.WimMessageType uMsg, IntPtr dwInstance, IntPtr dwParam1, IntPtr dwParam2)
        {
            switch (uMsg)
            {
                case Sound.WimMessageType.OpenOut:
                    break;
                case Sound.WimMessageType.CloseOut:
                    break;
                case Sound.WimMessageType.DataOut:
                    break;
            }
        }
        #endregion
создается доп класс NetFunClassAudio

C#
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
    public class NetProcessAudio
    {
        public Socket UDPSoundSocketSend;
        public IPEndPoint PESoundPointSend;
 
        public UdpClient UPDListerReceive;
        public IPEndPoint EPGroupReceive;
 
        public string SendCommand;
 
        public Thread NetThreadReceive;
 
        public bool _NetStartReceive = false;
 
        Sound.SoundState prevState;
        //--------------------------    
        public NetProcessAudio()
        {
            UDPSoundSocketSend = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            PESoundPointSend = new IPEndPoint(IPAddress.Parse(MainForm.IPServer), Int32.Parse(MainForm.AudioPort) + 1);
 
            UPDListerReceive = new UdpClient(Int32.Parse(MainForm.AudioPort));
            EPGroupReceive = new IPEndPoint(IPAddress.Any, Int32.Parse(MainForm.AudioPort));
 
            NetThreadReceive = new Thread(new ThreadStart(ProcessReceive));
            NetThreadReceive.IsBackground = true;
            NetThreadReceive.Name = "NetThreadReceive";
            _NetStartReceive = true;
            NetThreadReceive.Start();
        }
        //-------------------------- 
        ~NetProcessAudio()
        {
        }
        //---------------- Send Function ---------------------------------------------
        public void SendCommandToNetworkUDP(string Command)
        {
            byte[] bData = new byte[Command.Length];
            int i;
 
            for (i = 0; i < Command.Length; i++)
                bData[i] = (byte)Command[i];
 
            UDPSoundSocketSend.SendBufferSize = Command.Length;
            UDPSoundSocketSend.ReceiveBufferSize = Command.Length;
            UDPSoundSocketSend.SendTo(bData, PESoundPointSend);
            MainForm.SaveLogFile("Send " + Command);
            SendCommand = Command;
        }
        //----------------------------------------------------------------------------
        public void SendToNetworkUDP(IntPtr DataToSend, int Size)
        {
            byte[] Data = new byte[Size];
            Marshal.Copy(DataToSend, Data, 0, Size);
            UDPSoundSocketSend.SendBufferSize = Size;
            UDPSoundSocketSend.ReceiveBufferSize = Size;
            UDPSoundSocketSend.SendTo(Data, PESoundPointSend);
        }
        //---------------- Receive Function ------------------------------------------
        public void ProcessReceive() // прием данных с микрофона сервера
        {
            try
            {
                while (_NetStartReceive)
                {
                    ....
                    switch (MainForm.InSoundState)
                    {
                        ....
                        case Sound.SoundState.Start:
                            byte[] ReceiveBytesData = UPDListerReceive.Receive(ref EPGroupReceive);
                            using (MemoryStream MStream = new MemoryStream(ReceiveBytesData))
                            {
                                if (Sound.CurrentBufferNum == Sound.BuffersCount)
                                    Sound.CurrentBufferNum = 0;
 
                                Sound.PlayBuffer(MStream);
                            }
                            break;
                        case Sound.SoundState.Stop:
                            break;
                        default:
                             Thread.Sleep(100);
                            break;
                    }
                }
            }
            catch (Exception)
            {
                return;
            }
        }
        //---------------------------------------
        public void NetClose()
        {
            _NetStartReceive = false;
            UPDListerReceive.Close();
        }
        //-------------------------- 
    }//public class NetProcessAudio
    #endregion
Теперь сервер
Инициализация точно такая же как и у клиента, кулбаки такие же, отличие в классе NetProcessAudio
C#
1
2
3
4
5
            UDPSoundSocketSend = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            PESoundPointSend = new IPEndPoint(IPAddress.Parse(MainForm.IPClient), Int32.Parse(MainForm.AudioPort));
 
            UPDListerReceive = new UdpClient(Int32.Parse(MainForm.AudioPort) + 1);
            EPGroupReceive = new IPEndPoint(IPAddress.Any, Int32.Parse(MainForm.AudioPort) + 1);
Вроде должно работать, ан нет... один хриплый повторяющийся звук
Пробовал соединить и клиент и сервер в одной программе, такое же.
Не пойму, в чем дело или с микрофона звук крива снимается (но что то не вериться), или на динамик
криво кидаю (что быстрей всего).
Тюкните мордой пожалуйста, где я накасячил
Заранее благодарен.
ЗЫ: Сильно не пинайте
1
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.04.2012, 20:35
Ответы с готовыми решениями:

Передача файла по протоколу UDP
Сервер передает файл клиенту если его размер файла больше 8192 байта то файл разбивается на части. С этим все в порядке но вот со...

Передача файлов по протоколу UDP
Здравствуйте! Я написал программу которая передает файл с введенного IP на твой пк, ну и в общем, при вводе IP 255.255.255.255 все...

Передача сообщений по протоколу UDP
Всем привет, и с наступающим. Собственно есть необходимость передавать данные по udp протоколу, пока не представляю как это...

9
7 / 7 / 1
Регистрация: 16.01.2012
Сообщений: 95
08.04.2012, 13:51  [ТС]
Проблема решена. Тема закрыта
0
0 / 0 / 0
Регистрация: 30.05.2012
Сообщений: 5
30.05.2012, 15:39
DeGroup, Привет, я студент, учусь программированию на C + + Builder. Пожалуйста, вы можете отправить проект, который вы опубликовали: Передача звука по сети по протоколу UDP Передача звука по сети по протоколу UDP (FullDuplex)

мне очень нужен проект в C++ Builder . спасибо!
email: r.boon@mail.com
0
7 / 7 / 1
Регистрация: 16.01.2012
Сообщений: 95
30.05.2012, 16:30  [ТС]
TO: Sergiu
Добрый день.
Да я могу отправить Вам, свой проект, но учтите, он еще не доделан, но разобраться можно, и он включает в себя работу с WEB камерой, для этого Вам нужен компонент DSPack. Тоже выложу сюда на форум. Но только завтра сегодня я срулил с работы уже.
Завтра выложу, все что есть и по звуку и по камере. Качайте, комментируйте, ругайте, все что хотите.
ЗЫ: Проект на 6 булыжник, перекладываю на XE2. Могу и то и то выложить

Добавлено через 6 минут
Ща пороюсь на флешках, может найду.
0
7 / 7 / 1
Регистрация: 16.01.2012
Сообщений: 95
30.05.2012, 16:41  [ТС]
Вот пока DSPack заточен на 6-ой булыжник.
И проект,он тоже заточен 6-ку, но он старый, вроде, последний отошлю завтра.
Всех благ.
Вложения
Тип файла: rar DSPack.rar (3.39 Мб, 160 просмотров)
Тип файла: rar VideoNabludenie.rar (2.62 Мб, 171 просмотров)
1
0 / 0 / 0
Регистрация: 30.05.2012
Сообщений: 5
30.05.2012, 16:46
DeGroup, Я рад, что вы ответили...
Я хотел бы, если возможно, на C++ Builder 6 , потому что больше работаю с ним.
Если вы заинтересованы, есть работа для вас, как я полагаю вы эксперт в этом области... :cofee:
конечно могу заплатить, давайте поговорим в личке ... я Новичок на этом форуме
0
7 / 7 / 1
Регистрация: 16.01.2012
Сообщений: 95
30.05.2012, 16:50  [ТС]
Сразу предупреждаю, звук передается с шумом, может настройками поиграть? Не знаю, я копаю в сторону директсаунд, может там че нарою.

Добавлено через 2 минуты
И DSPack и проект, который я выложил, они на 6 буилдер (или булыжник). Пробуйте. Щас попробую найти чисто под звук
0
7 / 7 / 1
Регистрация: 16.01.2012
Сообщений: 95
30.05.2012, 16:56  [ТС]
вот, с чего начинал, пробный проект, но там Indy 6, а у меня 9, а перекомпиливать лень. Но там все ясно.
Вложения
Тип файла: rar Microfon.rar (640.1 Кб, 190 просмотров)
1
7 / 7 / 1
Регистрация: 16.01.2012
Сообщений: 95
30.05.2012, 16:59  [ТС]
Вообщем, вот что есть и я технический программист, и пластиковые карты и оборудование всякое, если есть разъем подключения к компу, подключим, наладим, софт наваяем сори за нескромность
0
0 / 0 / 0
Регистрация: 11.03.2013
Сообщений: 18
23.04.2015, 19:56
DeGroup, Привет а можешь скинуть проект на с#? а то мне надо сдавать курсовую, а сам не умею ни на чем писать, а все варианты по моделированию на Opnet был уже розданы и у меня нету выбора кроме как программировать)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.04.2015, 19:56
Помогаю со студенческими работами здесь

Передача больших файлов по протоколу UDP
Как отправлять большие файлы ? Помогите с реализацией пожалуйста. Передача файлов по UDP

Передача звука по локальной сети
Подскажите как производится захват звука для пакетной передачи по протоколу UDP в реальном времени?

Передача звука по сети UDP
Передача звука от клиента к серверу и его воспроизведение вполне удалась. Только вот теперь проблема в передаче звука в обратном...

Передача звука по сети с использованием UDP и BASS.DLL
Пытаюсь написать программу для передачи звука по сети. Мне посоветовали использовать BASS.DLL и UDP. Передача звука вроде как работает, но...

Передача массива байтов по UDP протоколу другому приложению
Как в BorlandС++ Builder6 решается вопрос обмена информацией с другими приложениями (не обязательно созданными в С++ Builder)? Например,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru