internal NativeExtendedAudioFile(AudioStreamBasicDescription description, AudioFileType fileType, Stream stream)
            : base(description, fileType, stream)
        {
            Contract.Requires(stream != null);
            Contract.Ensures(_handle != null);
            Contract.Ensures(!_handle.IsClosed);

            ExtendedAudioFileStatus status = SafeNativeMethods.ExtAudioFileWrapAudioFile(Handle, true, out _handle);

            if (status != ExtendedAudioFileStatus.Ok)
            {
                throw new IOException(string.Format(CultureInfo.CurrentCulture,
                                                    Resources.NativeExtendedAudioFileInitializationError, status));
            }
        }
Example #2
0
        public void Initialize(Stream stream, AudioInfo audioInfo, MetadataDictionary metadata, SettingsDictionary settings)
        {
            Contract.Ensures(_stream != null);
            Contract.Ensures(_stream == stream);
            Contract.Ensures(_metadata != null);
            Contract.Ensures(_metadata == metadata);
            Contract.Ensures(_settings != null);
            Contract.Ensures(_settings == settings);
            Contract.Ensures(_audioFile != null);

            _stream     = stream;
            _multiplier = (float)Math.Pow(2, audioInfo.BitsPerSample - 1);
            _metadata   = metadata;
            _settings   = settings;

            AudioStreamBasicDescription inputDescription  = GetInputDescription(audioInfo);
            AudioStreamBasicDescription outputDescription = GetOutputDescription(inputDescription);

            try
            {
                _audioFile = new NativeExtendedAudioFile(outputDescription, AudioFileType.M4A, stream);

                ExtendedAudioFileStatus status = _audioFile.SetProperty(ExtendedAudioFilePropertyId.ClientDataFormat,
                                                                        inputDescription);
                if (status != ExtendedAudioFileStatus.Ok)
                {
                    throw new IOException(string.Format(CultureInfo.CurrentCulture,
                                                        Resources.SampleEncoderInitializationError, status));
                }
            }
            catch (TypeInitializationException e)
            {
                if (e.InnerException != null && e.InnerException.GetType() == typeof(ExtensionInitializationException))
                {
                    throw e.InnerException;
                }
                throw;
            }
        }
Example #3
0
        public void Submit(SampleCollection samples)
        {
            Contract.Ensures(_buffer != null);

            if (_buffer == null)
            {
                _buffer = new int[samples.SampleCount * samples.Channels];
            }

            if (!samples.IsLast)
            {
                var index = 0;
                for (var sample = 0; sample < samples.SampleCount; sample++)
                {
                    for (var channel = 0; channel < samples.Channels; channel++)
                    {
                        _buffer[index++] = (int)Math.Round(samples[channel][sample] * _multiplier);
                    }
                }

                GCHandle handle = GCHandle.Alloc(_buffer, GCHandleType.Pinned);

                try
                {
                    var bufferList = new AudioBufferList
                    {
                        NumberBuffers = 1,
                        Buffers       = new AudioBuffer[1]
                    };
                    bufferList.Buffers[0].NumberChannels = (uint)samples.Channels;
                    bufferList.Buffers[0].DataByteSize   = (uint)(index * Marshal.SizeOf <int>());
                    bufferList.Buffers[0].Data           = handle.AddrOfPinnedObject();

                    ExtendedAudioFileStatus status = _audioFile.Write(bufferList, (uint)samples.SampleCount);
                    if (status != ExtendedAudioFileStatus.Ok)
                    {
                        throw new IOException(string.Format(CultureInfo.CurrentCulture,
                                                            Resources.SampleEncoderWriteError, status));
                    }
                }
                finally
                {
                    handle.Free();
                }
            }
            else
            {
                _audioFile.Dispose();

                // Call an external MP4 encoder for writing iTunes-compatible atoms:
                _stream.Position = 0;

                ExportFactory <IMetadataEncoder> metadataEncoderFactory =
                    ExtensionProvider.GetFactories <IMetadataEncoder>("Extension", EncoderInfo.FileExtension)
                    .SingleOrDefault();
                if (metadataEncoderFactory == null)
                {
                    throw new ExtensionInitializationException(string.Format(CultureInfo.CurrentCulture,
                                                                             Resources.SampleEncoderMetadataEncoderError, EncoderInfo.FileExtension));
                }

                using (ExportLifetimeContext <IMetadataEncoder> metadataEncoderLifetime = metadataEncoderFactory.CreateExport())
                    metadataEncoderLifetime.Value.WriteMetadata(_stream, _metadata, _settings);
            }
        }
        public void Initialize(Stream stream, AudioInfo audioInfo, MetadataDictionary metadata, SettingsDictionary settings)
        {
            Contract.Ensures(_stream != null);
            Contract.Ensures(_stream == stream);
            Contract.Ensures(_metadata != null);
            Contract.Ensures(_metadata == metadata);
            Contract.Ensures(_settings != null);
            Contract.Ensures(_settings == settings);
            Contract.Ensures(_audioFile != null);

            _stream   = stream;
            _metadata = metadata;
            _settings = settings;

            // Load the external gain filter:
            ExportFactory <ISampleFilter> sampleFilterFactory =
                ExtensionProvider.GetFactories <ISampleFilter>("Name", "ReplayGain").SingleOrDefault();

            if (sampleFilterFactory == null)
            {
                throw new ExtensionInitializationException(Resources.AacSampleEncoderReplayGainFilterError);
            }
            _replayGainFilterLifetime = sampleFilterFactory.CreateExport();
            _replayGainFilterLifetime.Value.Initialize(metadata, settings);

            AudioStreamBasicDescription inputDescription  = GetInputDescription(audioInfo);
            AudioStreamBasicDescription outputDescription = GetOutputDescription(inputDescription);

            try
            {
                _audioFile = new NativeExtendedAudioFile(outputDescription, AudioFileType.M4A, stream);

                ExtendedAudioFileStatus status = _audioFile.SetProperty(ExtendedAudioFilePropertyId.ClientDataFormat,
                                                                        inputDescription);
                if (status != ExtendedAudioFileStatus.Ok)
                {
                    throw new IOException(string.Format(CultureInfo.CurrentCulture,
                                                        Resources.SampleEncoderInitializationError, status));
                }

                // Configure the audio converter:
                ConfigureConverter(settings, audioInfo.Channels,
                                   _audioFile.GetProperty <IntPtr>(ExtendedAudioFilePropertyId.AudioConverter));

                // Setting the ConverterConfig property to null resynchronizes the converter settings:
                ExtendedAudioFileStatus fileStatus = _audioFile.SetProperty(
                    ExtendedAudioFilePropertyId.ConverterConfig, IntPtr.Zero);
                if (fileStatus != ExtendedAudioFileStatus.Ok)
                {
                    throw new IOException(string.Format(CultureInfo.CurrentCulture,
                                                        Resources.SampleEncoderConverterError, status));
                }
            }
            catch (TypeInitializationException e)
            {
                if (e.InnerException != null && e.InnerException.GetType() == typeof(ExtensionInitializationException))
                {
                    throw e.InnerException;
                }
                throw;
            }
        }