簡體   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