varispeed-sample icon indicating copy to clipboard operation
varispeed-sample copied to clipboard

Save speedControl in WaveFileWriter

Open julio-bc opened this issue 3 years ago • 0 comments

Hi,

I would like if is possible save an audio with speed control modified in another wav audio file.

It is possible?

Regards

Hi, I wrote in c# this function that save a wave file correctly, but I have not idea because the speedControl.Read() method does not stop reading data. I have to detect 0 values in samples read to detect end of file. speedControl.Read() allways returns buffer.Length. Any idea?

    ```

public static void CreateWaveFileWithSpeedControl(string outputFile, AudioFileReader reader, int percentageOfTime) { try { var speedControl = new VarispeedSampleProvider(reader, 100, new SoundTouchProfile(true, false));

            if (percentageOfTime != 100)
            {
                if (percentageOfTime is < 50 or > 150)
                {
                    var time = percentageOfTime;
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        MessageBox.Show(
                            "El porcentaje de tiempo tiene que estar en el rango 50 - 150 (se entrega el valor " +
                            time + "). Se redefine a 100%", "ERROR",
                            MessageBoxButton.OK, MessageBoxImage.Error);
                    }, null);
                    percentageOfTime = 100;
                }
            }
            speedControl.PlaybackRate = (float)percentageOfTime / 100;

            var buffer = new float[1024];
            int read;
            var flagBreak = false;
            var flagDetectadoPrimerCero = false;

            using var waveFileWriter = new WaveFileWriter(outputFile, reader.WaveFormat);
            while ((read = speedControl.Read(buffer, 0, buffer.Length)) > 0)
            {
                /* IMPORTANTE!! Puede haber 0´s al inicio del audio. Quizás por el algoritmo utilizado */
                /* IMPORTANTE!! speedControl.Read nunca devuelve 0. Parece que aunque termine el audio sigue devolviendo el
                                valor "buffer.Length" pero conteniendo 0's. Por lo tanto para detectar el final vamos a espiar
                                cuando envía el primer 0 del fin del audio */
                var offset = 0;

                if (!flagDetectadoPrimerCero)
                {
                    for (var i = 0; i < read; i++)
                    {
                        if (buffer[i] == 0) continue;
                        flagDetectadoPrimerCero = true;
                        offset = i;
                        break;
                    }

                    /* Por seguridad si devolviese siempre 0´s el sw se quedaría colgado. Imaginamos que ningún audio puede devolver todo el buffer a 0 */
                    if (!flagDetectadoPrimerCero)
                        throw new Exception("El audio no devuelve valores en CreateWaveFileWithSpeedControl()");
                }
                for (var i = offset; i < buffer.Length; i++)
                {
                    if (buffer[i] != 0) continue;
                    read = i - offset;
                    flagBreak = true;
                    break;
                }
                waveFileWriter?.WriteSamples(buffer, offset, read - offset);
                if (flagBreak)
                    break;
            }
        }
        catch (Exception e)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                MessageBox.Show(e.Message, "ERROR",
                    MessageBoxButton.OK, MessageBoxImage.Error);
            }, null);
        }
    }

julio-bc avatar Oct 31 '22 01:10 julio-bc