private void DrawWaveForm() { ClearPanels(); ClearLabels(); lblFileName.Invoke(new MethodInvoker(() => lblFileName.Text = "Analysis of audio file: " + (Parser.Songs == null ? Path.GetFileName(InputFile) : Parser.Songs[0].InternalName + ".mogg"))); var BassStream = Bass.BASS_StreamCreateFile(Tools.GetOggStreamIntPtr(), 0L, Tools.PlayingSongOggData.Length, BASSFlag.BASS_STREAM_DECODE); if (BassStream == 0) { MessageBox.Show("Error processing audio stream:\n" + Bass.BASS_ErrorGetCode(), Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } var length = Bass.BASS_ChannelGetLength(BassStream); var duration = Math.Round(Bass.BASS_ChannelBytes2Seconds(BassStream, length), 2); var audio_info = Bass.BASS_ChannelGetInfo(BassStream); string size; if (Tools.PlayingSongOggData.Length >= 1048576) { size = Math.Round((double)Tools.PlayingSongOggData.Length / 1048576, 2) + " MB"; } else { size = Math.Round((double)Tools.PlayingSongOggData.Length / 1024, 2) + " KB"; } var minutes = Parser.GetSongDuration((duration * 1000).ToString(CultureInfo.InvariantCulture)); lblStart.Invoke(new MethodInvoker(() => lblStart.Text = "0:00")); lblLength.Invoke(new MethodInvoker(() => lblLength.Text = minutes)); var info = "Channels: " + audio_info.chans + " | Sample rate: " + audio_info.freq + " Hz | Length: " + duration + " seconds (" + minutes + ") | File size: " + Tools.PlayingSongOggData.Length + " bytes (" + size + ")"; lblFileInfo.Invoke(new MethodInvoker(() => lblFileInfo.Text = info)); WaveForm WaveImage; switch (audio_info.chans) { case 1: WaveImage = GetNewWaveForm(false); if (!WaveImage.RenderStart(BassStream, false, true)) { MessageBox.Show("Error rendering audio stream:\n" + Bass.BASS_ErrorGetCode(), Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); ClearPanels(); return; } panelWave.BackgroundImage = WaveImage.CreateBitmap(WaveWidth, WaveHeight, -1, -1, highQualityDrawing.Checked); break; case 2: WaveImage = GetNewWaveForm(true); if (!WaveImage.RenderStart(BassStream, false, true)) { MessageBox.Show("Error rendering audio stream:\n" + Bass.BASS_ErrorGetCode(), Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); ClearPanels(); return; } panelWave.BackgroundImage = WaveImage.CreateBitmap(WaveWidth, WaveHeight, -1, -1, highQualityDrawing.Checked); break; default: try { List <string> TrackNames; List <bool> TrackIsStereo; var splitter = new MoggSplitter(); var ArrangedChannels = splitter.ArrangeStreamChannels(audio_info.chans, Path.GetExtension(InputFile) != ".wav"); GetTrackNames(out TrackNames, out TrackIsStereo); var height = WaveHeight / audio_info.chans; var top = 0; var index = 0; var maxCount = TrackNames.Any() ? TrackNames.Count : audio_info.chans; for (var i = 0; i < maxCount; i++) { var multiplier = TrackIsStereo.Any() && TrackIsStereo[i] ? 2 : 1; var panel = new Panel(); Invoke(new MethodInvoker(delegate { panel.Parent = panelWave; })); panel.Invoke(new MethodInvoker(() => panel.Left = -1)); panel.Invoke(new MethodInvoker(() => panel.Top = top - 1)); panel.Invoke(new MethodInvoker(() => panel.Width = WaveWidth + 2)); panel.Invoke(new MethodInvoker(() => panel.Height = (height * multiplier) + 1)); panel.Invoke(new MethodInvoker(() => panel.BackgroundImageLayout = ImageLayout.Stretch)); panel.Invoke(new MethodInvoker(() => panel.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right)); if (outlineAudioTracks.Checked && i < maxCount - 1) { panel.Invoke(new MethodInvoker(() => panel.BorderStyle = BorderStyle.FixedSingle)); } var map = TrackIsStereo.Any() && TrackIsStereo[i] ? new[] { ArrangedChannels[index], ArrangedChannels[index + 1], -1 } : new[] { ArrangedChannels[index], -1 }; var channel_stream = BassMix.BASS_Split_StreamCreate(BassStream, BASSFlag.BASS_STREAM_DECODE, map); WaveImage = GetNewWaveForm(TrackIsStereo.Any() && TrackIsStereo[i]); if (!WaveImage.RenderStart(channel_stream, false, true)) { MessageBox.Show("Error rendering audio stream:\n" + Bass.BASS_ErrorGetCode(), Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); ClearPanels(); ClearLabels(); return; } var endFrame = WaveImage.Position2Frames((length / audio_info.chans) * multiplier); panel.BackgroundImage = WaveImage.CreateBitmap(WaveWidth, height * multiplier, -1, endFrame, highQualityDrawing.Checked); var font = new Font("Times New Roman", 10f, FontStyle.Bold); var label = new Label(); Invoke(new MethodInvoker(delegate { label.Parent = panel; })); label.Invoke(new MethodInvoker(() => label.Visible = labelAudioChannels.Checked)); label.Invoke(new MethodInvoker(() => label.Location = new Point(3, 3))); label.Invoke(new MethodInvoker(() => label.BackColor = Color.Transparent)); label.Invoke(new MethodInvoker(() => label.ForeColor = Color.White)); label.Invoke(new MethodInvoker(() => label.Font = font)); label.Invoke(new MethodInvoker(() => label.Text = TrackNames.Count > 0 ? TrackNames[i] : "chan. " + i)); ChannelLabels.Add(label); Bass.BASS_StreamFree(channel_stream); ChannelPanels.Add(panel); top += (height * multiplier); index += multiplier; } } catch (Exception ex) { MessageBox.Show("Error rendering audio stream:\n" + ex.Message + "\n\n" + Bass.BASS_ErrorGetCode(), Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); ClearPanels(); ClearLabels(); return; } break; } Bass.BASS_StreamFree(BassStream); if (InputFiles.Count <= 1) { return; } var file = Path.GetDirectoryName(InputFile) + "\\" + Tools.CleanString(Path.GetFileNameWithoutExtension(InputFile), false) + ".jpg"; TakeScreenshot(file); }
public bool DownmixMogg(string CON_file, string output, MoggSplitFormat format, string quality, bool doWii = false, double start = 0.0, double length = 0.0, double fadeIn = 0.0, double fadeOut = 0.0, double volume = 0.0, string stems = "allstems") { if (!ExtractDecryptMogg(CON_file, true)) { return(false); } try { if (!InitBass()) { return(false); } var BassStream = Bass.BASS_StreamCreateFile(Tools.GetOggStreamIntPtr(), 0, Tools.PlayingSongOggData.Length, BASSFlag.BASS_STREAM_DECODE); var channel_info = Bass.BASS_ChannelGetInfo(BassStream); var BassMixer = BassMix.BASS_Mixer_StreamCreate(doWii ? 22050 : channel_info.freq, 2, BASSFlag.BASS_MIXER_END | BASSFlag.BASS_STREAM_DECODE); if (doWii) { BassMix.BASS_Mixer_StreamAddChannelEx(BassMixer, BassStream, BASSFlag.BASS_MIXER_MATRIX, 0, Bass.BASS_ChannelSeconds2Bytes(BassMixer, length)); var track_vol = (float)Utils.DBToLevel(Convert.ToDouble(volume), 1.0); Bass.BASS_ChannelSetPosition(BassStream, Bass.BASS_ChannelSeconds2Bytes(BassStream, start)); BASS_MIXER_NODE[] nodes = { new BASS_MIXER_NODE(0, 0), new BASS_MIXER_NODE(Bass.BASS_ChannelSeconds2Bytes(BassMixer, fadeIn), track_vol), new BASS_MIXER_NODE(Bass.BASS_ChannelSeconds2Bytes(BassMixer, length - fadeOut),track_vol), new BASS_MIXER_NODE(Bass.BASS_ChannelSeconds2Bytes(BassMixer, length), 0) }; BassMix.BASS_Mixer_ChannelSetEnvelope(BassStream, BASSMIXEnvelope.BASS_MIXER_ENV_VOL, nodes, nodes.Count()); } else { BassMix.BASS_Mixer_StreamAddChannel(BassMixer, BassStream, BASSFlag.BASS_MIXER_MATRIX); } var matrix = GetChannelMatrix(Parser.Songs[0], channel_info.chans, stems); BassMix.BASS_Mixer_ChannelSetMatrix(BassStream, matrix); var output_file = output; if (string.IsNullOrWhiteSpace(output)) { output_file = Path.GetDirectoryName(CON_file) + "\\" + Parser.Songs[0].InternalName + (format == MoggSplitFormat.WAV ? ".wav" : ".ogg"); } if (format == MoggSplitFormat.OGG) { var cmd = "bin\\oggenc2.exe -q" + quality + " - -o\"" + output_file + "\""; BassEnc.BASS_Encode_Start(BassMixer, cmd, BASSEncode.BASS_ENCODE_FP_24BIT | BASSEncode.BASS_ENCODE_AUTOFREE, null, IntPtr.Zero); } else { BassEnc.BASS_Encode_Start(BassMixer, output_file, BASSEncode.BASS_ENCODE_PCM | BASSEncode.BASS_ENCODE_AUTOFREE, null, IntPtr.Zero); } while (true) { var buffer = new byte[20000]; var c = Bass.BASS_ChannelGetData(BassMixer, buffer, buffer.Length); if (c < 0) { break; } } UnloadLibraries(); Tools.ReleaseStreamHandle(); return(File.Exists(output_file)); } catch (Exception ex) { ErrorLog.Add("Error downmixing mogg file:"); ErrorLog.Add(ex.Message); UnloadLibraries(); Tools.ReleaseStreamHandle(); return(false); } }