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 個の結果が返されることがわかります。そのうちの 1 つは、必要な mp3 形式への変換です。
バックグラウンド ワーカーを使用して最初の変換を実行した後にこれと同じ方法を実行すると、20 個の結果しか返されず、いずれも互換性のある mp3 形式ではありません。