/// <summary>
        /// Transcodes the source audio to the target format and quality.
        /// </summary>
        /// <param name="formatType">Format of the processed source audio: WAV, MP3 or WMA.</param>
        /// <param name="quality">Quality of the processed source audio. It can be one of the following: Low (96 kbps), Medium (128 kbps), Best (192 kbps)</param>
        /// <param name="targetFileName">Name of the file containing the processed source audio.</param>
        public void ConvertFormat(ConversionFormat formatType, ConversionQuality quality, string targetFileName)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("AudioContent");
            }

            throw new NotImplementedException();
        }
        /// <summary>
        /// Returns the sample rate for the given quality setting.
        /// </summary>
        /// <param name="quality">The quality setting.</param>
        /// <returns>The sample rate for the quality.</returns>
        int QualityToSampleRate(ConversionQuality quality)
        {
            switch (quality)
            {
            case ConversionQuality.Low:
                return(Math.Max(8000, format.SampleRate / 2));
            }

            return(Math.Max(8000, format.SampleRate));
        }
        /// <summary>
        /// Returns the bitrate for the given quality setting.
        /// </summary>
        /// <param name="quality">The quality setting.</param>
        /// <returns>The bitrate for the quality.</returns>
        int QualityToBitRate(ConversionQuality quality)
        {
            switch (quality)
            {
            case ConversionQuality.Low:
                return(96000);

            case ConversionQuality.Medium:
                return(128000);
            }

            return(192000);
        }
        protected static int QualityToSampleRate(ConversionQuality quality, int sourceSampleRate)
        {
            switch (quality)
            {
            case ConversionQuality.Low:
                return(Math.Max(8000, (int)Math.Floor(sourceSampleRate / 2.0)));

            case ConversionQuality.Medium:
                return(Math.Max(8000, (int)Math.Floor((sourceSampleRate / 4.0) * 3)));
            }

            return(Math.Max(8000, sourceSampleRate));
        }
Exemple #5
0
        protected static int QualityToBitRate(ConversionQuality quality)
        {
            switch (quality)
            {
            case ConversionQuality.Low:
                return(96000);

            case ConversionQuality.Medium:
                return(128000);

            default:
                return(192000);
            }
        }
        /// <summary>
        ///     Converts the input image to a desired PixelFormat using
        ///     a specified conversion quality and conversion type.
        /// </summary>
        /// <param name="img"> Input image </param>
        /// <param name="format"> Desired PixelFormat </param>
        /// <param name="quality"> Conversion quality </param>
        /// <param name="type"> Conversion type </param>
        public static Bitmap ConvertToFormat(
            Bitmap img,
            PixelFormat format,
            ConversionQuality quality = ConversionQuality.LowQuality,
            ConversionType type = ConversionType.Copy)
        {
            if (format == img.PixelFormat) return img;

            var bmp = new Bitmap(img.Width, img.Height, format);
            using (var g = Graphics.FromImage(bmp))
            {
                SetConversionQuality(g, quality);
                g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));
            }
            SetConversionType(ref img, bmp, type);
            return bmp;
        }
Exemple #7
0
        /// <summary>
        /// Transcodes the source audio to the target format and quality.
        /// </summary>
        /// <param name="formatType">Format to convert this audio to.</param>
        /// <param name="quality">Quality of the processed output audio. For streaming formats, it can be one of the following: Low (96 kbps), Medium (128 kbps), Best (192 kbps).  For WAV formats, it can be one of the following: Low (11kHz ADPCM), Medium (22kHz ADPCM), Best (44kHz PCM)</param>
        /// <param name="targetFileName">Name of the file containing the processed source audio. Must be null for Wav and Adpcm. Must not be null for streaming compressed formats.</param>
        public void ConvertFormat(ConversionFormat formatType, ConversionQuality quality, string targetFileName)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("AudioContent");
            }

            switch (formatType)
            {
            case ConversionFormat.Adpcm:
                ConvertWav(new AdpcmWaveFormat(QualityToSampleRate(quality), format.ChannelCount));
                break;

            case ConversionFormat.Pcm:
                ConvertWav(new WaveFormat(QualityToSampleRate(quality), format.ChannelCount));
                break;

            case ConversionFormat.WindowsMedia:
#if WINDOWS
                reader.Position = 0;
                MediaFoundationEncoder.EncodeToWma(reader, targetFileName, QualityToBitRate(quality));
                break;
#else
                throw new NotSupportedException("WindowsMedia encoding supported on Windows only");
#endif

            case ConversionFormat.Xma:
                throw new NotSupportedException("XMA is not a supported encoding format. It is specific to the Xbox 360.");

            case ConversionFormat.ImaAdpcm:
                ConvertWav(new ImaAdpcmWaveFormat(QualityToSampleRate(quality), format.ChannelCount, 4));
                break;

            case ConversionFormat.Aac:
#if WINDOWS
                reader.Position = 0;
                MediaFoundationEncoder.EncodeToAac(reader, targetFileName, QualityToBitRate(quality));
                break;
#else
                throw new NotImplementedException();
#endif

            case ConversionFormat.Vorbis:
                throw new NotImplementedException("Vorbis is not yet implemented as an encoding format.");
            }
        }
        public override ConversionQuality ConvertStreamingAudio(
            TargetPlatform platform,
            ConversionQuality quality,
            AudioContent content,
            string inputFile,
            out string destinationFile)
        {
            var targetFormat = PlatformToFormat(platform);

            // Get the song output path with the target format extension.
            destinationFile = Path.ChangeExtension(
                inputFile, AudioHelper.GetExtension(targetFormat));

            // Make sure the output folder for the file exists.
            Directory.CreateDirectory(Path.GetDirectoryName(destinationFile));

            return(ConvertToFormat(content, targetFormat, quality, destinationFile));
        }
        public override ConversionQuality ConvertAudio(TargetPlatform platform, ConversionQuality quality, AudioContent content)
        {
            // Default to PCM data, or ADPCM if the source is ADPCM.
            var targetFormat = ConversionFormat.Pcm;

            if (quality != ConversionQuality.Best || content.Format.Format == 2 || content.Format.Format == 17)
            {
                if (platform == TargetPlatform.iOS || platform == TargetPlatform.MacOSX || platform == TargetPlatform.DesktopGL)
                {
                    targetFormat = ConversionFormat.ImaAdpcm;
                }
                else
                {
                    targetFormat = ConversionFormat.Adpcm;
                }
            }

            return(ConvertToFormat(content, targetFormat, quality, null));
        }
        public override ConversionQuality ConvertAudio(TargetPlatform platform, ConversionQuality quality, AudioContent content)
        {
            // Default to PCM data.
            var targetFormat = ConversionFormat.Pcm;

            if (quality != ConversionQuality.Best)
            {
                if (platform == TargetPlatform.iOS || platform == TargetPlatform.MacOSX)
                {
                    targetFormat = ConversionFormat.ImaAdpcm;
                }
                else
                {
                    targetFormat = ConversionFormat.Adpcm;
                }
            }

            return(ConvertToFormat(content, targetFormat, quality, null));
        }
        public void ConvertAudio(string sourceFile, ConversionFormat format, ConversionQuality quality, int channels, int averageBytesPerSecond, int sampleRate, int bitsPerSample, int blockAlign)
        {
            var content = new AudioContent(sourceFile, AudioFileType.Wav);

            content.ConvertFormat(format, quality, null);

            Assert.AreEqual(ToWavFormat(format, content.Format.BitsPerSample), content.Format.Format);
            Assert.AreEqual(channels, content.Format.ChannelCount);
            Assert.AreEqual(bitsPerSample, content.Format.BitsPerSample);

            // TODO: We don't quite match right with XNA on these.
            // We should look to fix this for 100% compatibility.
            if (format != ConversionFormat.Adpcm)
            {
                Assert.AreEqual(sampleRate, content.Format.SampleRate);
                Assert.AreEqual(averageBytesPerSecond, content.Format.AverageBytesPerSecond);
                Assert.AreEqual(blockAlign, content.Format.BlockAlign);
            }

            content.Dispose();
        }
        public override ConversionQuality ConvertAudio(
            TargetPlatform platform,
            ConversionQuality quality,
            AudioContent content)
        {
            //// Default to PCM data, or ADPCM if the source is ADPCM.
            //var targetFormat = ConversionFormat.Pcm;
            //
            //if (quality != ConversionQuality.Best ||
            //    content.Format.Format == 2 ||
            //    content.Format.Format == 17)
            //{
            //    if (platform == TargetPlatform.iOS ||
            //        platform == TargetPlatform.MacOSX ||
            //        platform == TargetPlatform.DesktopGL)
            //        targetFormat = ConversionFormat.ImaAdpcm;
            //    else
            //        targetFormat = ConversionFormat.Adpcm;
            //}

            var targetFormat = ConversionFormat.Vorbis;

            return(ConvertToFormat(content, targetFormat, quality, null));
        }
Exemple #13
0
        /// <summary>
        /// Returns the bitrate for the given quality setting.
        /// </summary>
        /// <param name="quality">The quality setting.</param>
        /// <returns>The bitrate for the quality.</returns>
        int QualityToBitRate(ConversionQuality quality)
        {
            switch (quality)
            {
                case ConversionQuality.Low:
                    return 96000;
                case ConversionQuality.Medium:
                    return 128000;
            }

            return 192000;
        }
Exemple #14
0
        /// <summary>
        /// Transcodes the source audio to the target format and quality.
        /// </summary>
        /// <param name="formatType">Format to convert this audio to.</param>
        /// <param name="quality">Quality of the processed output audio. For streaming formats, it can be one of the following: Low (96 kbps), Medium (128 kbps), Best (192 kbps).  For WAV formats, it can be one of the following: Low (11kHz ADPCM), Medium (22kHz ADPCM), Best (44kHz PCM)</param>
        /// <param name="targetFileName">Name of the file containing the processed source audio. Must be null for Wav and Adpcm. Must not be null for streaming compressed formats.</param>
        public void ConvertFormat(ConversionFormat formatType, ConversionQuality quality, string targetFileName)
        {
            if (disposed)
                throw new ObjectDisposedException("AudioContent");


        switch (formatType)
            {
                case ConversionFormat.Adpcm:
#if WINDOWS
                    ConvertWav(new AdpcmWaveFormat(QualityToSampleRate(quality), format.ChannelCount));
                    break;
#else
                    throw new NotSupportedException("Adpcm encoding supported on Windows only");
#endif

                case ConversionFormat.Pcm:
#if WINDOWS
                    ConvertWav(new WaveFormat(QualityToSampleRate(quality), format.ChannelCount));
                    break;
#elif LINUX
                    // TODO Do the conversion for Linux platform
                    throw new NotSupportedException("Pcm has not been implemented on this platform");
#else //MONOMAC
                    targetFileName = Guid.NewGuid().ToString() + ".wav";
                    if (!ConvertAudio.Convert(fileName, targetFileName, AudioFormatType.LinearPCM, MonoMac.AudioToolbox.AudioFileType.WAVE, quality)) {
                        throw new InvalidDataException("Failed to convert to PCM");
                    }
                    Read(targetFileName);
                    if (File.Exists(targetFileName))
                        File.Delete(targetFileName);
                    break;
#endif

                case ConversionFormat.WindowsMedia:
#if WINDOWS
                    reader.Position = 0;
                    MediaFoundationEncoder.EncodeToWma(reader, targetFileName, QualityToBitRate(quality));
                    break;
#else
                    throw new NotSupportedException("WindowsMedia encoding supported on Windows only");
#endif

                case ConversionFormat.Xma:
                    throw new NotSupportedException("XMA is not a supported encoding format. It is specific to the Xbox 360.");

                case ConversionFormat.ImaAdpcm:
#if WINDOWS
                    ConvertWav(new ImaAdpcmWaveFormat(QualityToSampleRate(quality), format.ChannelCount, 4));
                    break;
#else
                    throw new NotImplementedException("ImaAdpcm has not been implemented on this platform");
#endif

                case ConversionFormat.Aac:
#if WINDOWS
                    reader.Position = 0;
                    var mediaType = SelectMediaType (AudioSubtypes.MFAudioFormat_AAC, reader.WaveFormat, QualityToBitRate (quality));
                    if (mediaType == null) {
                        throw new InvalidDataException ("Cound not find a suitable mediaType to convert to.");
                    }
                    using (var encoder = new MediaFoundationEncoder (mediaType)) {
                        encoder.Encode (targetFileName, reader);
                    }
                    break;
#elif LINUX
                    // TODO: Code for Linux convertion
                    throw new NotImplementedException("Aac has not been implemented on this platform");
#else //MONOMAC
                    if (!ConvertAudio.Convert(fileName, targetFileName, AudioFormatType.MPEG4AAC, MonoMac.AudioToolbox.AudioFileType.MPEG4, quality)) {
                        throw new InvalidDataException("Failed to convert to AAC");
                    }
                    break;
#endif

                case ConversionFormat.Vorbis:
                    throw new NotImplementedException("Vorbis is not yet implemented as an encoding format.");
            }
        }
Exemple #15
0
        /// <summary>
        /// Transcodes the source audio to the target format and quality.
        /// </summary>
        /// <param name="formatType">Format of the processed source audio: WAV, MP3 or WMA.</param>
        /// <param name="quality">Quality of the processed source audio. It can be one of the following: Low (96 kbps), Medium (128 kbps), Best (192 kbps)</param>
        /// <param name="targetFileName">Name of the file containing the processed source audio.</param>
        public void ConvertFormat(ConversionFormat formatType, ConversionQuality quality, string targetFileName)
        {
            if (disposed)
                throw new ObjectDisposedException("AudioContent");

            throw new NotImplementedException();
        }
        public static ConversionQuality ConvertToFormat(AudioContent content, ConversionFormat formatType, ConversionQuality quality, string saveToFile)
        {
            var temporaryOutput = Path.GetTempFileName();

            try
            {
                string ffmpegCodecName, ffmpegMuxerName;
                //int format;
                switch (formatType)
                {
                case ConversionFormat.Adpcm:
                    // ADPCM Microsoft
                    ffmpegCodecName = "adpcm_ms";
                    ffmpegMuxerName = "wav";
                    //format = 0x0002; /* WAVE_FORMAT_ADPCM */
                    break;

                case ConversionFormat.Pcm:
                    // XNA seems to preserve the bit size of the input
                    // format when converting to PCM.
                    if (content.Format.BitsPerSample == 8)
                    {
                        ffmpegCodecName = "pcm_u8";
                    }
                    else if (content.Format.BitsPerSample == 32 && content.Format.Format == 3)
                    {
                        ffmpegCodecName = "pcm_f32le";
                    }
                    else
                    {
                        ffmpegCodecName = "pcm_s16le";
                    }
                    ffmpegMuxerName = "wav";
                    //format = 0x0001; /* WAVE_FORMAT_PCM */
                    break;

                case ConversionFormat.WindowsMedia:
                    // Windows Media Audio 2
                    ffmpegCodecName = "wmav2";
                    ffmpegMuxerName = "asf";
                    //format = 0x0161; /* WAVE_FORMAT_WMAUDIO2 */
                    break;

                case ConversionFormat.Xma:
                    throw new NotSupportedException(
                              "XMA is not a supported encoding format. It is specific to the Xbox 360.");

                case ConversionFormat.ImaAdpcm:
                    // ADPCM IMA WAV
                    ffmpegCodecName = "adpcm_ima_wav";
                    ffmpegMuxerName = "wav";
                    //format = 0x0011; /* WAVE_FORMAT_IMA_ADPCM */
                    break;

                case ConversionFormat.Aac:
                    // AAC (Advanced Audio Coding)
                    // Requires -strict experimental
                    ffmpegCodecName = "aac";
                    ffmpegMuxerName = "ipod";
                    //format = 0x0000; /* WAVE_FORMAT_UNKNOWN */
                    break;

                case ConversionFormat.Vorbis:
                    // Vorbis
                    ffmpegCodecName = "libvorbis";
                    ffmpegMuxerName = "ogg";
                    //format = 0x0000; /* WAVE_FORMAT_UNKNOWN */
                    break;

                default:
                    // Unknown format
                    throw new NotSupportedException();
                }

                string ffmpegStdout, ffmpegStderr;
                int    ffmpegExitCode;
                do
                {
                    ffmpegExitCode = ExternalTool.Run(
                        "ffmpeg",
                        string.Format(
                            "-y -i \"{0}\" -vn -c:a {1} -b:a {2} -ar {3} -f:a {4} -strict experimental \"{5}\"",
                            content.FileName,
                            ffmpegCodecName,
                            QualityToBitRate(quality),
                            QualityToSampleRate(quality, content.Format.SampleRate),
                            ffmpegMuxerName,
                            temporaryOutput),
                        out ffmpegStdout,
                        out ffmpegStderr);
                    if (ffmpegExitCode != 0)
                    {
                        quality--;
                    }
                } while (quality >= 0 && ffmpegExitCode != 0);

                if (ffmpegExitCode != 0)
                {
                    throw new InvalidOperationException("ffmpeg exited with non-zero exit code: \n" + ffmpegStdout + "\n" + ffmpegStderr);
                }

                byte[] rawData;
                using (var fs = new FileStream(temporaryOutput, FileMode.Open, FileAccess.Read))
                {
                    rawData = new byte[fs.Length];
                    fs.Read(rawData, 0, rawData.Length);
                }

                if (saveToFile != null)
                {
                    using (var fs = new FileStream(saveToFile, FileMode.Create, FileAccess.Write))
                        fs.Write(rawData, 0, rawData.Length);
                }

                // Use probe to get the final format and information on the converted file.
                AudioFileType audioFileType;
                AudioFormat   audioFormat;
                TimeSpan      duration;
                int           loopStart, loopLength;
                ProbeFormat(temporaryOutput, out audioFileType, out audioFormat, out duration, out loopStart, out loopLength);

                AudioFormat riffAudioFormat;
                byte[]      data = StripRiffWaveHeader(rawData, out riffAudioFormat);

                // deal with adpcm
                if (audioFormat.Format == 2 || audioFormat.Format == 17)
                {
                    // riff contains correct blockAlign
                    audioFormat = riffAudioFormat;

                    // fix loopLength -> has to be multiple of sample per block
                    // see https://msdn.microsoft.com/de-de/library/windows/desktop/ee415711(v=vs.85).aspx
                    int samplesPerBlock = SampleAlignment(audioFormat);
                    loopLength = (int)(audioFormat.SampleRate * duration.TotalSeconds);
                    int remainder = loopLength % samplesPerBlock;
                    loopLength += samplesPerBlock - remainder;
                }

                content.SetData(data, audioFormat, duration, loopStart, loopLength);
            }
            finally
            {
                ExternalTool.DeleteFile(temporaryOutput);
            }

            return(quality);
        }
Exemple #17
0
        /// <summary>
        /// Transcodes the source audio to the target format and quality.
        /// </summary>
        /// <param name="formatType">Format to convert this audio to.</param>
        /// <param name="quality">Quality of the processed output audio. For streaming formats, it can be one of the following: Low (96 kbps), Medium (128 kbps), Best (192 kbps).  For WAV formats, it can be one of the following: Low (11kHz ADPCM), Medium (22kHz ADPCM), Best (44kHz PCM)</param>
        /// <param name="saveToFile">
        /// The name of the file that the converted audio should be saved into.  This is used for SongContent, where
        /// the audio is stored external to the XNB file.  If this is null, then the converted audio is stored in
        /// the Data property.
        /// </param>
        public void ConvertFormat(ConversionFormat formatType, ConversionQuality quality, string saveToFile)
        {
            var temporarySource = Path.GetTempFileName();
            var temporaryOutput = Path.GetTempFileName();

            try
            {
                using (var fs = new FileStream(temporarySource, FileMode.Create, FileAccess.Write))
                {
                    var dataBytes = this.data.ToArray();
                    fs.Write(dataBytes, 0, dataBytes.Length);
                }

                string ffmpegCodecName, ffmpegMuxerName;
                int    format;
                switch (formatType)
                {
                case ConversionFormat.Adpcm:
                    // ADPCM Microsoft
                    ffmpegCodecName = "adpcm_ms";
                    ffmpegMuxerName = "wav";
                    format          = 0x0002; /* WAVE_FORMAT_ADPCM */
                    break;

                case ConversionFormat.Pcm:
                    // PCM signed 16-bit little-endian
                    ffmpegCodecName = "pcm_s16le";
                    ffmpegMuxerName = "wav";
                    format          = 0x0001; /* WAVE_FORMAT_PCM */
                    break;

                case ConversionFormat.WindowsMedia:
                    // Windows Media Audio 2
                    ffmpegCodecName = "wmav2";
                    ffmpegMuxerName = "asf";
                    format          = 0x0161; /* WAVE_FORMAT_WMAUDIO2 */
                    break;

                case ConversionFormat.Xma:
                    throw new NotSupportedException(
                              "XMA is not a supported encoding format. It is specific to the Xbox 360.");

                case ConversionFormat.ImaAdpcm:
                    // ADPCM IMA WAV
                    ffmpegCodecName = "adpcm_ima_wav";
                    ffmpegMuxerName = "wav";
                    format          = 0x0011; /* WAVE_FORMAT_IMA_ADPCM */
                    break;

                case ConversionFormat.Aac:
                    // AAC (Advanced Audio Coding)
                    // Requires -strict experimental
                    ffmpegCodecName = "aac";
                    ffmpegMuxerName = "ipod";
                    format          = 0x0000; /* WAVE_FORMAT_UNKNOWN */
                    break;

                case ConversionFormat.Vorbis:
                    // Vorbis
                    ffmpegCodecName = "libvorbis";
                    ffmpegMuxerName = "ogg";
                    format          = 0x0000; /* WAVE_FORMAT_UNKNOWN */
                    break;

                default:
                    // Unknown format
                    throw new NotSupportedException();
                }

                string ffmpegStdout, ffmpegStderr;
                var    ffmpegExitCode = ExternalTool.Run(
                    "ffmpeg",
                    string.Format(
                        "-y -i \"{0}\" -vn -c:a {1} -b:a {2} -f:a {3} -strict experimental \"{4}\"",
                        temporarySource,
                        ffmpegCodecName,
                        QualityToBitRate(quality),
                        ffmpegMuxerName,
                        temporaryOutput),
                    out ffmpegStdout,
                    out ffmpegStderr);
                if (ffmpegExitCode != 0)
                {
                    throw new InvalidOperationException("ffmpeg exited with non-zero exit code: \n" + ffmpegStdout + "\n" + ffmpegStderr);
                }

                byte[] rawData;
                using (var fs = new FileStream(temporaryOutput, FileMode.Open, FileAccess.Read))
                {
                    rawData = new byte[fs.Length];
                    fs.Read(rawData, 0, rawData.Length);
                }

                if (saveToFile != null)
                {
                    using (var fs = new FileStream(saveToFile, FileMode.Create, FileAccess.Write))
                    {
                        fs.Write(rawData, 0, rawData.Length);
                    }

                    this.data = null;
                }
                else
                {
                    this.data = rawData.ToList();
                }

                // Get the audio metadata from the output file
                string ffprobeStdout, ffprobeStderr;
                var    ffprobeExitCode = ExternalTool.Run(
                    "ffprobe",
                    string.Format("-i \"{0}\" -show_entries streams -v quiet -of flat", temporaryOutput),
                    out ffprobeStdout,
                    out ffprobeStderr);
                if (ffprobeExitCode != 0)
                {
                    throw new InvalidOperationException("ffprobe exited with non-zero exit code.");
                }

                // Set default values if information is not available.
                int    averageBytesPerSecond = 0;
                int    bitsPerSample         = 0;
                int    blockAlign            = 0;
                int    channelCount          = 0;
                int    sampleRate            = 0;
                double durationInSeconds     = 0;

                var numberFormat = System.Globalization.CultureInfo.InvariantCulture.NumberFormat;
                foreach (var line in ffprobeStdout.Split(new[] { '\r', '\n', '\0' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    var kv = line.Split(new[] { '=' }, 2);

                    switch (kv[0])
                    {
                    case "streams.stream.0.sample_rate":
                        sampleRate = int.Parse(kv[1].Trim('"'), numberFormat);
                        break;

                    case "streams.stream.0.bits_per_sample":
                        bitsPerSample = int.Parse(kv[1].Trim('"'), numberFormat);
                        break;

                    case "streams.stream.0.duration":
                        durationInSeconds = double.Parse(kv[1].Trim('"'), numberFormat);
                        break;

                    case "streams.stream.0.channels":
                        channelCount = int.Parse(kv[1].Trim('"'), numberFormat);
                        break;

                    case "streams.stream.0.bit_rate":
                        averageBytesPerSecond = (int.Parse(kv[1].Trim('"'), numberFormat) / 8);
                        break;
                    }
                }

                // Calculate blockAlign.
                switch (formatType)
                {
                case ConversionFormat.Adpcm:
                case ConversionFormat.ImaAdpcm:
                case ConversionFormat.Pcm:
                    // Block alignment value is the number of bytes in an atomic unit (that is, a block) of audio for a particular format. For Pulse Code Modulation (PCM) formats, the formula for calculating block alignment is as follows:
                    //  •   Block Alignment = Bytes per Sample x Number of Channels
                    // For example, the block alignment value for 16-bit PCM format mono audio is 2 (2 bytes per sample x 1 channel). For 16-bit PCM format stereo audio, the block alignment value is 4.
                    // https://msdn.microsoft.com/en-us/library/system.speech.audioformat.speechaudioformatinfo.blockalign(v=vs.110).aspx
                    // Get the raw PCM from the output WAV file
                    using (var reader = new BinaryReader(new MemoryStream(rawData)))
                    {
                        data = GetRawWavData(reader, ref blockAlign).ToList();
                    }
                    break;

                default:
                    // blockAlign is not available from ffprobe (and may or may not
                    // be relevant for non-PCM formats anyway)
                    break;
                }

                this.duration = TimeSpan.FromSeconds(durationInSeconds);
                this.format   = new AudioFormat(
                    averageBytesPerSecond,
                    bitsPerSample,
                    blockAlign,
                    channelCount,
                    format,
                    sampleRate);

                // Loop start and length in number of samples. Defaults to entire sound
                loopStart = 0;
                if (data != null && bitsPerSample > 0 && channelCount > 0)
                {
                    loopLength = data.Count / ((bitsPerSample / 8) * channelCount);
                }
                else
                {
                    loopLength = 0;
                }
            }
            finally
            {
                File.Delete(temporarySource);
                File.Delete(temporaryOutput);
            }
        }
Exemple #18
0
        /// <summary>
        /// Transcodes the source audio to the target format and quality.
        /// </summary>
        /// <param name="formatType">Format to convert this audio to.</param>
        /// <param name="quality">Quality of the processed output audio. For streaming formats, it can be one of the following: Low (96 kbps), Medium (128 kbps), Best (192 kbps).  For WAV formats, it can be one of the following: Low (11kHz ADPCM), Medium (22kHz ADPCM), Best (44kHz PCM)</param>
        /// <param name="saveToFile">
        /// The name of the file that the converted audio should be saved into.  This is used for SongContent, where
        /// the audio is stored external to the XNB file.  If this is null, then the converted audio is stored in
        /// the Data property.
        /// </param>
        public void ConvertFormat(ConversionFormat formatType, ConversionQuality quality, string saveToFile)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("AudioContent");
            }

            var temporarySource = Path.GetTempFileName();
            var temporaryOutput = Path.GetTempFileName();

            try
            {
                using (var fs = new FileStream(temporarySource, FileMode.Create, FileAccess.Write))
                {
                    var dataBytes = this.data.ToArray();
                    fs.Write(dataBytes, 0, dataBytes.Length);
                }

                string ffmpegCodecName, ffmpegMuxerName;
                int    format;
                switch (formatType)
                {
                case ConversionFormat.Adpcm:
                    // ADPCM Microsoft
                    ffmpegCodecName = "adpcm_ms";
                    ffmpegMuxerName = "wav";
                    format          = 0x0002; /* WAVE_FORMAT_ADPCM */
                    break;

                case ConversionFormat.Pcm:
                    // PCM signed 16-bit little-endian
                    ffmpegCodecName = "pcm_s16le";
                    ffmpegMuxerName = "s16le";
                    format          = 0x0001; /* WAVE_FORMAT_PCM */
                    break;

                case ConversionFormat.WindowsMedia:
                    // Windows Media Audio 2
                    ffmpegCodecName = "wmav2";
                    ffmpegMuxerName = "asf";
                    format          = 0x0161; /* WAVE_FORMAT_WMAUDIO2 */
                    break;

                case ConversionFormat.Xma:
                    throw new NotSupportedException(
                              "XMA is not a supported encoding format. It is specific to the Xbox 360.");

                case ConversionFormat.ImaAdpcm:
                    // ADPCM IMA WAV
                    ffmpegCodecName = "adpcm_ima_wav";
                    ffmpegMuxerName = "wav";
                    format          = 0x0011; /* WAVE_FORMAT_IMA_ADPCM */
                    break;

                case ConversionFormat.Aac:
                    // AAC (Advanced Audio Coding)
                    // Requires -strict experimental
                    ffmpegCodecName = "aac";
                    ffmpegMuxerName = "ipod";
                    format          = 0x0000; /* WAVE_FORMAT_UNKNOWN */
                    break;

                case ConversionFormat.Vorbis:
                    // Vorbis
                    ffmpegCodecName = "libvorbis";
                    ffmpegMuxerName = "ogg";
                    format          = 0x0000; /* WAVE_FORMAT_UNKNOWN */
                    break;

                default:
                    // Unknown format
                    throw new NotSupportedException();
                }

                string ffmpegStdout, ffmpegStderr;
                var    ffmpegExitCode = ExternalTool.Run(
                    "ffmpeg",
                    string.Format(
                        "-y -i \"{0}\" -vn -c:a {1} -b:a {2} -f:a {3} -strict experimental \"{4}\"",
                        temporarySource,
                        ffmpegCodecName,
                        QualityToBitRate(quality),
                        ffmpegMuxerName,
                        temporaryOutput),
                    out ffmpegStdout,
                    out ffmpegStderr);
                if (ffmpegExitCode != 0)
                {
                    throw new InvalidOperationException("ffmpeg exited with non-zero exit code: \n" + ffmpegStdout + "\n" + ffmpegStderr);
                }

                byte[] rawData;
                using (var fs = new FileStream(temporaryOutput, FileMode.Open, FileAccess.Read))
                {
                    rawData = new byte[fs.Length];
                    fs.Read(rawData, 0, rawData.Length);
                }

                if (saveToFile != null)
                {
                    using (var fs = new FileStream(saveToFile, FileMode.Create, FileAccess.Write))
                    {
                        fs.Write(rawData, 0, rawData.Length);
                    }

                    this.data = null;
                }
                else
                {
                    this.data = rawData.ToList();
                }

                string ffprobeStdout, ffprobeStderr;
                var    ffprobeExitCode = ExternalTool.Run(
                    "ffprobe",
                    string.Format("-i \"{0}\" -show_entries streams -v quiet -of flat", temporarySource),
                    out ffprobeStdout,
                    out ffprobeStderr);
                if (ffprobeExitCode != 0)
                {
                    throw new InvalidOperationException("ffprobe exited with non-zero exit code.");
                }

                // Set default values if information is not available.
                int    averageBytesPerSecond = 0;
                int    bitsPerSample         = 0;
                int    blockAlign            = 0;
                int    channelCount          = 0;
                int    sampleRate            = 0;
                double durationInSeconds     = 0;

                var numberFormat = System.Globalization.CultureInfo.InvariantCulture.NumberFormat;
                foreach (var line in ffprobeStdout.Split(new[] { '\r', '\n', '\0' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    var kv = line.Split(new[] { '=' }, 2);

                    switch (kv[0])
                    {
                    case "streams.stream.0.sample_rate":
                        sampleRate = int.Parse(kv[1].Trim('"'), numberFormat);
                        break;

                    case "streams.stream.0.bits_per_sample":
                        bitsPerSample = int.Parse(kv[1].Trim('"'), numberFormat);
                        break;

                    case "streams.stream.0.duration":
                        durationInSeconds = double.Parse(kv[1].Trim('"'), numberFormat);
                        break;

                    case "streams.stream.0.channels":
                        channelCount = int.Parse(kv[1].Trim('"'), numberFormat);
                        break;
                    }
                }

                // This information is not available from ffprobe (and may or may not
                // be relevant for non-PCM formats anyway):
                //
                // * averageBytesPerSecond
                // * blockAlign

                this.duration = TimeSpan.FromSeconds(durationInSeconds);
                this.format   = new AudioFormat(
                    averageBytesPerSecond,
                    bitsPerSample,
                    blockAlign,
                    channelCount,
                    format,
                    sampleRate);
            }
            finally
            {
                File.Delete(temporarySource);
                File.Delete(temporaryOutput);
            }
        }
Exemple #19
0
		public void ConvertFormat(ConversionFormat formatType, ConversionQuality quality, string targetFileName)
		{
			throw new NotImplementedException();
		}
Exemple #20
0
 public void ConvertFormat(ConversionFormat formatType, ConversionQuality quality, string targetFileName)
 {
     throw new NotImplementedException();
 }
 private static void SetConversionQuality(Graphics graphics, ConversionQuality quality)
 {
     switch (quality)
     {
         case ConversionQuality.LowQuality:
             graphics.CompositingMode = CompositingMode.SourceCopy;
             graphics.CompositingQuality = CompositingQuality.HighSpeed;
             graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
             graphics.SmoothingMode = SmoothingMode.None;
             break;
         case ConversionQuality.HighQuality:
             graphics.CompositingMode = CompositingMode.SourceCopy;
             graphics.CompositingQuality = CompositingQuality.HighQuality;
             graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
             graphics.SmoothingMode = SmoothingMode.AntiAlias;
             break;
     }
 }
        /// <summary>
        ///     Applies a resize operation to the input image with the desired size using
        ///     a specified conversion quality and conversion type.
        /// </summary>
        /// <param name="img"> Input image </param>
        /// <param name="size"> Output size </param>
        /// <param name="rType"> Resizing operation </param>
        /// <param name="quality"> Conversion quality </param>
        /// <param name="type"> Conversion type </param>
        public static Bitmap Resize(
            Bitmap img, Size size,
            ResizeType rType = ResizeType.Scaling,
            ConversionQuality quality = ConversionQuality.LowQuality,
            ConversionType type = ConversionType.Copy)
        {
            if (img.Size == size) return img;

            var scaled = new Bitmap(size.Width, size.Height, img.PixelFormat);
            using (var g = Graphics.FromImage(scaled))
            {
                SetConversionQuality(g, quality);
                switch (rType)
                {
                    case ResizeType.Scaling:
                        g.DrawImage(img, new Rectangle(0, 0, size.Width, size.Height));
                        break;
                    case ResizeType.Crop:
                        g.DrawImageUnscaledAndClipped(img,
                            new Rectangle(0, 0, size.Width, size.Height));
                        break;
                }
            }
            SetConversionType(ref img, scaled, type);
            return scaled;
        }
        /// <summary>
        /// Transcodes the source audio to the target format and quality.
        /// </summary>
        /// <param name="formatType">Format to convert this audio to.</param>
        /// <param name="quality">Quality of the processed output audio. For streaming formats, it can be one of the following: Low (96 kbps), Medium (128 kbps), Best (192 kbps).  For WAV formats, it can be one of the following: Low (11kHz ADPCM), Medium (22kHz ADPCM), Best (44kHz PCM)</param>
        /// <param name="targetFileName">Name of the file containing the processed source audio. Must be null for Wav and Adpcm. Must not be null for streaming compressed formats.</param>
        public void ConvertFormat(ConversionFormat formatType, ConversionQuality quality, string targetFileName)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("AudioContent");
            }


            switch (formatType)
            {
            case ConversionFormat.Adpcm:
#if WINDOWS
                ConvertWav(new AdpcmWaveFormat(QualityToSampleRate(quality), format.ChannelCount));
#else
                throw new NotSupportedException("Adpcm encoding supported on Windows only");
#endif
                break;

            case ConversionFormat.Pcm:
#if WINDOWS
                ConvertWav(new WaveFormat(QualityToSampleRate(quality), format.ChannelCount));
#elif LINUX
                // TODO Do the conversion for Linux platform
#else
                targetFileName = Guid.NewGuid().ToString() + ".wav";
                if (!ConvertAudio.Convert(fileName, targetFileName, AudioFormatType.LinearPCM, MonoMac.AudioToolbox.AudioFileType.WAVE, quality))
                {
                    throw new InvalidDataException("Failed to convert to PCM");
                }
                Read(targetFileName);
                if (File.Exists(targetFileName))
                {
                    File.Delete(targetFileName);
                }
#endif
                break;

            case ConversionFormat.WindowsMedia:
#if WINDOWS
                reader.Position = 0;
                MediaFoundationEncoder.EncodeToWma(reader, targetFileName, QualityToBitRate(quality));
                break;
#else
                throw new NotSupportedException("WindowsMedia encoding supported on Windows only");
#endif

            case ConversionFormat.Xma:
                throw new NotSupportedException("XMA is not a supported encoding format. It is specific to the Xbox 360.");

            case ConversionFormat.ImaAdpcm:
#if WINDOWS
                ConvertWav(new ImaAdpcmWaveFormat(QualityToSampleRate(quality), format.ChannelCount, 4));
#else
                throw new NotImplementedException("ImaAdpcm has not been implemented on this platform");
#endif
                break;

            case ConversionFormat.Aac:
#if WINDOWS
                reader.Position = 0;
                var mediaType = SelectMediaType(AudioSubtypes.MFAudioFormat_AAC, reader.WaveFormat, QualityToBitRate(quality));
                if (mediaType == null)
                {
                    throw new InvalidDataException("Cound not find a suitable mediaType to convert to.");
                }
                using (var encoder = new MediaFoundationEncoder(mediaType)) {
                    encoder.Encode(targetFileName, reader);
                }
#elif LINUX
                // TODO: Code for Linux convertion
#else
                if (!ConvertAudio.Convert(fileName, targetFileName, AudioFormatType.MPEG4AAC, MonoMac.AudioToolbox.AudioFileType.MPEG4, quality))
                {
                    throw new InvalidDataException("Failed to convert to AAC");
                }
#endif
                break;

            case ConversionFormat.Vorbis:
                throw new NotImplementedException("Vorbis is not yet implemented as an encoding format.");
            }
        }
Exemple #24
0
        /// <summary>
        /// Transcodes the source audio to the target format and quality.
        /// </summary>
        /// <param name="formatType">Format to convert this audio to.</param>
        /// <param name="quality">Quality of the processed output audio. For streaming formats, it can be one of the following: Low (96 kbps), Medium (128 kbps), Best (192 kbps).  For WAV formats, it can be one of the following: Low (11kHz ADPCM), Medium (22kHz ADPCM), Best (44kHz PCM)</param>
        /// <param name="saveToFile">
        /// The name of the file that the converted audio should be saved into.  This is used for SongContent, where
        /// the audio is stored external to the XNB file.  If this is null, then the converted audio is stored in
        /// the Data property.
        /// </param>
        public void ConvertFormat(ConversionFormat formatType, ConversionQuality quality, string saveToFile)
        {
            if (disposed)
                throw new ObjectDisposedException("AudioContent");

            var temporarySource = Path.GetTempFileName();
            var temporaryOutput = Path.GetTempFileName();
            try
            {
                using (var fs = new FileStream(temporarySource, FileMode.Create, FileAccess.Write))
                {
                    var dataBytes = this.data.ToArray();
                    fs.Write(dataBytes, 0, dataBytes.Length);
                }

                string ffmpegCodecName, ffmpegMuxerName;
                int format;
                switch (formatType)
                {
                    case ConversionFormat.Adpcm:
                        // ADPCM Microsoft 
                        ffmpegCodecName = "adpcm_ms";
                        ffmpegMuxerName = "wav";
                        format = 0x0002; /* WAVE_FORMAT_ADPCM */
                        break;
                    case ConversionFormat.Pcm:
                        // PCM signed 16-bit little-endian
                        ffmpegCodecName = "pcm_s16le";
                        ffmpegMuxerName = "s16le";
                        format = 0x0001; /* WAVE_FORMAT_PCM */
                        break;
                    case ConversionFormat.WindowsMedia:
                        // Windows Media Audio 2
                        ffmpegCodecName = "wmav2";
                        ffmpegMuxerName = "asf";
                        format = 0x0161; /* WAVE_FORMAT_WMAUDIO2 */
                        break;
                    case ConversionFormat.Xma:
                        throw new NotSupportedException(
                            "XMA is not a supported encoding format. It is specific to the Xbox 360.");
                    case ConversionFormat.ImaAdpcm:
                        // ADPCM IMA WAV
                        ffmpegCodecName = "adpcm_ima_wav";
                        ffmpegMuxerName = "wav";
                        format = 0x0011; /* WAVE_FORMAT_IMA_ADPCM */
                        break;
                    case ConversionFormat.Aac:
                        // AAC (Advanced Audio Coding)
                        // Requires -strict experimental
                        ffmpegCodecName = "aac";
                        ffmpegMuxerName = "ipod";
                        format = 0x0000; /* WAVE_FORMAT_UNKNOWN */
                        break;
                    case ConversionFormat.Vorbis:
                        // Vorbis
                        ffmpegCodecName = "libvorbis";
                        ffmpegMuxerName = "ogg";
                        format = 0x0000; /* WAVE_FORMAT_UNKNOWN */
                        break;
                    default:
                        // Unknown format
                        throw new NotSupportedException();
                }

                string ffmpegStdout, ffmpegStderr;
                var ffmpegExitCode = ExternalTool.Run(
                    "ffmpeg",
                    string.Format(
                        "-y -i \"{0}\" -vn -c:a {1} -b:a {2} -f:a {3} -strict experimental \"{4}\"",
                        temporarySource,
                        ffmpegCodecName,
                        QualityToBitRate(quality),
                        ffmpegMuxerName,
                        temporaryOutput),
                    out ffmpegStdout,
                    out ffmpegStderr);
                if (ffmpegExitCode != 0)
                {
                    throw new InvalidOperationException("ffmpeg exited with non-zero exit code: \n" + ffmpegStdout + "\n" + ffmpegStderr);
                }

                byte[] rawData;
                using (var fs = new FileStream(temporaryOutput, FileMode.Open, FileAccess.Read))
                {
                    rawData = new byte[fs.Length];
                    fs.Read(rawData, 0, rawData.Length);
                }

                if (saveToFile != null)
                {
                    using (var fs = new FileStream(saveToFile, FileMode.Create, FileAccess.Write))
                    {
                        fs.Write(rawData, 0, rawData.Length);
                    }

                    this.data = null;
                }
                else
                {
                    this.data = rawData.ToList();
                }

                string ffprobeStdout, ffprobeStderr;
                var ffprobeExitCode = ExternalTool.Run(
                    "ffprobe",
                    string.Format("-i \"{0}\" -show_entries streams -v quiet -of flat", temporarySource),
                    out ffprobeStdout,
                    out ffprobeStderr);
                if (ffprobeExitCode != 0)
                {
                    throw new InvalidOperationException("ffprobe exited with non-zero exit code.");
                }

                // Set default values if information is not available.
                int averageBytesPerSecond = 0;
                int bitsPerSample = 0;
                int blockAlign = 0;
                int channelCount = 0;
                int sampleRate = 0;
                double durationInSeconds = 0;

                var numberFormat = System.Globalization.CultureInfo.InvariantCulture.NumberFormat;
                foreach (var line in ffprobeStdout.Split(new[] { '\r', '\n', '\0' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    var kv = line.Split(new[] { '=' }, 2);

                    switch (kv[0])
                    {
                        case "streams.stream.0.sample_rate":
                            sampleRate = int.Parse(kv[1].Trim('"'), numberFormat);
                            break;
                        case "streams.stream.0.bits_per_sample":
                            bitsPerSample = int.Parse(kv[1].Trim('"'), numberFormat);
                            break;
                        case "streams.stream.0.duration":
                            durationInSeconds = double.Parse(kv[1].Trim('"'), numberFormat);
                            break;
                        case "streams.stream.0.channels":
                            channelCount = int.Parse(kv[1].Trim('"'), numberFormat);
                            break;
                    }
                }

                // This information is not available from ffprobe (and may or may not
                // be relevant for non-PCM formats anyway):
                //
                // * averageBytesPerSecond
                // * blockAlign

                this.duration = TimeSpan.FromSeconds(durationInSeconds);
                this.format = new AudioFormat(
                    averageBytesPerSecond,
                    bitsPerSample,
                    blockAlign,
                    channelCount,
                    format,
                    sampleRate);
            }
            finally
            {
                File.Delete(temporarySource);
                File.Delete(temporaryOutput);
            }
        }
Exemple #25
0
        /// <summary>
        /// Returns the sample rate for the given quality setting.
        /// </summary>
        /// <param name="quality">The quality setting.</param>
        /// <returns>The sample rate for the quality.</returns>
        int QualityToSampleRate(ConversionQuality quality)
        {
            switch (quality)
            {
                case ConversionQuality.Low:
                    return Math.Max(8000, format.SampleRate / 2);
            }

            return Math.Max(8000, format.SampleRate);
        }
Exemple #26
0
 public void ConvertFormat(ConversionFormat formatType, ConversionQuality quality, string saveToFile)
 {
     // Call the legacy conversion code.
     DefaultAudioProfile.ConvertToFormat(this, formatType, quality, saveToFile);
 }
Exemple #27
0
        /// <summary>
        /// Transcodes the source audio to the target format and quality.
        /// </summary>
        /// <param name="formatType">Format to convert this audio to.</param>
        /// <param name="quality">Quality of the processed output audio. For streaming formats, it can be one of the following: Low (96 kbps), Medium (128 kbps), Best (192 kbps).  For WAV formats, it can be one of the following: Low (11kHz ADPCM), Medium (22kHz ADPCM), Best (44kHz PCM)</param>
        /// <param name="saveToFile">
        /// The name of the file that the converted audio should be saved into.  This is used for SongContent, where
        /// the audio is stored external to the XNB file.  If this is null, then the converted audio is stored in
        /// the Data property.
        /// </param>
        public void ConvertFormat(ConversionFormat formatType, ConversionQuality quality, string saveToFile)
        {
            var temporarySource = Path.GetTempFileName();
            var temporaryOutput = Path.GetTempFileName();
            try
            {
                using (var fs = new FileStream(temporarySource, FileMode.Create, FileAccess.Write))
                {
                    var dataBytes = this.data.ToArray();
                    fs.Write(dataBytes, 0, dataBytes.Length);
                }

                string ffmpegCodecName, ffmpegMuxerName;
                int format;
                switch (formatType)
                {
                    case ConversionFormat.Adpcm:
                        // ADPCM Microsoft
                        ffmpegCodecName = "adpcm_ms";
                        ffmpegMuxerName = "wav";
                        format = 0x0002; /* WAVE_FORMAT_ADPCM */
                        break;
                    case ConversionFormat.Pcm:
                        // PCM signed 16-bit little-endian
                        ffmpegCodecName = "pcm_s16le";
                        ffmpegMuxerName = "wav";
                        format = 0x0001; /* WAVE_FORMAT_PCM */
                        break;
                    case ConversionFormat.WindowsMedia:
                        // Windows Media Audio 2
                        ffmpegCodecName = "wmav2";
                        ffmpegMuxerName = "asf";
                        format = 0x0161; /* WAVE_FORMAT_WMAUDIO2 */
                        break;
                    case ConversionFormat.Xma:
                        throw new NotSupportedException(
                            "XMA is not a supported encoding format. It is specific to the Xbox 360.");
                    case ConversionFormat.ImaAdpcm:
                        // ADPCM IMA WAV
                        ffmpegCodecName = "adpcm_ima_wav";
                        ffmpegMuxerName = "wav";
                        format = 0x0011; /* WAVE_FORMAT_IMA_ADPCM */
                        break;
                    case ConversionFormat.Aac:
                        // AAC (Advanced Audio Coding)
                        // Requires -strict experimental
                        ffmpegCodecName = "aac";
                        ffmpegMuxerName = "ipod";
                        format = 0x0000; /* WAVE_FORMAT_UNKNOWN */
                        break;
                    case ConversionFormat.Vorbis:
                        // Vorbis
                        ffmpegCodecName = "libvorbis";
                        ffmpegMuxerName = "ogg";
                        format = 0x0000; /* WAVE_FORMAT_UNKNOWN */
                        break;
                    default:
                        // Unknown format
                        throw new NotSupportedException();
                }

                string ffmpegStdout, ffmpegStderr;
                var ffmpegExitCode = ExternalTool.Run(
                    "ffmpeg",
                    string.Format(
                        "-y -i \"{0}\" -vn -c:a {1} -b:a {2} -f:a {3} -strict experimental \"{4}\"",
                        temporarySource,
                        ffmpegCodecName,
                        QualityToBitRate(quality),
                        ffmpegMuxerName,
                        temporaryOutput),
                    out ffmpegStdout,
                    out ffmpegStderr);
                if (ffmpegExitCode != 0)
                {
                    throw new InvalidOperationException("ffmpeg exited with non-zero exit code: \n" + ffmpegStdout + "\n" + ffmpegStderr);
                }

                byte[] rawData;
                using (var fs = new FileStream(temporaryOutput, FileMode.Open, FileAccess.Read))
                {
                    rawData = new byte[fs.Length];
                    fs.Read(rawData, 0, rawData.Length);
                }

                if (saveToFile != null)
                {
                    using (var fs = new FileStream(saveToFile, FileMode.Create, FileAccess.Write))
                    {
                        fs.Write(rawData, 0, rawData.Length);
                    }

                    this.data = null;
                }
                else
                {
                    this.data = rawData.ToList();
                }

                // Get the audio metadata from the output file
                string ffprobeStdout, ffprobeStderr;
                var ffprobeExitCode = ExternalTool.Run(
                    "ffprobe",
                    string.Format("-i \"{0}\" -show_entries streams -v quiet -of flat", temporaryOutput),
                    out ffprobeStdout,
                    out ffprobeStderr);
                if (ffprobeExitCode != 0)
                {
                    throw new InvalidOperationException("ffprobe exited with non-zero exit code.");
                }

                // Set default values if information is not available.
                int averageBytesPerSecond = 0;
                int bitsPerSample = 0;
                int blockAlign = 0;
                int channelCount = 0;
                int sampleRate = 0;
                double durationInSeconds = 0;

                var numberFormat = System.Globalization.CultureInfo.InvariantCulture.NumberFormat;
                foreach (var line in ffprobeStdout.Split(new[] { '\r', '\n', '\0' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    var kv = line.Split(new[] { '=' }, 2);

                    switch (kv[0])
                    {
                        case "streams.stream.0.sample_rate":
                            sampleRate = int.Parse(kv[1].Trim('"'), numberFormat);
                            break;
                        case "streams.stream.0.bits_per_sample":
                            bitsPerSample = int.Parse(kv[1].Trim('"'), numberFormat);
                            break;
                        case "streams.stream.0.duration":
                            durationInSeconds = double.Parse(kv[1].Trim('"'), numberFormat);
                            break;
                        case "streams.stream.0.channels":
                            channelCount = int.Parse(kv[1].Trim('"'), numberFormat);
                            break;
                        case "streams.stream.0.bit_rate":
                            averageBytesPerSecond = (int.Parse(kv[1].Trim('"'), numberFormat) / 8);
                            break;
                    }
                }

                // Calculate blockAlign.
                switch (formatType)
                {
                    case ConversionFormat.Adpcm:
                    case ConversionFormat.ImaAdpcm:
                    case ConversionFormat.Pcm:
                        // Block alignment value is the number of bytes in an atomic unit (that is, a block) of audio for a particular format. For Pulse Code Modulation (PCM) formats, the formula for calculating block alignment is as follows:
                        //  •   Block Alignment = Bytes per Sample x Number of Channels
                        // For example, the block alignment value for 16-bit PCM format mono audio is 2 (2 bytes per sample x 1 channel). For 16-bit PCM format stereo audio, the block alignment value is 4.
                        // https://msdn.microsoft.com/en-us/library/system.speech.audioformat.speechaudioformatinfo.blockalign(v=vs.110).aspx
                        // Get the raw PCM from the output WAV file
                        using (var reader = new BinaryReader(new MemoryStream(rawData)))
                        {
                            data = GetRawWavData(reader, ref blockAlign).ToList();
                        }
                        break;
                    default:
                        // blockAlign is not available from ffprobe (and may or may not
                        // be relevant for non-PCM formats anyway)
                        break;
                }

                this.duration = TimeSpan.FromSeconds(durationInSeconds);
                this.format = new AudioFormat(
                    averageBytesPerSecond,
                    bitsPerSample,
                    blockAlign,
                    channelCount,
                    format,
                    sampleRate);

                // Loop start and length in number of samples. Defaults to entire sound
                loopStart = 0;
                if (data != null && bitsPerSample > 0 && channelCount > 0)
                    loopLength = data.Count / ((bitsPerSample / 8) * channelCount);
                else
                    loopLength = 0;
            }
            finally
            {
                File.Delete(temporarySource);
                File.Delete(temporaryOutput);
            }
        }
Exemple #28
0
        /// <summary>
        /// Transcodes the source audio to the target format and quality.
        /// </summary>
        /// <param name="formatType">Format to convert this audio to.</param>
        /// <param name="quality">Quality of the processed output audio. For streaming formats, it can be one of the following: Low (96 kbps), Medium (128 kbps), Best (192 kbps).  For WAV formats, it can be one of the following: Low (11kHz ADPCM), Medium (22kHz ADPCM), Best (44kHz PCM)</param>
        /// <param name="targetFileName">Name of the file containing the processed source audio. Must be null for Wav and Adpcm. Must not be null for streaming compressed formats.</param>
        public void ConvertFormat(ConversionFormat formatType, ConversionQuality quality, string targetFileName)
        {
            if (disposed)
                throw new ObjectDisposedException("AudioContent");

            switch (formatType)
            {
                case ConversionFormat.Adpcm:
                    ConvertWav(new AdpcmWaveFormat(QualityToSampleRate(quality), format.ChannelCount));
                    break;

                case ConversionFormat.Pcm:
                    ConvertWav(new WaveFormat(QualityToSampleRate(quality), format.ChannelCount));
                    break;

                case ConversionFormat.WindowsMedia:
#if WINDOWS
                    reader.Position = 0;
                    MediaFoundationEncoder.EncodeToWma(reader, targetFileName, QualityToBitRate(quality));
                    break;
#else
                    throw new NotSupportedException("WindowsMedia encoding supported on Windows only");
#endif

                case ConversionFormat.Xma:
                    throw new NotSupportedException("XMA is not a supported encoding format. It is specific to the Xbox 360.");

                case ConversionFormat.ImaAdpcm:
                    ConvertWav(new ImaAdpcmWaveFormat(QualityToSampleRate(quality), format.ChannelCount, 4));
                    break;

                case ConversionFormat.Aac:
#if WINDOWS
                    reader.Position = 0;
                    MediaFoundationEncoder.EncodeToAac(reader, targetFileName, QualityToBitRate(quality));
                    break;
#else
                    throw new NotImplementedException();
#endif

                case ConversionFormat.Vorbis:
                    throw new NotImplementedException("Vorbis is not yet implemented as an encoding format.");
            }
        }
Exemple #29
0
 /// <summary>
 /// Converts the audio content to work on targeted platform.
 /// </summary>
 /// <param name="platform">The platform to build the audio content for.</param>
 /// <param name="quality">The suggested audio quality level.</param>
 /// <param name="content">The audio content to convert.</param>
 /// <returns>The quality used for conversion which could be different from the suggested quality.</returns>
 public abstract ConversionQuality ConvertAudio(
     TargetPlatform platform,
     ConversionQuality quality,
     AudioContent content);
Exemple #30
0
 /// <summary>
 /// Converts the audio content to a streaming format that works on targeted platform.
 /// </summary>
 /// <param name="platform">The platform to build the audio content for.</param>
 /// <param name="quality">The suggested audio quality level.</param>
 /// <param name="content">he audio content to convert.</param>
 /// <param name="inputFile">The input file name. This may change varying on platform and profile.</param>
 /// <param name="destinationFile">The output file name, changed by platform and profile.</param>
 /// <returns>The quality used for conversion which could be different from the suggested quality.</returns>
 public abstract ConversionQuality ConvertStreamingAudio(
     TargetPlatform platform,
     ConversionQuality quality,
     AudioContent content,
     string inputFile,
     out string destinationFile);
        public override ConversionQuality ConvertStreamingAudio(TargetPlatform platform, ConversionQuality quality, AudioContent content, ref string outputFileName)
        {
            // Most platforms will use AAC ("mp4") by default
            var targetFormat = ConversionFormat.Aac;

            if (platform == TargetPlatform.Windows ||
                platform == TargetPlatform.WindowsPhone8 ||
                platform == TargetPlatform.WindowsStoreApp)
            {
                targetFormat = ConversionFormat.WindowsMedia;
            }

            else if (platform == TargetPlatform.DesktopGL)
            {
                targetFormat = ConversionFormat.Vorbis;
            }

            // Get the song output path with the target format extension.
            outputFileName = Path.ChangeExtension(outputFileName, AudioHelper.GetExtension(targetFormat));

            // Make sure the output folder for the file exists.
            Directory.CreateDirectory(Path.GetDirectoryName(outputFileName));

            return(ConvertToFormat(content, targetFormat, quality, outputFileName));
        }
Exemple #32
0
 /// <summary>
 /// Converts the audio content to a streaming format that works on targeted platform.
 /// </summary>
 /// <param name="platform">The platform to build the audio content for.</param>
 /// <param name="quality">The suggested audio quality level.</param>
 /// <param name="content">he audio content to convert.</param>
 /// <param name="outputFileName"></param>
 /// <returns>The quality used for conversion which could be different from the suggested quality.</returns>
 public abstract ConversionQuality ConvertStreamingAudio(TargetPlatform platform, ConversionQuality quality, AudioContent content, ref string outputFileName);