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));
Esempio n. 2
0
        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();
            }
        }
Esempio n. 4
0
        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));
        }
Esempio n. 5
0
        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();
        }
Esempio n. 6
0
 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;
 }
Esempio n. 7
0
        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);
Esempio n. 9
0
        public AudioRoute(IAudioCodec codec, IAudioTransport transport)
        {
            _codec     = codec;
            _transport = transport;

            _buffer = new AudioBuffer(codec);
            _first  = true;

            WaveFormat = _codec.Format.ToWaveFormat();
        }
Esempio n. 10
0
            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);
            }
Esempio n. 11
0
        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;
        }
Esempio n. 12
0
    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 !);
Esempio n. 14
0
        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);
        }
Esempio n. 15
0
 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;
 }
Esempio n. 16
0
 public LiveBroadcastStreamer(string serverIp, int port, IAudioCodec audioCodec)
 {
     serverEndpoint  = new IPEndPoint(IPAddress.Parse(serverIp), port);
     this.audioCodec = audioCodec;
 }
Esempio n. 17
0
        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);
        }
Esempio n. 18
0
        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());
            }
        }
Esempio n. 19
0
        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);
        }
Esempio n. 20
0
        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();
        }
Esempio n. 21
0
        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);
        }