Sign in to follow this  
cartographer

How can i manage a smooth audio?

Recommended Posts

Hi all, i m using DirectSound to capture the audio from a server and sending it to client which plays the incomming data. But alas when i play audio i just hear sounds like hiss with short delays. everthing is fine but i couldnt find the clue to handle it. Here is my server code: <code> namespace MSDNAudioServer2 { public partial class Form1 : Form { public BufferPositionNotify[] PositionNotify = new BufferPositionNotify[NumberRecordNotifications + 1]; public const int NumberRecordNotifications = 2; public AutoResetEvent NotificationEvent = null; public CaptureBuffer applicationBuffer = null; public Capture applicationDevice = null; public Notify applicationNotify = null; private Thread NotifyThread = null; public int CaptureBufferSize = 0; public int NextCaptureOffset = 0; public WaveFormat InputFormat; public int NotifySize = 0; private bool Capturing = false; Socket socketForClient = null; TcpListener tcpListener = null; public Form1() { InitializeComponent(); InitDirectSound(); if (null == applicationDevice) Close(); else { InputFormat.SamplesPerSecond = 16000; InputFormat.BitsPerSample = 8; InputFormat.Channels = 1; InputFormat.BlockAlign = (short)(InputFormat.Channels * (InputFormat.BitsPerSample / 8)); InputFormat.AverageBytesPerSecond = InputFormat.BlockAlign * InputFormat.SamplesPerSecond; InputFormat.FormatTag = WaveFormatTag.Pcm; } } private void InitDirectSound() { CaptureBufferSize = 0; NotifySize = 0; // Create DirectSound.Capture using the preferred capture device try { applicationDevice = new Capture(); rt.AppendText("\n Capture initialized"); } catch { rt.AppendText("\n Capture not initialized");} } void CreateCaptureBuffer() { //----------------------------------------------------------------------------- // Name: CreateCaptureBuffer() // Desc: Creates a capture buffer and sets the format //----------------------------------------------------------------------------- CaptureBufferDescription dscheckboxd = new CaptureBufferDescription(); if (null != applicationNotify) { applicationNotify.Dispose(); applicationNotify = null; } if (null != applicationBuffer) { applicationBuffer.Dispose(); applicationBuffer = null; } if (0 == InputFormat.Channels) return; // Set the notification size NotifySize = (1024 > InputFormat.AverageBytesPerSecond / 8) ? 1024 : (InputFormat.AverageBytesPerSecond / 8); NotifySize -= NotifySize % InputFormat.BlockAlign; rt.AppendText("\n Notify Size "+ NotifySize); // Set the buffer sizes CaptureBufferSize = NotifySize * NumberRecordNotifications; rt.AppendText("\n Capture Buffer size "+CaptureBufferSize); // Create the capture buffer dscheckboxd.BufferBytes = CaptureBufferSize; dscheckboxd.Format = InputFormat; // Set the format during creatation applicationBuffer = new CaptureBuffer(dscheckboxd, applicationDevice); rt.AppendText("\nCapture Buffere created"); NextCaptureOffset = 0; InitNotifications(); } void InitNotifications() { //----------------------------------------------------------------------------- // Name: InitNotifications() // Desc: Inits the notifications on the capture buffer which are handled // in the notify thread. //----------------------------------------------------------------------------- if (null == applicationBuffer) throw new NullReferenceException(); // Create a thread to monitor the notify events if (null == NotifyThread) { if (socketForClient.Connected) { socketForClient.Send(BitConverter.GetBytes(NotifySize), 0, 4, System.Net.Sockets.SocketFlags.None); } rt.AppendText("\nNotify Thread Created"); NotifyThread = new Thread(new ThreadStart(WaitThread)); Capturing = true; NotifyThread.Start(); // Create a notification event, for when the sound stops playing NotificationEvent = new AutoResetEvent(false); } // Setup the notification positions for (int i = 0; i < NumberRecordNotifications; i++) { PositionNotify[i].Offset = (NotifySize * i) + NotifySize - 1; PositionNotify[i].EventNotifyHandle = NotificationEvent.Handle; } applicationNotify = new Notify(applicationBuffer); // Tell DirectSound when to notify the app. The notification will come in the from // of signaled events that are handled in the notify thread. applicationNotify.SetNotificationPositions(PositionNotify, NumberRecordNotifications); } void StartOrStopRecord(bool StartRecording) { //----------------------------------------------------------------------------- // Name: StartOrStopRecord() // Desc: Starts or stops the capture buffer from recording //----------------------------------------------------------------------------- if (StartRecording) { // Create a capture buffer, and tell the capture // buffer to start recording CreateCaptureBuffer(); applicationBuffer.Start(true); } else { // Stop the buffer, and read any data that was not // caught by a notification applicationBuffer.Stop(); Capturing = false; RecordCapturedData(); } } void RecordCapturedData() { //----------------------------------------------------------------------------- // Name: RecordCapturedData() // Desc: Copies data from the capture buffer to the output buffer //----------------------------------------------------------------------------- byte[] CaptureData = null; int ReadPos; int CapturePos; int LockSize; applicationBuffer.GetCurrentPosition(out CapturePos, out ReadPos); LockSize = ReadPos - NextCaptureOffset; if (LockSize < 0) LockSize += CaptureBufferSize; // Block align lock size so that we are always write on a boundary LockSize -= (LockSize % NotifySize); if (0 == LockSize) return; // Read the capture buffer. CaptureData = (byte[])applicationBuffer.Read(NextCaptureOffset, typeof(byte), LockFlag.None,LockSize); if(socketForClient.Connected) SendToClient(CaptureData); // Move the capture offset along NextCaptureOffset += CaptureData.Length; NextCaptureOffset %= CaptureBufferSize; // Circular buffer } private void WaitThread() { while (Capturing) { //Sit here and wait for a message to arrive NotificationEvent.WaitOne(Timeout.Infinite, true); RecordCapturedData(); } } private void SendToClient(byte[] audioData) { int length; length = audioData.Length; try { if (socketForClient.Connected) { socketForClient.Send(BitConverter.GetBytes(length), 0, 4, System.Net.Sockets.SocketFlags.None); int PacketSize = 16000; if (length > PacketSize) { long totalBytes = length; long index = 0; while (totalBytes > 0) { if (totalBytes > PacketSize) { byte[] b = new byte[PacketSize]; Array.Copy(audioData, index, b, 0, PacketSize); socketForClient.Send(b, 0, PacketSize, System.Net.Sockets.SocketFlags.None); b = null; } else { socketForClient.Send(audioData, (int)index, (int)totalBytes, System.Net.Sockets.SocketFlags.None); } totalBytes -= PacketSize; index += PacketSize; } } else { socketForClient.Send(audioData, (int)length, System.Net.Sockets.SocketFlags.None); } } } catch (SocketException e) { MessageBox.Show(e.ToString()); } } private void button1_Click(object sender, EventArgs e) { button1.Enabled = false; tcpListener = new TcpListener(6555); tcpListener.Start(); socketForClient = tcpListener.AcceptSocket(); rt.AppendText("\n Client connected"); CreateCaptureBuffer(); StartOrStopRecord(true); } } } </code> and here is my client code <code> namespace MSDNAudioClient2 { public partial class Form1 : Form { private SecondaryBuffer ApplicationBuffer = null; BufferDescription pBuffDesc; WaveFormat wFormat; private Device ApplicationDevice = null; private string PathSoundFile = string.Empty; private byte[] m_RecBuffer = null ; public Socket cs; public TcpClient tcp; Stream stm; private Thread ReaderThread = null; public Form1() { InitializeComponent(); try { ApplicationDevice = new Device(); ApplicationDevice.SetCooperativeLevel(this, CooperativeLevel.Priority); } catch { MessageBox.Show("Unable to create sound device. Sample will now exit."); // this.Close(); } wFormat = new WaveFormat(); wFormat.SamplesPerSecond = 16000; //44MHz wFormat.Channels = 1; wFormat.BitsPerSample = 8; wFormat.BlockAlign = (short)(wFormat.Channels * (wFormat.BitsPerSample / 8)); wFormat.AverageBytesPerSecond = wFormat.BlockAlign * wFormat.SamplesPerSecond; wFormat.FormatTag = WaveFormatTag.Pcm; pBuffDesc = new BufferDescription(); pBuffDesc.ControlEffects = true; pBuffDesc.ControlFrequency = true; pBuffDesc.ControlPan = true; pBuffDesc.ControlVolume = true; pBuffDesc.Format = wFormat; pBuffDesc.GlobalFocus = true; } private void button1_Click(object sender, EventArgs e) { tcp = new TcpClient(); try { tcp.Connect(IPAddress.Parse("192.168.0.16"), 6555); } catch (SocketException se) { MessageBox.Show("not connected"); tcp = null; } if (tcp.Connected) { this.stm = tcp.GetStream(); } byte[] ba = new byte[4]; stm.Read(ba, 0, 4); int notifysize = BitConverter.ToInt32(ba, 0); pBuffDesc.BufferBytes = notifysize * 2; try { ApplicationBuffer = new SecondaryBuffer(pBuffDesc, ApplicationDevice); } catch (Exception) { MessageBox.Show("Unable to create sound buffer. Application will now exit."); this.Close(); } ReaderThread = new Thread(new ThreadStart(ReaderThreadProc)); ReaderThread.Start(); button1.Enabled = false; } public void ReaderThreadProc() { while (tcp.Connected) { ReadData(); } } private void ReadData() { int packetSize = 16000; int length = 0; byte[] ba = new byte[4]; stm.Read(ba, 0, 4); length = BitConverter.ToInt32(ba, 0); rt.AppendText("\nData Recevied: " + length); byte[] m_RecBuffer = new byte[length]; try { if (tcp.Connected) { if (length > packetSize) { long bytesToRead = length; long idx = 0; while (bytesToRead > 0) { byte[] tb = new byte[packetSize]; long bytesRead = 0; if (bytesToRead < packetSize) { bytesRead = (long)stm.Read(tb, 0, (int)bytesToRead); } else { bytesRead = (long)stm.Read(tb, 0, (int)packetSize); } Array.Copy(tb, 0, m_RecBuffer, idx, bytesRead); tb = null; idx += bytesRead; bytesToRead -= bytesRead; } } else { stm.Read(m_RecBuffer, 0, (int)length); } // MemoryStream ms = new MemoryStream(m_RecBuffer); ApplicationBuffer.Write(0, m_RecBuffer , LockFlag.EntireBuffer); ApplicationBuffer.SetCurrentPosition(0); ApplicationBuffer.Play(0, BufferPlayFlags.Default); } //end of first if } catch (Exception e) { } } </code> Please give me idea to tackle it

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this