public void SetStreamFormat(SupportedStreamFormat format) { if (cmbStreamFormat == null) { return; } if (InvokeRequired) { Invoke(new Action <SupportedStreamFormat>(SetStreamFormat), new object[] { format }); return; } if (IsDisposed) { return; } FillStreamFormats(); for (int i = 0; i < cmbStreamFormat.Items.Count; i++) { if ((SupportedStreamFormat)((ComboboxItem)cmbStreamFormat.Items[i]).Value == format) { cmbStreamFormat.SelectedIndex = i; } } SetStreamFormat(); }
/// <summary> /// Add bytes to the application buffer. /// </summary> public void AddToBuffer(byte[] dataToSend, WaveFormat formatIn, int reduceLagThresholdIn, SupportedStreamFormat streamFormatIn) { waveFormat = formatIn; reduceLagThreshold = reduceLagThresholdIn; streamFormatSelected = streamFormatIn; KeepABuffer(dataToSend); SetBufferSize(); }
public Mp3Stream(WaveFormat format, SupportedStreamFormat formatSelected) { Output = new MemoryStream(); var bitRate = 128; if (formatSelected.Equals(SupportedStreamFormat.Mp3_320)) { bitRate = 320; } Writer = new LameMP3FileWriter(Output, format, bitRate); }
/// <summary> /// The user changed the stream format in the user interface. /// Restart streaming in the new format. /// </summary> /// <param name="formatIn">the chosen format</param> public void SetStreamFormat(SupportedStreamFormat formatIn) { if (devices == null) { return; } if (formatIn != StreamFormatSelected) { StreamFormatSelected = formatIn; Mp3Stream = null; devices.Stop(); devices.Start(); } }
/// <summary> /// Generate a mp3 header for a mp3 stream. /// see: http://www.mp3-tech.org/programmer/frame_header.html /// </summary> /// <param name="format">the format of the stream</param> /// <returns>a mp3 header</returns> public byte[] GetMp3Header(WaveFormat format, SupportedStreamFormat streamFormat) { if (format == null) { return(new byte[0]); } var riffHeaderStream = new MemoryStream(); var writer = new BinaryWriter(riffHeaderStream, Encoding.UTF8); //Write header: AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM writer.Write(new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); // A: all bits must be set writer.Write(new byte[] { 1, 1 }); // B: MPEG Version 1 (ISO/IEC 11172-3) writer.Write(new byte[] { 0, 1 }); // C: Layer III writer.Write(new byte[] { 1 }); // D: 1 - Not protected if (streamFormat.Equals(SupportedStreamFormat.Mp3_128)) { // V1,L3 writer.Write(new byte[] { 1, 0, 0, 1 }); // E: bitrate: 1001 288 160 128 144 80 } else { writer.Write(new byte[] { 1, 1, 1, 0 }); // E: bitrate: 1110 448 384 320 256 160 } if (format.SampleRate == 44100) { writer.Write(new byte[] { 0, 0 }); // F: MPEG1 - 44100 Hz } else if (format.SampleRate == 48000) { writer.Write(new byte[] { 0, 1 }); // F: MPEG1 - 48000 Hz } else { writer.Write(new byte[] { 1, 0 }); // F: MPEG1 - 32000 Hz } writer.Write(new byte[] { 0 }); // G: 0 - frame is not padded writer.Write(new byte[] { 0 }); // H: Private bit. This one is only informative. writer.Write(new byte[] { 0, 0 }); // I: Stereo writer.Write(new byte[] { 0, 0 }); // J: Mode extension (Only used in Joint stereo) writer.Write(new byte[] { 0 }); // K: Copyright - Audio is not copyrighted writer.Write(new byte[] { 0 }); // L: Original - Copy of original media writer.Write(new byte[] { 0, 0 }); // M: Emphasis - none return(riffHeaderStream.ToArray()); }
/// <summary> /// The user changed the stream format in the user interface. /// Restart streaming in the new format. /// </summary> /// <param name="formatIn">the chosen format</param> public void SetStreamFormat(SupportedStreamFormat formatIn) { if (devices == null) { return; } if (formatIn != StreamFormatSelected) { logger.Log($"Set stream format to {formatIn}"); StreamFormatSelected = formatIn; Mp3Stream = null; devices.Stop(); devices.Start(); } }
/// <summary> /// A device has made a new streaming connection. Add the connection to the right device. /// </summary> /// <param name="socket">the socket</param> /// <param name="httpRequest">the HTTP headers, including the 'CAST-DEVICE-CAPABILITIES' header</param> public void AddStreamingConnection(Socket socket, string httpRequest, SupportedStreamFormat streamFormatIn) { if (deviceList == null || socket == null || applicationBuffer == null) { return; } var remoteAddress = ((IPEndPoint)socket.RemoteEndPoint).Address.ToString(); foreach (var device in deviceList) { if (device.AddStreamingConnection(remoteAddress, socket)) { applicationBuffer.SendStartupBuffer(device, streamFormatIn); break; } } }
/// <summary> /// Send the startup buffer, a buffer containing the past x seconds. /// </summary> /// <param name="device"></param> public void SendStartupBuffer(IDevice device, SupportedStreamFormat streamFormatIn) { if (device == null) { return; } streamFormatSelected = streamFormatIn; SetBufferSize(); byte[] bufferAlreadySent; do { bufferAlreadySent = GetBufferAlreadySent(); if (bufferAlreadySent.Length < BufferSizeInBytes) { Task.Delay(1000).Wait(); } } while (bufferAlreadySent.Length < BufferSizeInBytes); device.OnRecordingDataAvailable(bufferAlreadySent, waveFormat, reduceLagThreshold, streamFormatSelected); startBufferSend = true; }
/// <summary> /// Stream the recorded data to the device. /// </summary> /// <param name="dataToSend">tha audio data</param> /// <param name="format">the wav format</param> /// <param name="reduceLagThreshold">lag value</param> /// <param name="streamFormat">the stream format</param> public void OnRecordingDataAvailable(byte[] dataToSend, WaveFormat format, int reduceLagThreshold, SupportedStreamFormat streamFormat) { if (streamingConnection == null || dataToSend == null || dataToSend.Length == 0) { return; } if (streamingConnection.IsConnected()) { if (GetDeviceState() != DeviceState.NotConnected && GetDeviceState() != DeviceState.Paused) // When you keep streaming to a device when it is paused, the application stops streaming after a while (local buffers full?) { streamingConnection.SendData(dataToSend, format, reduceLagThreshold, streamFormat); } } else { logger.Log($"Connection closed from {streamingConnection.GetRemoteEndPoint()}"); streamingConnection = null; } }
/// <summary> /// Send audio data to the device. /// </summary> /// <param name="dataToSend">the audio data</param> /// <param name="format">the audio format</param> /// <param name="reduceLagThreshold">lag control value</param> /// <param name="streamFormat">the stream format selected</param> public void SendData(byte[] dataToSend, WaveFormat format, int reduceLagThreshold, SupportedStreamFormat streamFormat) { if (dataToSend == null || dataToSend.Length == 0 || format == null) { return; } // Lag control functionality. if (reduceLagThreshold < 1000) { reduceLagCounter++; if (reduceLagCounter > reduceLagThreshold) { reduceLagCounter = 0; return; } } // Send audio header before the fitrst data. if (!isAudioHeaderSent) { isAudioHeaderSent = true; if (streamFormat.Equals(SupportedStreamFormat.Wav)) { Send(audioHeader.GetRiffHeader(format)); } else { Send(audioHeader.GetMp3Header(format, streamFormat)); } } Send(dataToSend); }
/// <summary> /// New audio data is available. /// </summary> /// <param name="dataToSend">the data</param> /// <param name="format">the wav format that's used</param> /// <param name="reduceLagThreshold">value for the lag control</param> /// <param name="streamFormat">the stream format</param> public void OnRecordingDataAvailable(byte[] dataToSend, WaveFormat format, int reduceLagThreshold, SupportedStreamFormat streamFormat) { if (deviceList == null || dataToSend == null || applicationBuffer == null) { return; } if (applicationBuffer.IsStartBufferSend()) { foreach (var device in deviceList) { device.OnRecordingDataAvailable(dataToSend, format, reduceLagThreshold, streamFormat); } } // Keep a buffer applicationBuffer.AddToBuffer(dataToSend, format, reduceLagThreshold, streamFormat); }
public void SendData(byte[] dataToSend, WaveFormat format, int reduceLagThreshold, SupportedStreamFormat streamFormat) { if (reduceLagThreshold < 1000) { reduceLagCounter++; if (reduceLagCounter > reduceLagThreshold) { reduceLagCounter = 0; return; } } if (!isAudioHeaderSent) { isAudioHeaderSent = true; if (streamFormat.Equals(SupportedStreamFormat.Wav)) { Send(audioHeader.GetRiffHeader(format)); } else { Send(audioHeader.GetMp3Header(format, streamFormat)); // Hack to start mp3 streams faster: Send a 7.8 seconds buffer of 320 kbps silence. Send(Properties.Resources.silence); } } Send(dataToSend); }
/// <summary> /// New audio data is available. /// </summary> /// <param name="dataToSend">the data</param> /// <param name="format">the wav format that's used</param> /// <param name="reduceLagThreshold">value for the lag control</param> /// <param name="streamFormat">the stream format</param> public void OnRecordingDataAvailable(byte[] dataToSend, WaveFormat format, int reduceLagThreshold, SupportedStreamFormat streamFormat) { if (deviceList == null || dataToSend == null) { return; } foreach (var device in deviceList) { device.OnRecordingDataAvailable(dataToSend, format, reduceLagThreshold, streamFormat); } }