繁体   English   中英

我无法弄清楚为什么与后台工作程序一起使用时此代码会失败

[英]I can't figure out why this code is failing when used with a background worker

我正在使用Alvas音频库将文件从Mp3转换为Wave格式,以便我可以对其进行编辑,然后将其转换回Mp3。 转换为Wave效果很好,但是当我尝试转换回Mp3时遇到麻烦。 由于某种原因,此失败与我使用后台工作者执行初始转换这一事实有关。

我知道,如果没有该库的源代码,将很难尝试找出正在发生的事情,但是我希望有人可能会对发生的问题提出建议。

当我在没有后台工作程序的情况下同步调用相同的代码时,它可以完美运行。 有任何想法吗?

这是我从后台工作人员调用以执行转换的代码:

    public Tuple<float, float> convertMp3ToWav(Track track) //with Detection, duration check, and TODO: silence removal
    {
        try
        {
            string baseFile = Path.GetFileName(track.location);
            ////////////////////////////
            //string baseFile = track.location.Remove(track.location.Length - 4);
            string outputFile = directory + "Temp\\" + baseFile.Remove(baseFile.Length - 4) + ".wav";
            cleanupFiles.Add(outputFile);
            if (!File.Exists(outputFile))
            {
                int soundStart = -1;
                int soundEnd = 0;
                Mp3Reader mr = new Mp3Reader(File.OpenRead(track.location));
                IntPtr mp3Format = mr.ReadFormat();
                IntPtr pcmFormat = AudioCompressionManager.GetCompatibleFormat(mp3Format, AudioCompressionManager.PcmFormatTag);
                AcmConverter acm = new AcmConverter(mp3Format, pcmFormat, false);

                int sec = 1024;
                int i = 0;

                bool soundFound = false;
                while (true)
                {
                    byte[] mp3Data = mr.ReadDataInBytes(i, sec);
                    if (mp3Data.Length == 0)
                    {
                        break;
                    }
                    byte[] pcmData = acm.Convert(mp3Data);
                    foreach (byte d in pcmData) //THIS SECTION CHECKS IF THE Section in question has silence
                    {
                        if (d != 0)
                        {
                            soundFound = true;
                        }

                    }
                    if ((soundStart == -1) && (soundFound == true)) //if no beginning sound has been found yet, but has now been found
                    {
                        soundStart = i; //This will be precise to whatever value of sec has been chosen
                    }
                    else if ((soundStart != -1) && (soundFound == true)) //this is a possible end value
                    {
                        soundEnd = i;   //this value will be rewritten each time there is sound found after soundstart is set.
                                        //so this value will remain the same if no further sound is found in the track, and will represent the 
                                        //end of sound in the track
                    }

                    soundFound = false;
                    i += sec;
                }
                int finalDuration = soundEnd - soundStart;
                mr.Close();
                Mp3Reader reader = new Mp3Reader(File.OpenRead(track.location));
                IntPtr thisFormat = reader.ReadFormat();
                byte[] completeTrack = reader.ReadDataInBytes(soundStart, finalDuration);
                byte[] convertedTrack = AudioCompressionManager.Convert(thisFormat, pcmFormat, completeTrack, false);
                WaveWriter ww = new WaveWriter(File.OpenWrite(outputFile), AudioCompressionManager.FormatBytes(pcmFormat));
                ww.WriteData(convertedTrack);
                ww.Close();
                reader.Close();

                float bpm = performBeatDetection(track);
                float duration = getTrackDuration(track);

                return new Tuple<float, float>(bpm, duration);
            }
            else
            {
                //File already exists, just remove silence, get bpm and duration
                //string silenceRemoved = removeSilenceFromTrack(outputFile);
                float bpm = performBeatDetection(track);
                float duration = getTrackDuration(track);
                return new Tuple<float, float>(bpm, duration);
            }
        }
        catch (Alvas.Audio.AudioException e)
        {
            MessageBox.Show("ERROR: " + e.ToString());
            return new Tuple<float, float>(0f, 0f);
        }
    }

编辑:

特定故障是库中的异常。 当您想使用Alvas将文件从一种音频格式转换为另一种音频格式时,首先要阅读文件当前格式的格式,例如

IntPtr mp3Format = mr.ReadFormat();

然后进行转换,您调用静态方法

AudioCompressionManager.GetCompatibleFormat(oldFormat, newFormatTag);

当我在使用后台工作者后调用此最后一个方法时,它以错误的英语引发了一个异常“格式转换失败”。 在库中使用稍微不同的方法:

AudioCompressionManager.GetCompatibleFormatList(oldFormat);

揭示了当我不使用后台工作程序并且使用后一种方法(GetCompatibleFormatList)时,它将返回51个结果,其中之一是对所需mp3格式的转换。

如果使用后台工作程序执行初始转换后执行相同的方法,则它仅返回20个结果,但都不是兼容的mp3格式。

当您不定义“麻烦”时,很难具体说明。 但是也许这些想法会有所帮助:

  • 后台线程使用的任何数据(或文件)是否会被前台线程触及? (例如,在使用track参数时,它是否可以以任何方式处置或修改?)

  • 后台线程运行时,前台线程是否调用任何库API? 您的任何代码都可以在多个线程上调用库代码吗? 您的前台线程是否正确等待后台线程完成结果? (例如,作为测试,请尝试仅使您的前台线程加入后台线程(或进行繁忙的等待/睡眠),以便它仅在执行处理时等待-问题消失了吗?)

  • 库是否执行可能需要在特定线程上调用的任何操作-特别是是否可能需要在UI线程中运行它才能更新进度条或类似的东西? (这包括可能需要在UI线程中调用的代码中的事件处理程序)

  • 除了返回类型之外,是否还有其他数据要传递回主线程? 如果是这样,您是否正在使用同步(锁定或易失性等)来确保您读取正确的(最新)值?

  • 您确定在处理方法返回之前,所有数据都已写入,刷新到磁盘并且已关闭所有文件吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM