Esempio n. 1
0
        /// <summary>
        /// Convertit un fichier et lance le suivant dans <see cref='FilesToConvert'/>.
        /// </summary>
        /// <param name="fichier">Le fichier à convertir.</param>
        /// <param name="cancellationToken">Jeton d'annulation qui peut être utilisé par d'autres objets ou threads pour être informés de l'annulation.</param>
        /// <returns>true si la conversion a réussi; sinon false.</returns>
        public static async Task <string[]> ConvertFile(Fichier fichier, bool finalize = true, CancellationToken cancellationToken = default, PauseToken pauseToken = default)
        {
            bool success = false;
            IEnumerable <string> filesToDelete = null;

            try
            {
                ConversionCount++;
                await pauseToken.WaitWhilePausedAsync();

                if (cancellationToken.IsCancellationRequested || !File.Exists(fichier.Path))
                {
                    return(null);
                }

                fichier.OriginalState = "FSTATE_Conversion";

                var(dspFileNames, channelsCount) = await GetDSPFiles(fichier.Path, VGMStreamProcessTypes.Conversion, 0, cancellationToken, pauseToken);

                if ((filesToDelete = dspFileNames) == null)
                {
                    return(null);
                }

                var wavFileNames = (await dspFileNames.SelectAsync(dspFile => VGMStream.CreateTempFile("wav", VGMStreamProcessTypes.Conversion), cancellationToken)).ToArray();
                filesToDelete = dspFileNames.Concat(wavFileNames);

                var vgmstreamTmpInfos   = new ProcessStartInfo[channelsCount];
                var vgmstreamTmpProcess = new Process[channelsCount];

                await pauseToken.WaitWhilePausedAsync();

                if (cancellationToken.IsCancellationRequested || !File.Exists(App.VGMStreamPath) && !await App.AskVGMStream())
                {
                    return(null);                                                                                                           //Check VGMStream
                }
                for (int i = 0; i < channelsCount && !cancellationToken.IsCancellationRequested; i++)
                {
                    await Task.Run(() =>
                    {
                        pauseToken.WaitWhilePausedAsync();
                        vgmstreamTmpInfos[i]   = VGMStream.StartInfo(dspFileNames[i], wavFileNames[i], fichier.LoopCount, fichier.FadeOut, fichier.FadeDelay, fichier.FadeTime, fichier.StartEndLoop);
                        vgmstreamTmpProcess[i] = Process.Start(vgmstreamTmpInfos[i]);
                        VGMStream.RunningProcess.Add(vgmstreamTmpProcess[i], VGMStreamProcessTypes.Conversion);
                    });
                }

                for (int i = 0; i < vgmstreamTmpProcess.Length; i++)
                {
                    await vgmstreamTmpProcess[i].WaitForExitAsync(cancellationToken);
                    if (vgmstreamTmpProcess[i].ExitCode != 0)
                    {
                        return(null);
                    }
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return(null);
                }

                try
                {
                    await Task.Run(() =>
                    {
                        var wfrs         = wavFileNames.Select(file => new WaveFileReader(file)).ToArray();
                        var waveProvider = new MultiplexingWaveProvider(wfrs);
                        WaveFileWriter.CreateWaveFile(fichier.FinalDestination, waveProvider);

                        foreach (var wfr in wfrs)
                        {
                            wfr.Close();
                        }
                    }, cancellationToken);

                    await pauseToken.WaitWhilePausedAsync();

                    if (!cancellationToken.IsCancellationRequested)
                    {
                        success = true;
                        var data = await vgmstreamTmpProcess[0].StandardOutput.ReadAllLinesAsync().WithCancellation(cancellationToken);

                        var indexOfPath     = data.IndexOf(data.FirstOrDefault(s => s.Contains(dspFileNames[0])));
                        var indexOfChannels = data.IndexOf(data.FirstOrDefault(s => s.Contains("channels")));
                        var indexOfFormat   = data.IndexOf(data.FirstOrDefault(s => s.Contains("metadata from")));
                        var indexOfBitrate  = data.IndexOf(data.FirstOrDefault(s => s.Contains("bitrate")));

                        data[indexOfPath]     = data[indexOfPath].Replace(dspFileNames[0], fichier.Path);
                        data[indexOfChannels] = data[indexOfChannels].Replace("1", channelsCount.ToString());
                        data[indexOfFormat]   = data[indexOfFormat].Replace("Standard Nintendo DSP header", "Retro Studios DKCTF CSMP");

                        var brp = data[indexOfBitrate].Split(':');
                        if (brp.Length == 2)
                        {
                            var brs = brp[1].Replace("kbps", string.Empty);
                            var br  = brs.ToInt();
                            if (br != null)
                            {
                                var bitrate = br * channelsCount;
                                data[indexOfBitrate] = data[indexOfBitrate].Replace(br.ToString(), bitrate.ToString());
                            }
                        }

                        return(data);
                    }
                    else
                    {
                        return(null);
                    }
                }
                catch { return(null); }
            }
            catch (OperationCanceledException) { return(null); }
            finally
            {
                await VGMStream.DeleteTempFilesByName(filesToDelete);

                if (success)
                {
                    fichier.OriginalState = "FSTATE_Completed";
                }
                else if (!cancellationToken.IsCancellationRequested && finalize)
                {
                    fichier.SetInvalid();
                }

                ConversionCount--;
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Obtient le nom du fichier audio au format WAV à partir d'un fichier RFRM CSMP.
        /// </summary>
        /// <param name="fichier">Le fichier à décoder.</param>
        /// <param name="Out">true si la sortie doit être lue; false si l'entrée doit être lue.</param>
        /// <param name="cancellationToken">Jeton d'annulation qui peut être utilisé par d'autres objets ou threads pour être informés de l'annulation.</param>
        /// <returns>Le Stream contenant les données audio.</returns>
        public static async Task <Stream> GetStream(Fichier fichier, bool Out = false, CancellationToken cancellationToken = default)
        {
            if (cancellationToken.IsCancellationRequested || !File.Exists(fichier.Path))
            {
                return(null);
            }

            IEnumerable <string> filesToDelete = null;
            string fn = await VGMStream.CreateTempFileAsync("wav", VGMStreamProcessTypes.Streaming); //Nom du fichier temporaire

            try
            {
                StreamingCount++;
                var(dspFileNames, channelsCount) = await GetDSPFiles(fichier.Path, VGMStreamProcessTypes.Streaming, 0, cancellationToken);

                if ((filesToDelete = dspFileNames) == null)
                {
                    return(null);
                }

                var wavFileNames = (await dspFileNames.SelectAsync(dspFile => VGMStream.CreateTempFile("wav", VGMStreamProcessTypes.Streaming), cancellationToken)).ToArray();
                filesToDelete = dspFileNames.Concat(wavFileNames);

                var vgmstreamTmpInfos   = new ProcessStartInfo[channelsCount];
                var vgmstreamTmpProcess = new Process[channelsCount];

                if (cancellationToken.IsCancellationRequested || !File.Exists(App.VGMStreamPath) && !await App.AskVGMStream())
                {
                    return(null);                                                                                                           //Check VGMStream
                }
                for (int i = 0; i < channelsCount && !cancellationToken.IsCancellationRequested; i++)
                {
                    await Task.Run(() =>
                    {
                        vgmstreamTmpInfos[i]   = Out ? VGMStream.StartInfo(dspFileNames[i], wavFileNames[i], fichier.LoopCount, fichier.FadeOut, fichier.FadeDelay, fichier.FadeTime, fichier.StartEndLoop) : VGMStream.StartInfo(dspFileNames[i], wavFileNames[i], 1, false);
                        vgmstreamTmpProcess[i] = Process.Start(vgmstreamTmpInfos[i]);
                        VGMStream.RunningProcess.Add(vgmstreamTmpProcess[i], VGMStreamProcessTypes.Streaming);
                    });
                }

                cancellationToken.Register(() =>
                {
                    foreach (Process process in vgmstreamTmpProcess)
                    {
                        process.TryKill();
                        if (VGMStream.RunningProcess.ContainsKey(process))
                        {
                            VGMStream.RunningProcess.Remove(process);
                        }
                    }
                });

                for (int i = 0; i < vgmstreamTmpProcess.Length; i++)
                {
                    await vgmstreamTmpProcess[i].WaitForExitAsync(cancellationToken);
                    if (vgmstreamTmpProcess[i].ExitCode != 0)
                    {
                        return(null);
                    }
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return(null);
                }

                try
                {
                    await Task.Run(() =>
                    {
                        var wfrs         = wavFileNames.Select(file => new WaveFileReader(file)).ToArray();
                        var waveProvider = new MultiplexingWaveProvider(wfrs);
                        WaveFileWriter.CreateWaveFile(fn, waveProvider);

                        foreach (var wfr in wfrs)
                        {
                            wfr.Close();
                        }
                    }, cancellationToken);

                    return(cancellationToken.IsCancellationRequested ? null : File.OpenRead(fn));
                }
                catch (OperationCanceledException) { return(null); }
                catch
                {
                    fichier.SetInvalid();
                    return(null);
                }
            }
            catch (OperationCanceledException) { return(null); }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, App.Str("TT_Error"), MessageBoxButton.OK, MessageBoxImage.Error);
                return(null);
            }
            finally
            {
                if (!cancellationToken.IsCancellationRequested)
                {
                    await VGMStream.DeleteTempFilesByName(filesToDelete);
                }
                StreamingCount--;
            }
        }