Пример #1
0
        /// <summary>
        /// Converts a file to WAV using SoX and reads it into an LWAV object.
        /// If the format is not supported, SoX will write a message to the console and this function will throw an AudioImporterException.
        /// </summary>
        /// <param name="filename">The path of the file to read</param>
        /// <returns>A non-looping LWAV</returns>
        public PCM16Audio ReadFile(string filename)
        {
            if (!File.Exists(ExePath))
            {
                throw new AudioImporterException("test.exe not found at path: " + ExePath);
            }
            if (filename.Contains('"'))
            {
                throw new AudioImporterException("File paths with double quote marks (\") are not supported");
            }

            string outfile = TempFiles.Create("wav");

            ProcessStartInfo psi = new ProcessStartInfo {
                FileName        = ExePath,
                UseShellExecute = false,
                CreateNoWindow  = true,
                Arguments       = "\"" + filename + "\" -b 16 -t wav " + outfile
            };
            Process p = Process.Start(psi);

            p.WaitForExit();

            try {
                PCM16Audio lwav = PCM16Factory.FromFile(outfile, true);
                return(lwav);
            } catch (Exception e) {
                throw new AudioImporterException("Could not read SoX output: " + e.Message);
            }
        }
Пример #2
0
        /// <summary>
        /// Converts a file to WAV using test.exe and reads it into a PCM16Audio object.
        /// If the format is not supported, test.exe will write a message to the console and this function will throw an AudioImporterException.
        /// </summary>
        /// <param name="filename">The path of the file to read</param>
        /// <returns>A PCM16Audio, which may or may not be looping</returns>
        public async Task <PCM16Audio> ReadFileAsync(string filename)
        {
            if (!File.Exists(TestExePath))
            {
                throw new AudioImporterException("test.exe not found at path: " + TestExePath);
            }
            if (filename.Contains('"'))
            {
                throw new AudioImporterException("File paths with double quote marks (\") are not supported");
            }

            if (!Directory.Exists("tmp"))
            {
                Directory.CreateDirectory("tmp");
            }

            ProcessStartInfo psi = new ProcessStartInfo {
                WorkingDirectory = "tmp",
                FileName         = TestExePath,
                UseShellExecute  = false,
                CreateNoWindow   = true,
                Arguments        = "-L -l 1 -f 0 -o dump.wav \"" + filename + "\""
            };
            var pr = await ProcessEx.RunAsync(psi);

            try {
                PCM16Audio lwav = PCM16Factory.FromFile("tmp/dump.wav", true);
                return(lwav);
            } catch (Exception e) {
                throw new AudioImporterException("Could not read output of test.exe: " + e.Message);
            }
        }
Пример #3
0
        public async Task <PCM16Audio> ReadFileAsync(string filename)
        {
            if (!File.Exists(ExePath))
            {
                throw new AudioImporterException("faad not found at path: " + ExePath);
            }
            if (filename.Contains('"'))
            {
                throw new AudioImporterException("File paths with double quote marks (\") are not supported");
            }

            string outfile = TempFiles.Create("wav");

            ProcessStartInfo psi = new ProcessStartInfo {
                FileName        = ExePath,
                UseShellExecute = false,
                CreateNoWindow  = true,
                Arguments       = "-o " + outfile + " \"" + filename + "\""
            };
            var pr = await ProcessEx.RunAsync(psi);

            try {
                return(PCM16Factory.FromFile(outfile, true));
            } catch (PCM16FactoryException e) {
                throw new AudioImporterException("Could not read faad output: " + e.Message);
            }
        }
Пример #4
0
 public Task <PCM16Audio> ReadFileAsync(string filename)
 {
     try {
         return(Task.FromResult(PCM16Factory.FromByteArray(File.ReadAllBytes(filename))));
     } catch (PCM16FactoryException e) {
         throw new AudioImporterException(e.Message, e);
     }
 }
Пример #5
0
 public PCM16Audio ReadFile(string filename)
 {
     try {
         return(PCM16Factory.FromByteArray(File.ReadAllBytes(filename)));
     } catch (PCM16FactoryException e) {
         throw new AudioImporterException(e.Message, e);
     }
 }
Пример #6
0
        private PCM16Audio ReadFile_vgm2wav(string filename)
        {
            string           outfile = TempFiles.Create("wav");
            ProcessStartInfo psi     = new ProcessStartInfo {
                FileName        = ExePath,
                UseShellExecute = false,
                CreateNoWindow  = true,
                Arguments       = "--loop-count 1 --fade-ms 500 \"" + filename + "\" " + outfile
            };
            Process p = Process.Start(psi);

            p.WaitForExit();
            try {
                return(PCM16Factory.FromFile(outfile, true));
            } catch (Exception e) {
                throw new AudioImporterException("Could not read output of vgm2wav: " + e.Message);
            }
        }
Пример #7
0
        public async Task <PCM16Audio> ReadFileAsync(string filename)
        {
            if (filename.Contains('"'))
            {
                throw new AudioImporterException("File paths with double quote marks (\") are not supported");
            }

            byte[] data = File.ReadAllBytes(filename);
            if (data.Length == 0)
            {
                throw new AudioImporterException("Empty input file");
            }

            try {
                await Task.Yield();

                return(PCM16Factory.FromAudioData(Read(data, filename)));
            } catch (Exception e) {
                throw new AudioImporterException("Could not convert from B" + (char)data[0] + "STM: " + e.Message);
            }
        }
        /// <summary>
        /// Renders a file to WAV using VGMPlay and reads it into a PCM16Audio object.
        /// </summary>
        /// <param name="filename">The path of the file to read</param>
        /// <param name="preferredSampleRate">The sample rate to render the VGM at</param>
        /// <returns>A PCM16Audio, which may or may not be looping</returns>
        public async Task <PCM16Audio> ReadFileAsync(string filename)
        {
            if (!File.Exists(ExePath))
            {
                throw new AudioImporterException("VGMPlay not found at path: " + ExePath);
            }
            if (filename.Contains('"'))
            {
                throw new AudioImporterException("File paths with double quote marks (\") are not supported");
            }

            try {
                string tmpDir = Path.Combine(Path.GetTempPath(), "LoopingaudioConverter-" + Guid.NewGuid());
                Directory.CreateDirectory(tmpDir);

                string inFile = Path.Combine(tmpDir, "audio" + Path.GetExtension(filename));
                File.Copy(filename, inFile);
                using (var sw = new StreamWriter(new FileStream(Path.Combine(tmpDir, "VGMPlay.ini"), FileMode.Create, FileAccess.Write))) {
                    sw.WriteLine("[General]");
                    if (SampleRate != null)
                    {
                        sw.WriteLine("SampleRate = " + SampleRate);
                    }
                    sw.WriteLine("FadeTime = 500");
                    sw.WriteLine("LogSound = 1");
                    sw.WriteLine("MaxLoops = 0x01");
                }

                ProcessStartInfo psi = new ProcessStartInfo {
                    FileName         = Path.GetFullPath(ExePath),
                    WorkingDirectory = tmpDir,
                    UseShellExecute  = false,
                    CreateNoWindow   = true,
                    Arguments        = inFile
                };
                var pr = await ProcessEx.RunAsync(psi);

                var data = PCM16Factory.FromFile(Path.Combine(tmpDir, "audio.wav"), true);
                Directory.Delete(tmpDir, true);

                // Check format
                bool compressed;
                using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
                    using (var br = new BinaryReader(fs)) {
                        int tag = br.ReadUInt16();
                        if (tag == 0x1F8B)
                        {
                            throw new Exception("Machine is big-endian");
                        }
                        compressed = tag == 0x8B1F;
                    }

                // Read loop points from file
                using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
                    using (var gz = compressed ? new GZipStream(fs, CompressionMode.Decompress) : fs as Stream)
                        using (var br = new BinaryReader(gz)) {
                            int tag = br.ReadInt32();
                            if (tag == 0x56676D20)
                            {
                                throw new Exception("Machine is big-endian");
                            }
                            if (tag != 0x206D6756)
                            {
                                throw new Exception($"File not in Vgm format ({tag.ToString("X8")})");
                            }

                            for (int i = 0; i < 5; i++)
                            {
                                br.ReadInt32();
                            }

                            int samples = br.ReadInt32();
                            br.ReadInt32();
                            int loopSamples = br.ReadInt32();

                            double sampleRateRatio = data.SampleRate / 44100.0;
                            samples     = (int)(samples * sampleRateRatio);
                            loopSamples = (int)(loopSamples * sampleRateRatio);

                            if (loopSamples == 0)
                            {
                                data.NonLooping = true;
                            }
                            else
                            {
                                data.Looping   = true;
                                data.LoopStart = samples - loopSamples;
                                data.LoopEnd   = samples;
                            }
                        }

                return(data);
            } catch (Exception e) {
                Console.Error.WriteLine(e.GetType());
                Console.Error.WriteLine(e.Message);
                Console.Error.WriteLine(e.StackTrace);
                throw new AudioImporterException("Could not read output of VGMPlay: " + e.Message);
            }
        }
Пример #9
0
        /// <summary>
        /// Applies one or more SoX effects to the LWAV given and reads the result into a new LWAV.
        /// Intended to either adjust the volume of the audio or reduce the file size.
        /// </summary>
        /// <param name="lwav">The LWAV to use as an input</param>
        /// <param name="max_channels">The new number of channels (if the LWAV already has this number of channels or fewer, this effect will not be applied)</param>
        /// <param name="db">Volume adjustment, in decibels (if 0, this effect will not be applied)</param>
        /// <param name="amplitude">Volume adjustment, in linear ratio (if 1, this effect will not be applied)</param>
        /// <param name="max_rate">The new sample rate (if the LWAV's sample rate is less than or equal to this value, this effect will not be applied)</param>
        /// <returns>A new LWAV object if one or more effects are applied; the same LWAV object if no effects are applied.</returns>
        public PCM16Audio ApplyEffects(PCM16Audio lwav, int max_channels = int.MaxValue, decimal db = 0, decimal amplitude = 1, int max_rate = int.MaxValue)
        {
            byte[] wav = lwav.Export();

            int channels   = Math.Min(max_channels, lwav.Channels);
            int sampleRate = Math.Min(max_rate, lwav.SampleRate);

            StringBuilder effects_string = new StringBuilder();

            if (channels != lwav.Channels)
            {
                effects_string.Append(" channels " + max_channels);
            }
            if (db != 0)
            {
                effects_string.Append(" vol " + db + " dB");
            }
            if (amplitude != 1)
            {
                effects_string.Append(" vol " + amplitude + " amplitude");
            }
            if (sampleRate != lwav.SampleRate)
            {
                effects_string.Append(" rate " + max_rate);
            }

            if (effects_string.Length == 0)
            {
                // No effects will be performed - just return the same LWAV that was passed in without calling SoX unnecessarily
                return(lwav);
            }

            string infile  = TempFiles.Create("wav");
            string outfile = TempFiles.Create("wav");

            File.WriteAllBytes(infile, wav);

            // Sometimes when SoX changes sample rate and sends the result to stdout, it gives the wrong length in the data chunk. Let's just have it send us raw PCM data instead.
            ProcessStartInfo psi = new ProcessStartInfo {
                FileName        = ExePath,
                UseShellExecute = false,
                CreateNoWindow  = true,
                Arguments       = "-t wav " + infile + " -t wav " + outfile + " " + effects_string
            };
            Process p = Process.Start(psi);

            p.WaitForExit();
            File.Delete(infile);

            try {
                PCM16Audio l = PCM16Factory.FromFile(outfile, true);
                l.Looping   = lwav.Looping;
                l.LoopStart = lwav.LoopStart;
                l.LoopEnd   = lwav.LoopEnd;

                if (l.Looping && l.SampleRate != lwav.SampleRate)
                {
                    // When the sample rate is changed, we need to change the loop points to match.
                    double ratio = (double)l.SampleRate / lwav.SampleRate;
                    l.LoopStart = (int)(l.LoopStart * ratio);
                    l.LoopEnd   = (int)(l.LoopEnd * ratio);
                }
                return(l);
            } catch (Exception e) {
                throw new AudioImporterException("Could not read SoX output: " + e.Message);
            }
        }