コード例 #1
0
ファイル: Program.cs プロジェクト: PikminGuts92/BFForever
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: audio.clt converted_audio.wav");
                return;
            }

            string outPath = (args.Length > 1)
                ? args[1]
                : Path.Combine(Path.GetDirectoryName(args[0]), $"{Path.GetFileNameWithoutExtension(args[0])}.wav");

            try
            {
                Celt celt = Celt.FromFile(args[0]);
                celt.WriteToWavFile(outPath);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
                return;
            }

            Console.WriteLine("Successfully wrote output wav file to {0}", outPath);
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: maxton/BFForever
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("Usage: audio.clt converted_audio.wav");
                return;
            }

            try
            {
                Celt celt = Celt.FromFile(args[0]);
                celt.WriteToWavFile(args[1]);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
                return;
            }

            Console.WriteLine("Successfully wrote output wav file to {0}", args[1]);
        }
コード例 #3
0
        static void AudioEncoder(AudioEncoderOptions options)
        {
            bool IsCeltFile(string path)
            {
                string ext = Path.GetExtension(path);

                return(ext.Equals(".clt", StringComparison.CurrentCultureIgnoreCase));
            }

            // Imports audio file
            Celt celt = IsCeltFile(options.InputPath) ? Celt.FromFile(options.InputPath) : Celt.FromAudio(options.InputPath);

            Console.WriteLine($"Opened {options.InputPath}");

            string o = options.OutputPath;

            // Exports audio file
            if (IsCeltFile(o))
            {
                celt.Export(o);
            }
            else
            {
                o = Path.Combine(Path.GetDirectoryName(o), Path.GetFileNameWithoutExtension(o)) + ".wav";

                // Creates directory if it doesn't exist
                if (!Directory.Exists(Path.GetDirectoryName(o)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(o));
                }

                celt.WriteToWavFile(o);
            }

            Console.WriteLine($"Saved {o}");
        }
コード例 #4
0
            protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                var assetManager = new ContentManager();

                // Get absolute path of asset source on disk
                var assetDirectory = Parameters.Source.GetParent();
                var assetSource    = UPath.Combine(assetDirectory, Parameters.Source);

                var installationDir = DirectoryHelper.GetPackageDirectory("Xenko");
                var binDir          = UPath.Combine(installationDir, new UDirectory("Bin"));

                binDir = UPath.Combine(binDir, new UDirectory("Windows"));
                var ffmpeg = UPath.Combine(binDir, new UFile("ffmpeg.exe"));

                if (!File.Exists(ffmpeg))
                {
                    throw new AssetException("Failed to compile a sound asset, ffmpeg was not found.");
                }

                var channels    = Parameters.Spatialized ? 1 : 2;
                var tempPcmFile = Path.GetTempFileName();
                var ret         = RunProcessAndGetOutput(ffmpeg, $"-i \"{assetSource}\" -f f32le -acodec pcm_f32le -ac {channels} -ar {Parameters.SampleRate} -y \"{tempPcmFile}\"");

                if (ret != 0)
                {
                    File.Delete(tempPcmFile);
                    throw new AssetException($"Failed to compile a sound asset, ffmpeg failed to convert {assetSource}");
                }

                var encoder = new Celt(Parameters.SampleRate, CompressedSoundSource.SamplesPerFrame, channels, false);

                var uncompressed = CompressedSoundSource.SamplesPerFrame * channels * sizeof(short); //compare with int16 for CD quality comparison.. but remember we are dealing with 32 bit floats for encoding!!
                var target       = (int)Math.Floor(uncompressed / (float)Parameters.CompressionRatio);

                var dataUrl  = Url + "_Data";
                var newSound = new Sound
                {
                    CompressedDataUrl = dataUrl,
                    Channels          = channels,
                    SampleRate        = Parameters.SampleRate,
                    StreamFromDisk    = Parameters.StreamFromDisk,
                    Spatialized       = Parameters.Spatialized,
                };

                //make sure we don't compress celt data
                commandContext.AddTag(new ObjectUrl(UrlType.ContentLink, dataUrl), disableCompressionSymbol);

                var frameSize = CompressedSoundSource.SamplesPerFrame * channels;

                using (var reader = new BinaryReader(new FileStream(tempPcmFile, FileMode.Open, FileAccess.Read)))
                    using (var outputStream = ContentManager.FileProvider.OpenStream(dataUrl, VirtualFileMode.Create, VirtualFileAccess.Write, VirtualFileShare.Read, StreamFlags.Seekable))
                    {
                        var writer = new BinarySerializationWriter(outputStream);

                        var outputBuffer = new byte[target];
                        var buffer       = new float[frameSize];
                        var count        = 0;
                        var length       = reader.BaseStream.Length; // Cache the length, because this getter is expensive to use
                        for (var position = 0; position < length; position += sizeof(float))
                        {
                            if (count == frameSize) //flush
                            {
                                var len = encoder.Encode(buffer, outputBuffer);
                                writer.Write((short)len);
                                outputStream.Write(outputBuffer, 0, len);

                                count = 0;
                                Array.Clear(buffer, 0, frameSize);

                                newSound.NumberOfPackets++;
                                newSound.MaxPacketLength = Math.Max(newSound.MaxPacketLength, len);
                            }

                            buffer[count] = reader.ReadSingle();
                            count++;
                        }

                        if (count > 0) //flush
                        {
                            var len = encoder.Encode(buffer, outputBuffer);
                            writer.Write((short)len);
                            outputStream.Write(outputBuffer, 0, len);

                            newSound.NumberOfPackets++;
                            newSound.MaxPacketLength = Math.Max(newSound.MaxPacketLength, len);
                        }
                    }

                File.Delete(tempPcmFile);

                assetManager.Save(Url, newSound);

                return(Task.FromResult(ResultStatus.Successful));
            }
コード例 #5
0
ファイル: SoundAssetCompiler.cs プロジェクト: glepag1/stride
            /// <inheritdoc />
            protected override async Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                // Get path to ffmpeg
                var ffmpeg = ToolLocator.LocateTool("ffmpeg.exe")?.ToWindowsPath() ?? throw new AssetException("Failed to compile a sound asset, ffmpeg was not found.");

                // Get absolute path of asset source on disk
                var assetDirectory = Parameters.Source.GetParent();
                var assetSource    = UPath.Combine(assetDirectory, Parameters.Source);

                // Execute ffmpeg to convert source to PCM and then encode with Celt
                var tempFile = Path.GetTempFileName();

                try
                {
                    var channels    = Parameters.Spatialized ? 1 : 2;
                    var commandLine = "  -hide_banner -loglevel error" +                                          // hide most log output
                                      $" -i \"{assetSource.ToWindowsPath()}\"" +                                  // input file
                                      $" -f f32le -acodec pcm_f32le -ac {channels} -ar {Parameters.SampleRate}" + // codec
                                      $" -map 0:{Parameters.Index}" +                                             // stream index
                                      $" -y \"{tempFile}\"";                                                      // output file (always overwrite)
                    var ret = await ShellHelper.RunProcessAndGetOutputAsync(ffmpeg, commandLine, commandContext.Logger);

                    if (ret != 0 || commandContext.Logger.HasErrors)
                    {
                        throw new AssetException($"Failed to compile a sound asset, ffmpeg failed to convert {assetSource}");
                    }

                    var encoder = new Celt(Parameters.SampleRate, CompressedSoundSource.SamplesPerFrame, channels, false);

                    var uncompressed = CompressedSoundSource.SamplesPerFrame * channels * sizeof(short); //compare with int16 for CD quality comparison.. but remember we are dealing with 32 bit floats for encoding!!
                    var target       = (int)Math.Floor(uncompressed / (float)Parameters.CompressionRatio);

                    var dataUrl  = Url + "_Data";
                    var newSound = new Sound
                    {
                        CompressedDataUrl = dataUrl,
                        Channels          = channels,
                        SampleRate        = Parameters.SampleRate,
                        StreamFromDisk    = Parameters.StreamFromDisk,
                        Spatialized       = Parameters.Spatialized,
                    };

                    //make sure we don't compress celt data
                    commandContext.AddTag(new ObjectUrl(UrlType.Content, dataUrl), Builder.DoNotCompressTag);

                    var delay = encoder.GetDecoderSampleDelay();

                    var frameSize = CompressedSoundSource.SamplesPerFrame * channels;
                    using (var reader = new BinaryReader(new FileStream(tempFile, FileMode.Open, FileAccess.Read)))
                        using (var outputStream = MicrothreadLocalDatabases.DatabaseFileProvider.OpenStream(dataUrl, VirtualFileMode.Create, VirtualFileAccess.Write, VirtualFileShare.Read, StreamFlags.Seekable))
                        {
                            var writer = new BinarySerializationWriter(outputStream);

                            var outputBuffer = new byte[target];
                            var buffer       = new float[frameSize];
                            var count        = 0;
                            var padding      = sizeof(float) * channels * delay;
                            var length       = reader.BaseStream.Length; // Cache the length, because this getter is expensive to use
                            for (var position = 0; position < length + padding; position += sizeof(float))
                            {
                                if (count == frameSize) //flush
                                {
                                    var len = encoder.Encode(buffer, outputBuffer);
                                    writer.Write((short)len);
                                    outputStream.Write(outputBuffer, 0, len);

                                    newSound.Samples += count / channels;
                                    newSound.NumberOfPackets++;
                                    newSound.MaxPacketLength = Math.Max(newSound.MaxPacketLength, len);

                                    count = 0;
                                    Array.Clear(buffer, 0, frameSize);
                                }

                                // Pad with 0 once we reach end of stream (this is needed because of encoding delay)
                                buffer[count++] = (position < length)
                                    ? reader.ReadSingle()
                                    : 0.0f;
                            }

                            if (count > 0) //flush
                            {
                                var len = encoder.Encode(buffer, outputBuffer);
                                writer.Write((short)len);
                                outputStream.Write(outputBuffer, 0, len);

                                newSound.Samples += count / channels;
                                newSound.NumberOfPackets++;
                                newSound.MaxPacketLength = Math.Max(newSound.MaxPacketLength, len);
                            }
                        }

                    // Samples is the real sound sample count, remove the delay at the end
                    newSound.Samples -= delay;

                    var assetManager = new ContentManager(MicrothreadLocalDatabases.ProviderService);
                    assetManager.Save(Url, newSound);

                    return(ResultStatus.Successful);
                }
                finally
                {
                    File.Delete(tempFile);
                }
            }
コード例 #6
0
        private void EncodeAudio(FusedSong song)
        {
            string mapPath = GetFilePath("hashes.json");

            // Imports existing mappings if found
            AudioHashMappings audioMap = File.Exists(mapPath)
                ? AudioHashMappings.Import(mapPath)
                : new AudioHashMappings();

            string GetPackageFilePath(string relativePath) =>
            Path.Combine(_packageManager.CurrentPackageDirectory + "\\songs\\", song.Identifier.Replace(".", "\\") + "\\" + relativePath);

            bool IsCeltFile(string path)
            {
                string ext = Path.GetExtension(path);

                return(ext.Equals(".clt", StringComparison.CurrentCultureIgnoreCase));
            }

            HashMapping EncodeAudio(string input, string output, HashMapping oldMap)
            {
                if (!File.Exists(input))
                {
                    // Delete if no input
                    if (File.Exists(output))
                    {
                        File.Delete(output);
                    }

                    return(oldMap);
                }
                else if (!File.Exists(output))
                {
                    // Encodes audio (Import from celt supported)
                    Celt celt = IsCeltFile(input) ? Celt.FromFile(input) : Celt.FromAudio(input);
                    celt.Export(output);

                    // Updates hashes
                    return(HashMapping.CreateMapping(input, output));
                }

                HashMapping newMap = HashMapping.CreateMapping(input, output);

                if (newMap.Input != oldMap.Input || newMap.Output != oldMap.Output)
                {
                    // Encodes audio
                    Celt celt = IsCeltFile(input) ? Celt.FromFile(input) : Celt.FromAudio(input);
                    celt.Export(output);

                    // Updates output hash
                    newMap.Output = HashMapping.ComputeHashFromFile(output);
                }
                // Else means they're equal, no need to re-encode

                // Returns new hashes
                return(newMap);
            }

            audioMap.Preview      = EncodeAudio(GetFilePath(song.AudioPaths.Preview), GetPackageFilePath("preview\\audio.clt"), audioMap.Preview);
            audioMap.Backing      = EncodeAudio(GetFilePath(song.AudioPaths.Backing), GetPackageFilePath("gamestems\\back\\audio.clt"), audioMap.Backing);
            audioMap.Bass         = EncodeAudio(GetFilePath(song.AudioPaths.Bass), GetPackageFilePath("gamestems\\bass\\audio.clt"), audioMap.Bass);
            audioMap.Drums        = EncodeAudio(GetFilePath(song.AudioPaths.Drums), GetPackageFilePath("gamestems\\drums\\audio.clt"), audioMap.Drums);
            audioMap.LeadGuitar   = EncodeAudio(GetFilePath(song.AudioPaths.LeadGuitar), GetPackageFilePath("gamestems\\gtr1\\audio.clt"), audioMap.LeadGuitar);
            audioMap.RhythmGuitar = EncodeAudio(GetFilePath(song.AudioPaths.RhythmGuitar), GetPackageFilePath("gamestems\\gtr2\\audio.clt"), audioMap.RhythmGuitar);
            audioMap.Vox          = EncodeAudio(GetFilePath(song.AudioPaths.Vox), GetPackageFilePath("gamestems\\vox\\audio.clt"), audioMap.Vox);

            audioMap.Export(mapPath);
        }