public void Initialize(Stream stream, AudioInfo info, AudioMetadata metadata, SettingDictionary settings)
        {
            _stream        = stream;
            _metadata      = metadata;
            _settings      = settings;
            _bitsPerSample = info.BitsPerSample;

            // Pre-allocate the whole stream (estimate worst case compression, plus cover art)
            stream.SetLength(info.FrameCount * info.Channels * (long)Math.Ceiling(info.BitsPerSample / 8.0)
                             + (metadata.CoverArt?.Data.Length ?? 0));

            var inputDescription = GetInputDescription(info);

            _audioFile = new ExtendedAudioFile(GetOutputDescription(inputDescription), AudioFileType.M4A, stream);
            _audioFile.SetProperty(ExtendedAudioFilePropertyId.ClientDataFormat, inputDescription);
        }
Example #2
0
        public void Finish()
        {
            // ReSharper disable once PossibleNullReferenceException
            _audioFile.Dispose();
            _audioFile = null;

            // ReSharper disable once PossibleNullReferenceException
            _stream.Position = 0;

            // Call the external MP4 encoder for writing iTunes-compatible atoms
            var metadataEncoderFactory =
                ExtensionProvider.GetFactories <IAudioMetadataEncoder>("Extension", FileExtension).FirstOrDefault();

            if (metadataEncoderFactory == null)
            {
                return;
            }
            using (var export = metadataEncoderFactory.CreateExport())
                // ReSharper disable twice AssignNullToNotNullAttribute
                export.Value.WriteMetadata(_stream, _metadata, _settings);
        }
Example #3
0
        public void Initialize(Stream stream, AudioInfo info, AudioMetadata metadata, SettingDictionary settings)
        {
            _stream   = stream;
            _metadata = metadata;
            _settings = settings;

            InitializeReplayGainFilter(info, metadata, settings);

            var inputDescription = GetInputDescription(info);

            _audioFile = new ExtendedAudioFile(GetOutputDescription(inputDescription), AudioFileType.M4A, stream);
            _audioFile.SetProperty(ExtendedAudioFilePropertyId.ClientDataFormat, inputDescription);

            var converter = _audioFile.GetProperty <IntPtr>(ExtendedAudioFilePropertyId.AudioConverter);

            var logger = LoggerManager.LoggerFactory.CreateLogger <AacAudioEncoder>();

            // Enable high quality (defaults to medium, 0x40)
            SetConverterProperty(converter, AudioConverterPropertyId.CodecQuality, 0x60);

            if (settings.TryGetValue("BitRate", out int bitRate))
            {
                if (bitRate > 256 && info.Channels == 1)
                {
                    logger.LogWarning("The maximum bitrate for 1-channel audio is 256 kbps.");
                    bitRate = 256;
                }
                else if (bitRate < 64 && info.Channels == 2)
                {
                    logger.LogWarning("The minimum bitrate for 2-channel audio is 64 kbps.");
                    bitRate = 64;
                }

                SetConverterProperty(converter, AudioConverterPropertyId.BitRate, bitRate * 1000);

                // Set the control mode (constrained is the default)
                var controlMode = BitrateControlMode.VariableConstrained;
                if (settings.TryGetValue("ControlMode", out string controlModeValue))
                {
                    if (controlModeValue.Equals("Average", StringComparison.OrdinalIgnoreCase))
                    {
                        controlMode = BitrateControlMode.LongTermAverage;
                    }
                    else if (controlModeValue.Equals("Constant", StringComparison.OrdinalIgnoreCase))
                    {
                        controlMode = BitrateControlMode.Constant;
                    }
                }
                SetConverterProperty(converter, AudioConverterPropertyId.BitRateControlMode, (uint)controlMode);
            }
            else
            {
                // Enable a true variable bitrate
                SetConverterProperty(converter, AudioConverterPropertyId.BitRateControlMode,
                                     (uint)BitrateControlMode.Variable);

                // Use a default VBR quality index of 9
                SetConverterProperty(converter, AudioConverterPropertyId.VbrQuality,
                                     settings.TryGetValue("VBRQuality", out int quality)
                        ? _vbrQualities[quality]
                        : _vbrQualities[9]);
            }

            // Setting the ConverterConfig property to null resynchronizes the converter settings
            _audioFile.SetProperty(ExtendedAudioFilePropertyId.ConverterConfig, IntPtr.Zero);
        }