public static async ValueTask <TranscoderPipeline?> CreatePipelineAsync( PlayerManager manager, PipeReader input, IAudioCodec inputCodec, CancellationToken cancellationToken = default) { var transcoders = new List <IAudioTranscoder>(); var currentCodec = inputCodec; // TODO: We could potentially bail out here if we're already the // desired codec. do { if (!manager.TryGetTranscoderFactory(currentCodec, out var factory)) { return(null); } var transcoder = factory.GetTranscoder(currentCodec, input); transcoders.Add(transcoder); currentCodec = await transcoder.GetOutputCodecAsync( cancellationToken); input = transcoder.Output; }while (!IsDesiredCodec(currentCodec)); return(new TranscoderPipeline(input, transcoders));
public void Init(IAudioCodec codec) { this.codec = codec; // Init record input input = new WaveIn(); input.DeviceNumber = cbInput.SelectedIndex; input.WaveFormat = codec.RecordFormat; input.DataAvailable += Input_DataAvailable; input.StartRecording(); // Init buffer - level meters will use it buffer = new BufferedWaveProvider(codec.RecordFormat); InputBufferMilisec = 50; // Init level meters channel = new SampleChannel(buffer, true); var meter = new MeteringSampleProvider(channel); meter.StreamVolume += Meter_StreamVolume; // Init feedback output output = new WaveOut(); output.Volume = FeedbackVolume; output.Init(meter); output.Play(); Ready = true; }
protected virtual void Awake() { codec = GetCodec(); microphone = GetComponent <AudioInputDeviceBase>(); speaker = GetComponent(typeof(IAudioPlayer)) as IAudioPlayer; if (microphone == null) { Debug.LogError("No audio input component attached to speaker", this); return; } if (speaker == null) { Debug.LogError("No audio output component attached to speaker", this); return; } if (IsLocal) { microphone.OnAudioBufferReady += this.OnMicrophoneDataReady; microphone.StartRecording(); } }
private static int CompressWAVFile(string wavFileName, IAudioCodec codec, byte[] compressedBuffer, int compressedBufferOffset, out int pcmSize) { var wavFileBuffer = File.ReadAllBytes(wavFileName); //read in WAV file return(CompressWAVBits(wavFileBuffer, 0, wavFileBuffer.Length, compressedBuffer, 0, codec, out pcmSize)); }
private void RecordForm_Load(object sender, EventArgs e) { codec = new PcmCodec(); // TODO: codec selection from settings rcRecorder.Init(codec); rcRecorder.DataAvailable += RcRecorder_DataAvailable; preview = new WaveOut(); }
public LiveBroadcastReciever(string ipAddress, int port, IAudioCodec audioCodec, Playback playback) { RemoteIP = ipAddress; broadcastLoop = new Thread(Broadcast); acceptingEndpoint = new IPEndPoint(IPAddress.Any, port); this.audioCodec = audioCodec; buffer = new BufferedWaveProvider(this.audioCodec.RecordFormat); this.playback = playback; }
private void RecordForm_Load(object sender, EventArgs e) { var settings = Settings.Default; codec = new PcmCodec(); // TODO: codec selection from settings rcRecorder.Init(codec); rcRecorder.DataAvailable += RcRecorder_DataAvailable; streamer = new LiveBroadcastStreamer(settings.SERVER_IP, settings.BROADCAST_PORT, codec); }
/// <inheritdoc/> public IAudioTranscoder GetTranscoder(IAudioCodec codec, PipeReader input) { if (!(codec is PcmAudioCodec pcmCodec)) { ThrowArgumentException(nameof(codec), $"Invalid codec passed to " + $"{nameof(PcmAudioTranscoderFactory)}"); return(default);
public AudioRoute(IAudioCodec codec, IAudioTransport transport) { _codec = codec; _transport = transport; _buffer = new AudioBuffer(codec); _first = true; WaveFormat = _codec.Format.ToWaveFormat(); }
static bool IsDesiredCodec(IAudioCodec codec) { if (!(codec is OpusAudioCodec opusCodec)) { return(false); } // 48khz Stereo Opus is what we desire return(opusCodec.ChannelCount == 2 && opusCodec.SamplingRate == 48000); }
public AudioBuffer(IAudioCodec codec) { _codec = codec; _waveProvider = new BufferedWaveProvider(_codec.Format.ToWaveFormat()); _waveProvider.DiscardOnBufferOverflow = false; _sampleProvider = _waveProvider.ToSampleProvider(); _jitter = new JitterTimer <IAudioPacket>(new AudioPacketRestorer(), codec.Format.Duration); _jitter.Completed += OnCaptured; }
public FileRecorder(IAudioCodec codec, int devNumber) { this.codec = codec; this.devNumber = devNumber; waveIn = new WaveIn(); waveIn.DeviceNumber = devNumber; waveIn.WaveFormat = codec.RecordFormat; waveIn.DataAvailable += WaveIn_DataAvailable; buffer = new BufferedWaveProvider(codec.RecordFormat); }
/// <inheritdoc/> public IAudioTranscoder GetTranscoder(IAudioCodec codec, PipeReader input) { if (codec is MpegAudioCodec mpegInfo) { return(new MpegAudioTranscoder(input, mpegInfo)); } ThrowArgumentException(nameof(codec), $"Invalid codec passed to " + $"{nameof(MpegAudioTranscoderFactory)}"); return(default !);
internal bool TryGetTranscoderFactory(IAudioCodec codec, [NotNullWhen(true)] out IAudioTranscoderFactory?factory) { foreach (var transcoderFactory in Transcoders) { if (transcoderFactory.IsSupported(codec)) { factory = transcoderFactory; return(true); } } factory = default; return(false); }
public MediaClient( ProtocolSwitch protocolSwitch, IAudioSource audioSource, IAudioPlayer audioPlayer, IAudioCodec audioCodec, IJitterBuffer jitterBuffer, IClientSettings clientSettings) { _protocolSwitch = protocolSwitch; _protocolSwitch.SetMediaPacketParser(this); _audioSource = audioSource; _audioPlayer = audioPlayer; _audioCodec = audioCodec; _jitterBuffer = jitterBuffer; _clientSettings = clientSettings; }
public LiveBroadcastStreamer(string serverIp, int port, IAudioCodec audioCodec) { serverEndpoint = new IPEndPoint(IPAddress.Parse(serverIp), port); this.audioCodec = audioCodec; }
public static int CompressWAVBits(byte[] wavFileBuffer, int wavFileBufferOffset, int wavFileBufferLength, byte[] compressedBuffer, int compressedBufferOffset, IAudioCodec codec, out int pcmSize) { if (compressedBuffer.Length - compressedBufferOffset < wavFileBuffer.Length) { Array.Resize(ref compressedBuffer, wavFileBuffer.Length + compressedBufferOffset); //allocate buffers } int compressedSize; pcmSize = wavFileBuffer.Length - WAV_HEADER_SIZE; compressedSize = codec.Encode(wavFileBuffer, wavFileBufferOffset + WAV_HEADER_SIZE, pcmSize, compressedBuffer, compressedBufferOffset); //compress WAV file return(compressedSize); }
private static void AddProperties(List <MetadataItem> metadata, TagLib.File f) { if (f.Properties == null) { return; } if (f.Properties.MediaTypes != MediaTypes.None) { TimeSpan duration = f.Properties.Duration; if (duration.Ticks > 0) { AddData(metadata, MetadataType.DURATION, MetadataUtils.SecsToMetadataDuration(duration.TotalSeconds)); } } string[] formats = new string[3]; int fmtCount = 0; int w = int.MinValue, h = int.MinValue; int q = int.MinValue; foreach (ICodec codec in f.Properties.Codecs) { if ((codec.MediaTypes & MediaTypes.Video) == TagLib.MediaTypes.Video) { IVideoCodec vcodec = codec as IVideoCodec; w = vcodec.VideoWidth; h = vcodec.VideoHeight; if (HasValidData(vcodec.Description)) { formats[0] = vcodec.Description; fmtCount++; } } if ((codec.MediaTypes & MediaTypes.Audio) == TagLib.MediaTypes.Audio) { IAudioCodec acodec = codec as IAudioCodec; if (HasValidData(acodec.Description)) { StringBuilder fmt = new StringBuilder(); fmt.Append(acodec.Description); if (acodec.AudioBitrate > 0) { if (fmt.Length > 0) { fmt.Append(", "); } fmt.Append(acodec.AudioBitrate.ToString()).Append(" kb/s"); } if (acodec.AudioChannels > 0) { if (fmt.Length > 0) { fmt.Append(", "); } fmt.Append(acodec.AudioChannels.ToString()).Append(" channels"); } if (acodec.AudioSampleRate > 0) { if (fmt.Length > 0) { fmt.Append(", "); } fmt.Append(acodec.AudioSampleRate.ToString()).Append(" Hz"); } if (fmt.Length > 0) { formats[1] = fmt.ToString(); fmtCount++; } } } if ((codec.MediaTypes & MediaTypes.Photo) == TagLib.MediaTypes.Photo) { IPhotoCodec pcodec = codec as IPhotoCodec; // don't overwrite video dimensions if ((w == int.MinValue) && (h == int.MinValue)) { w = pcodec.PhotoWidth; h = pcodec.PhotoHeight; } q = pcodec.PhotoQuality; if (HasValidData(pcodec.Description)) { formats[2] = pcodec.Description; fmtCount++; } } } // size format of libextrator is NxN if ((w > int.MinValue) && (h > int.MinValue)) { AddData(metadata, MetadataType.SIZE, string.Format("{0}x{1}", w, h)); } if (q > int.MinValue) { AddData(metadata, MetadataType.IMAGE_QUALITY, q.ToString()); } // build format string StringBuilder sb = new StringBuilder(); for (int i = 0; i < formats.Length; i++) { string s = formats[i]; if (s == null) { continue; } if (sb.Length > 0) { sb.Append("; "); } if (fmtCount > 1) { sb.AppendFormat("{0}: {1}", formatTypes[i], s); } else { sb.Append(s); } } if (sb.Length > 0) { AddData(metadata, MetadataType.FORMAT, sb.ToString()); } }
public static void CompressWAVFileAndWriteToStream(string wavFileName, Stream stream, IAudioCodec codec) { int compressedSize; int pcmSize; compressedSize = CompressWAVFile(wavFileName, codec, _compressedAudioBuffer, 0, out pcmSize); stream.Write(BitConverter.GetBytes(pcmSize), 0, 4); stream.Write(BitConverter.GetBytes(compressedSize), 0, 4); stream.Write(_compressedAudioBuffer, 0, compressedSize); }
public void Read(string path) { Logger.Debug($"Starting tag read for {path}"); IsValid = false; TagLib.File file = null; try { file = TagLib.File.Create(path); var tag = file.Tag; Title = tag.Title ?? tag.TitleSort; Performers = tag.Performers ?? tag.PerformersSort; AlbumArtists = tag.AlbumArtists ?? tag.AlbumArtistsSort; Track = tag.Track; TrackCount = tag.TrackCount; Album = tag.Album ?? tag.AlbumSort; Disc = tag.Disc; DiscCount = tag.DiscCount; Year = tag.Year; Publisher = tag.Publisher; Duration = file.Properties.Duration; Genres = tag.Genres; ImageSize = tag.Pictures.FirstOrDefault()?.Data.Count ?? 0; DateTime tempDate; // Do the ones that aren't handled by the generic taglib implementation if (file.TagTypesOnDisk.HasFlag(TagTypes.Id3v2)) { var id3tag = (TagLib.Id3v2.Tag)file.GetTag(TagTypes.Id3v2); Media = id3tag.GetTextAsString("TMED"); Date = ReadId3Date(id3tag, "TDRC"); OriginalReleaseDate = ReadId3Date(id3tag, "TDOR"); } else if (file.TagTypesOnDisk.HasFlag(TagTypes.Xiph)) { // while publisher is handled by taglib, it seems to be mapped to 'ORGANIZATION' and not 'LABEL' like Picard is // https://picard.musicbrainz.org/docs/mappings/ var flactag = (TagLib.Ogg.XiphComment)file.GetTag(TagLib.TagTypes.Xiph); Media = flactag.GetField("MEDIA").ExclusiveOrDefault(); Date = DateTime.TryParse(flactag.GetField("DATE").ExclusiveOrDefault(), out tempDate) ? tempDate : default(DateTime?); OriginalReleaseDate = DateTime.TryParse(flactag.GetField("ORIGINALDATE").ExclusiveOrDefault(), out tempDate) ? tempDate : default(DateTime?); Publisher = flactag.GetField("LABEL").ExclusiveOrDefault(); } else if (file.TagTypesOnDisk.HasFlag(TagTypes.Ape)) { var apetag = (TagLib.Ape.Tag)file.GetTag(TagTypes.Ape); Media = apetag.GetItem("Media")?.ToString(); Date = DateTime.TryParse(apetag.GetItem("Year")?.ToString(), out tempDate) ? tempDate : default(DateTime?); OriginalReleaseDate = DateTime.TryParse(apetag.GetItem("Original Date")?.ToString(), out tempDate) ? tempDate : default(DateTime?); Publisher = apetag.GetItem("Label")?.ToString(); } else if (file.TagTypesOnDisk.HasFlag(TagTypes.Asf)) { var asftag = (TagLib.Asf.Tag)file.GetTag(TagTypes.Asf); Media = asftag.GetDescriptorString("WM/Media"); Date = DateTime.TryParse(asftag.GetDescriptorString("WM/Year"), out tempDate) ? tempDate : default(DateTime?); OriginalReleaseDate = DateTime.TryParse(asftag.GetDescriptorString("WM/OriginalReleaseTime"), out tempDate) ? tempDate : default(DateTime?); Publisher = asftag.GetDescriptorString("WM/Publisher"); } else if (file.TagTypesOnDisk.HasFlag(TagTypes.Apple)) { var appletag = (TagLib.Mpeg4.AppleTag)file.GetTag(TagTypes.Apple); Media = appletag.GetDashBox("com.apple.iTunes", "MEDIA"); Date = DateTime.TryParse(appletag.DataBoxes(FixAppleId("day")).FirstOrDefault()?.Text, out tempDate) ? tempDate : default(DateTime?); OriginalReleaseDate = DateTime.TryParse(appletag.GetDashBox("com.apple.iTunes", "Original Date"), out tempDate) ? tempDate : default(DateTime?); } OriginalYear = OriginalReleaseDate.HasValue ? (uint)OriginalReleaseDate?.Year : 0; foreach (ICodec codec in file.Properties.Codecs) { IAudioCodec acodec = codec as IAudioCodec; if (acodec != null && (acodec.MediaTypes & MediaTypes.Audio) != MediaTypes.None) { int bitrate = acodec.AudioBitrate; if (bitrate == 0) { // Taglib can't read bitrate for Opus. bitrate = EstimateBitrate(file, path); } Logger.Debug("Audio Properties: " + acodec.Description + ", Bitrate: " + bitrate + ", Sample Size: " + file.Properties.BitsPerSample + ", SampleRate: " + acodec.AudioSampleRate + ", Channels: " + acodec.AudioChannels); Quality = QualityParser.ParseQuality(file.Name, acodec.Description); Logger.Debug($"Quality parsed: {Quality}, Source: {Quality.QualityDetectionSource}"); MediaInfo = new MediaInfoModel { AudioFormat = acodec.Description, AudioBitrate = bitrate, AudioChannels = acodec.AudioChannels, AudioBits = file.Properties.BitsPerSample, AudioSampleRate = acodec.AudioSampleRate }; } } IsValid = true; } catch (Exception ex) { if (ex is CorruptFileException) { Logger.Warn(ex, $"Tag reading failed for {path}. File is corrupt"); } else { // Log as error so it goes to sentry with correct fingerprint Logger.Error(ex, "Tag reading failed for {0}", path); } } finally { file?.Dispose(); } // make sure these are initialized to avoid errors later on if (Quality == null) { Quality = QualityParser.ParseQuality(path); Logger.Debug($"Unable to parse qulity from tag, Quality parsed from file path: {Quality}, Source: {Quality.QualityDetectionSource}"); } MediaInfo = MediaInfo ?? new MediaInfoModel(); }
public static int CompressWAVBits(byte[] wavFileBuffer, int wavFileBufferOffset, int wavFileBufferLength, byte[] compressedBuffer, int compressedBufferOffset, IAudioCodec codec, out int pcmSize) { if (compressedBuffer.Length - compressedBufferOffset < wavFileBuffer.Length) { Array.Resize(ref compressedBuffer, wavFileBuffer.Length + compressedBufferOffset); //allocate buffers } int compressedSize; int dataChunkSizeFieldPosition; using (var stream = new MemoryStream(wavFileBuffer, wavFileBufferOffset, wavFileBufferLength)) using (var reader = new BinaryReader(stream)) { dataChunkSizeFieldPosition = stream.ScanUntilFound(Encoding.ASCII.GetBytes("data")); pcmSize = reader.ReadInt32(); } compressedSize = codec.Encode(wavFileBuffer, dataChunkSizeFieldPosition, pcmSize, compressedBuffer, compressedBufferOffset); //compress PCM data return(compressedSize); }