private void FrameConverter_DoWork(object sender, DoWorkEventArgs e) { try { // Initialize BASS and variables Bass.BASS_Init(0, 44100, BASSInit.BASS_DEVICE_NOSPEAKER, IntPtr.Zero); Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_MIDI_VOICES, 0); Data.StreamHandle = BassMidi.BASS_MIDI_StreamCreateFile(Data.MIDIToLoad, 0L, 0L, BASSFlag.BASS_MIDI_NOCROP | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_MIDI_DECAYEND, 0); Data.PlayedNotesAvg = new List <Double>(); // Check if the MIDI file is valid BASSError Error = Bass.BASS_ErrorGetCode(); if (Error == BASSError.BASS_ERROR_ILLPARAM || Error == BASSError.BASS_ERROR_FILEOPEN || Error == BASSError.BASS_ERROR_FILEFORM) { MessageBox.Show("Invalid MIDI file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Settings.Interrupt = true; return; } Data.OsuemSize = Properties.Settings.Default.CounterFont.Size; Int64 StreamLength = Bass.BASS_ChannelGetLength(Data.StreamHandle); Int32 ChunkLength = Convert.ToInt32(Bass.BASS_ChannelSeconds2Bytes(Data.StreamHandle, FFMPEGProcess.Hertz)); Byte[] Buffer; // Initialize played notes sync Data.NoteSync = new SYNCPROC(NoteSyncProc); Bass.BASS_ChannelSetSync(Data.StreamHandle, BASSSync.BASS_SYNC_MIDI_EVENT, (long)BASSMIDIEvent.MIDI_EVENT_NOTE, Data.NoteSync, IntPtr.Zero); // Initialize time signature sync BassMidi.BASS_MIDI_StreamGetMark(Data.StreamHandle, BASSMIDIMarker.BASS_MIDI_MARK_TIMESIG, 0, Data.Mark); Data.TimeSigSync = new SYNCPROC(TimeSigSyncProc); Bass.BASS_ChannelSetSync(Data.StreamHandle, BASSSync.BASS_SYNC_MIDI_TIMESIG, (long)BASSMIDIMarker.BASS_MIDI_MARK_TIMESIG, Data.TimeSigSync, IntPtr.Zero); // Initialize note count Data.TotalNotes = Convert.ToUInt32(BassMidi.BASS_MIDI_StreamGetEvents(Data.StreamHandle, -1, (BASSMIDIEvent)0x20000, null)); Data.HowManyZeroesNotes = "00000"; // Initialize conversion if (!StartConversion(Data.MIDIToLoad)) { return; } FPSUpdate(); if (Properties.Settings.Default.StillFramesBeginning) { for (int a = 0; a <= (Properties.Settings.Default.FPSExport * 5); a++) { // 5 seconds of nothing if (Settings.Interrupt == true) { break; } CheckPosition(); Data.NotesPerSecond = "0"; PushFrame(false); FFMPEGProcess.Frames++; FPSUpdate(); } } while (Bass.BASS_ChannelIsActive(Data.StreamHandle) == BASSActive.BASS_ACTIVE_PLAYING) { if (Data.OsuemSize > Properties.Settings.Default.CounterFont.Size) { Data.OsuemSize -= (Properties.Settings.Default.CounterFont.Size / 24); if (Data.OsuemSize < Properties.Settings.Default.CounterFont.Size) { Data.OsuemSize = Properties.Settings.Default.CounterFont.Size; } } else { Data.OsuemSize = Properties.Settings.Default.CounterFont.Size; } if (Settings.Interrupt == true) { break; } Buffer = new Byte[ChunkLength]; Bass.BASS_ChannelGetData(Data.StreamHandle, Buffer, ChunkLength); CheckPosition(); if (FFMPEGProcess.Frames % (ulong)Properties.Settings.Default.FPSExport == 0) { Data.NotesPerSecond = Data.PlayedNotesFrame.ToString(); Data.PlayedNotesAvg.Add(Data.PlayedNotesFrame); Data.AverageNotesPerSecond = Data.PlayedNotesAvg.Average().ToString("0.0"); Data.PlayedNotesFrame = 0; } PushFrame(false); FFMPEGProcess.Frames++; FPSUpdate(); } Buffer = new Byte[ChunkLength]; Bass.BASS_ChannelGetData(Data.StreamHandle, Buffer, ChunkLength); if (Properties.Settings.Default.StillFramesEnd) { for (int a = 0; a <= (Properties.Settings.Default.FPSExport * 5); a++) { if (Data.OsuemSize > Properties.Settings.Default.CounterFont.Size) { Data.OsuemSize -= (Properties.Settings.Default.CounterFont.Size / 24); if (Data.OsuemSize < Properties.Settings.Default.CounterFont.Size) { Data.OsuemSize = Properties.Settings.Default.CounterFont.Size; } } else { Data.OsuemSize = Properties.Settings.Default.CounterFont.Size; } // 5 seconds of nothing if (Settings.Interrupt == true) { break; } CheckPosition(); Data.NotesPerSecond = "0"; PushFrame(false); FFMPEGProcess.Frames++; FPSUpdate(); } } for (int i = 0; i < Data.PlayedNotesChan.Length; i++) { Data.PlayedNotesChan[i] = 0; } Data.Mark = new BASS_MIDI_MARK(); FFMPEGProcess.Frames = 0; FFMPEGProcess.FFMPEG.StandardInput.Close(); Bass.BASS_StreamFree(Data.StreamHandle); Bass.BASS_Free(); Settings.Interrupt = false; } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
/// <summary> /// Determines if the stream contains frames with the specified syncwords. /// </summary> /// <param name="syncWord">Syncword to search for.</param> /// <returns></returns> private bool IsEncoded(SyncWord syncWord) { const int framesToCheck = 5; const int bytesPerSample = 4; const int bytesPerWord = 2; const int channelCount = 2; long streamLength = Bass.BASS_ChannelGetLength(_handle); long currentPosition = 0; if (streamLength > 0) { currentPosition = Bass.BASS_ChannelGetPosition(_handle); if (currentPosition != 0) { Bass.BASS_ChannelSetPosition(_handle, 0); } } SyncFifoBuffer syncFifoBuffer = new SyncFifoBuffer(syncWord); float[] readBuffer = new float[channelCount]; int lastSyncWordPosition = -1; int lastFrameSize = -1; int frameCount = 0; bool result = false; int sampleIndex = 0; int maxSampleIndex = (syncWord.MaxFrameSize / bytesPerWord) * framesToCheck + syncWord.WordLength; while (!result && sampleIndex < maxSampleIndex) { int bytesRead = Bass.BASS_ChannelGetData(_handle, readBuffer, readBuffer.Length * bytesPerSample); if (bytesRead <= 0) { // End of stream break; } int samplesRead = bytesRead / bytesPerSample; int readSample = 0; while (!result && readSample < samplesRead) { // Convert float value to word UInt16 word = (UInt16)(readBuffer[readSample] * 32768); // Add word to fifo buffer syncFifoBuffer.Write(word); // Check Sync word if (syncFifoBuffer.IsMatch()) { int newSyncWordPosition = (sampleIndex - syncWord.WordLength + 1) * bytesPerWord; if (lastSyncWordPosition != -1) { int thisFrameSize = newSyncWordPosition - lastSyncWordPosition; if (lastFrameSize != -1) { if (thisFrameSize != lastFrameSize) { break; } } lastFrameSize = thisFrameSize; frameCount++; } lastSyncWordPosition = newSyncWordPosition; result = (frameCount == framesToCheck); } sampleIndex++; readSample++; } } if (streamLength > 0) { Bass.BASS_ChannelSetPosition(_handle, currentPosition); } return(result); }
private static string[] SplitAudio(string fileName, double[] segments, string prefix, string outputDirectory) { if (fileName == null) { throw new ArgumentNullException("fileName"); } if (segments == null) { throw new ArgumentNullException("segments"); } if (prefix == null) { throw new ArgumentNullException("prefix"); } if (outputDirectory == null) { throw new ArgumentNullException("outputDirectory"); } int i = Bass.BASS_StreamCreateFile(fileName, 0, 0, BASSFlag.BASS_STREAM_PRESCAN | BASSFlag.BASS_STREAM_DECODE); if (i == 0) { throw new InvalidOperationException("Couldn't create stream"); } double sum = segments.Sum(); long length = Bass.BASS_ChannelGetLength(i); double seconds = Bass.BASS_ChannelBytes2Seconds(i, length); if (sum > seconds) { throw new ArgumentOutOfRangeException("segments", "Required segments exceed file duration"); } BASS_CHANNELINFO info = Bass.BASS_ChannelGetInfo(i); if (!Directory.Exists(outputDirectory)) { Directory.CreateDirectory(outputDirectory); } int index = 0; var list = new List <string>(); foreach (double segment in segments) { double d = segment; long seconds2Bytes = Bass.BASS_ChannelSeconds2Bytes(i, d); var buffer = new byte[seconds2Bytes]; int getData = Bass.BASS_ChannelGetData(i, buffer, buffer.Length); string name = string.Format("{0}_{1}.wav", prefix, index); string combine = Path.Combine(outputDirectory, name); int bitsPerSample = info.Is8bit ? 8 : info.Is32bit ? 32 : 16; var waveWriter = new WaveWriter(combine, info.chans, info.freq, bitsPerSample, true); waveWriter.WriteNoConvert(buffer, buffer.Length); waveWriter.Close(); list.Add(combine); index++; } bool free = Bass.BASS_StreamFree(i); return(list.ToArray()); }
private void GenerateWaveformData(string path, int points = waveformCompressedPointCount) { if (generateWaveCancelTokenSource != null && !generateWaveCancelTokenSource.IsCancellationRequested) { generateWaveCancelTokenSource.Cancel(); } generateWaveCancelTokenSource = new CancellationTokenSource(); Task.Run(() => { int stream = Bass.BASS_StreamCreateFile(path, 0, 0, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_PRESCAN); int frameLength = (int)Bass.BASS_ChannelSeconds2Bytes(stream, 0.02); long streamLength = Bass.BASS_ChannelGetLength(stream, 0); int frameCount = (int)(streamLength / (double)frameLength); int waveformLength = frameCount * 2; float[] waveform = new float[waveformLength]; float[] levels = new float[2]; int actualPoints = Math.Min(points, frameCount); int compressedPointCount = actualPoints * 2; float[] waveformCompressedPoints = new float[compressedPointCount]; List <int> waveMaxPointIndexes = new List <int>(); for (int i = 1; i <= actualPoints; i++) { waveMaxPointIndexes.Add((int)Math.Round(waveformLength * (i / (double)actualPoints), 0)); } float maxLeftPointLevel = float.MinValue; float maxRightPointLevel = float.MinValue; int currentPointIndex = 0; for (int i = 0; i < waveformLength; i += 2) { Bass.BASS_ChannelGetLevel(stream, levels); waveform[i] = levels[0]; waveform[i + 1] = levels[1]; if (levels[0] > maxLeftPointLevel) { maxLeftPointLevel = levels[0]; } if (levels[1] > maxRightPointLevel) { maxRightPointLevel = levels[1]; } if (i > waveMaxPointIndexes[currentPointIndex]) { waveformCompressedPoints[(currentPointIndex * 2)] = maxLeftPointLevel; waveformCompressedPoints[(currentPointIndex * 2) + 1] = maxRightPointLevel; maxLeftPointLevel = float.MinValue; maxRightPointLevel = float.MinValue; currentPointIndex++; } if (i % 3000 == 0) { float[] clonedData = (float[])waveformCompressedPoints.Clone(); if (MainDispatcher == null) { WaveformData = clonedData; } else { MainDispatcher.Invoke(() => { WaveformData = clonedData; }); } } if (generateWaveCancelTokenSource.IsCancellationRequested) { break; } } float[] finalClonedData = (float[])waveformCompressedPoints.Clone(); if (MainDispatcher == null) { FullLevelData = waveform; WaveformData = finalClonedData; } else { MainDispatcher.Invoke(() => { FullLevelData = waveform; WaveformData = finalClonedData; }); } Bass.BASS_StreamFree(stream); }, generateWaveCancelTokenSource.Token); }
//複数のサウンドを合体(Posにマイナスが含まれている場合バグります //引数:合体させるファイル, サウンドの開始位置, 音量, 再生速度, 保存先, MP3として保存するか(falseの場合は.wav形式), 元のファイルを削除するか public static void Sound_Combine(List <string> Files, List <double> Pos, List <double> Volume, List <double> Speed, string To_File, bool IsEncodeMP3, bool IsFromFileDelete = false) { int mixer = BassMix.BASS_Mixer_StreamCreate(48000, 2, BASSFlag.BASS_STREAM_DECODE); long Mixer_Max_Length = 0; List <int> Streams = new List <int>(); List <int> Stream_Handles = new List <int>(); //ファイルをミックスする for (int Number = 0; Number < Files.Count; Number++) { Streams.Add(Bass.BASS_StreamCreateFile(Files[Number], 0, 0, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE)); Stream_Handles.Add(BassFx.BASS_FX_TempoCreate(Streams[Streams.Count - 1], BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_FX_FREESOURCE)); float Freq = 48000; Bass.BASS_ChannelGetAttribute(Stream_Handles[Stream_Handles.Count - 1], BASSAttribute.BASS_ATTRIB_TEMPO_FREQ, ref Freq); Bass.BASS_ChannelSetAttribute(Stream_Handles[Stream_Handles.Count - 1], BASSAttribute.BASS_ATTRIB_TEMPO_FREQ, Freq * (float)Speed[Number]); Bass.BASS_ChannelSetAttribute(Stream_Handles[Stream_Handles.Count - 1], BASSAttribute.BASS_ATTRIB_VOL, (float)(Volume[Number] / 100)); long start = Bass.BASS_ChannelSeconds2Bytes(mixer, Pos[Number]); BassMix.BASS_Mixer_StreamAddChannelEx(mixer, Stream_Handles[Stream_Handles.Count - 1], BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE, start, 0); long Now_Stream_Length = Bass.BASS_ChannelGetLength(Streams[Streams.Count - 1], BASSMode.BASS_POS_BYTES); if (Mixer_Max_Length < Now_Stream_Length + start) { Mixer_Max_Length = Now_Stream_Length + start; } } //.wavでエンコード(こっちの方が速い + 安定性が高い) EncoderWAV l = new EncoderWAV(mixer); l.InputFile = null; l.OutputFile = To_File + ".tmp"; l.WAV_BitsPerSample = 24; l.Start(null, IntPtr.Zero, false); byte[] encBuffer = new byte[65536]; while (Bass.BASS_ChannelIsActive(mixer) == BASSActive.BASS_ACTIVE_PLAYING) { int len = Bass.BASS_ChannelGetData(mixer, encBuffer, encBuffer.Length); if (len <= 0) { break; } else if (Mixer_Max_Length <= Bass.BASS_ChannelGetPosition(mixer, BASSMode.BASS_POS_BYTES)) { break; } } l.Stop(); //メモリ解放 Bass.BASS_StreamFree(mixer); foreach (int Stream in Stream_Handles) { Bass.BASS_StreamFree(Stream); } foreach (int Stream in Streams) { Bass.BASS_StreamFree(Stream); } //MP3形式にエンコード if (IsEncodeMP3) { Un4seen.Bass.Misc.EncoderLAME mc = new Un4seen.Bass.Misc.EncoderLAME(0); mc.EncoderDirectory = Voice_Set.Special_Path + "/Encode_Mp3"; mc.InputFile = To_File + ".tmp"; mc.OutputFile = To_File; mc.LAME_Bitrate = (int)Un4seen.Bass.Misc.EncoderLAME.BITRATE.kbps_144; mc.LAME_Mode = Un4seen.Bass.Misc.EncoderLAME.LAMEMode.Default; mc.LAME_Quality = Un4seen.Bass.Misc.EncoderLAME.LAMEQuality.Q2; Un4seen.Bass.Misc.BaseEncoder.EncodeFile(mc, null, true, false, true); mc.Dispose(); File.Delete(To_File + ".tmp"); } else { Sub_Code.File_Move(To_File + ".tmp", To_File, true); } if (File.Exists(To_File) && IsFromFileDelete) { foreach (string File_Now in Files) { Sub_Code.File_Delete_V2(File_Now); } } }
/// <summary> /// Получить время воспроизведения /// </summary> /// <returns></returns> public int GetDurationOfStream() { long time = Bass.BASS_ChannelGetLength(stream); return((int)Bass.BASS_ChannelBytes2Seconds(stream, time)); }
public long ChannelLengthInBytes() { return(Bass.BASS_ChannelGetLength(audioHandle, BASSMode.BASS_POS_BYTES)); }
internal static bool LoadAndPreviewMp3(string filename, bool previewPosition) { if (!File.Exists(filename)) { return(false); } UpdateTime = true; activeTimingPointIndex = -1; bool same = true; if (continuePlayback && audioTime / AudioLength < 0.8F && audioRate == 100 && filename == audioFilename) { SetVolumeMusicFade(volumeMusicFade / 3); } else { audioFilename = filename; FreeMusic(); //if (!Md5Dictionary.ContainsKey(filename)) // Md5Dictionary[filename] = GameBase.GetMd5(filename); audioStreamPrefilter = Bass.BASS_StreamCreateFile(filename, 0, 0, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_STREAM_PRESCAN); audioStream = BassFx.BASS_FX_TempoCreate(audioStreamPrefilter, BASSFlag.BASS_DEFAULT); Bass.BASS_ChannelSetAttribute(audioStream, BASSAttribute.BASS_ATTRIB_TEMPO_OPTION_USE_QUICKALGO, Bass.TRUE); Bass.BASS_ChannelSetAttribute(audioStream, BASSAttribute.BASS_ATTRIB_TEMPO_OPTION_OVERLAP_MS, 4); Bass.BASS_ChannelSetAttribute(audioStream, BASSAttribute.BASS_ATTRIB_TEMPO_OPTION_SEQUENCE_MS, 15); /* * Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_UPDATEPERIOD, 5); * Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_BUFFER, 6); * SYNCPROC proc = new SYNCPROC(syncCallback); * Bass.BASS_ChannelSetSync(audioStream, BASSSync.BASS_SYNC_POS, 10000, proc, new IntPtr(10000)); */ try { TAG_INFO tagInfo = new TAG_INFO(filename); if (BassTags.BASS_TAG_GetFromFile(audioStream, tagInfo)) { audioArtist = tagInfo.artist; audioTitle = tagInfo.title; } else { audioArtist = "unknown"; audioTitle = "unknown"; } } catch { audioArtist = "unknown"; audioTitle = "unknown"; } ResetMp3(); same = false; audioLengthRaw = Bass.BASS_ChannelGetLength(audioStream); AudioLength = (int)(Bass.BASS_ChannelBytes2Seconds(audioStream, audioLengthRaw) * 1000); Bass.BASS_ChannelGetAttribute(audioStream, BASSAttribute.BASS_ATTRIB_FREQ, ref audioFrequency); if (previewPosition) { Bass.BASS_ChannelSetPosition(audioStream, (PreviewTime == -1 ? ((float)AudioLength / 1000 * 0.4) : (float)PreviewTime / 1000)); } SetVolumeMusicFade(0); } AudioLength = (int)(Bass.BASS_ChannelBytes2Seconds(audioStream, Bass.BASS_ChannelGetLength(audioStream)) * 1000); continuePlayback = false; //volumeMusicCurrent = 0; //Bass.BASS_ChannelSetAttributes(audioStream, -1, volumeMusicCurrent, -101); Bass.BASS_ChannelPlay(audioStream, false); AudioState = AudioStates.Playing; return(same); }
private void tmrUpdateControls_Tick(object sender, EventArgs e) { if (stream == -1) { return; } try { long pos = 0; long len = 0; len = Bass.BASS_ChannelGetLength(stream); pos = Bass.BASS_ChannelGetPosition(stream); double tElapsed = 0; double tRemain = 0; double tLength = 0; tLength = Bass.BASS_ChannelBytes2Seconds(stream, len); tElapsed = Bass.BASS_ChannelBytes2Seconds(stream, pos); tRemain = tLength - tElapsed; lblTime2.Text = Un4seen.Bass.Utils.FixTimespan(tLength, "MMSS"); lblTime1.Text = Un4seen.Bass.Utils.FixTimespan(tElapsed, "MMSS"); trbPosition.MaxValue = (int)(Bass.BASS_ChannelGetLength(stream) / 1000); TaskbarManager.Instance.SetProgressValue((int)(Bass.BASS_ChannelGetPosition(stream) / 1000), (int)(Bass.BASS_ChannelGetLength(stream) / 1000), this.Handle); if (!shouldChangePosition) { trbPosition.Value = (int)(Bass.BASS_ChannelGetPosition(stream) / 1000); if (tRemain == 0) { if (lbFiles.Items.Count > 1) { cmdNext.PerformClick(); } } } Un4seen.Bass.BASSActive isActive = default(Un4seen.Bass.BASSActive); isActive = Bass.BASS_ChannelIsActive(stream); if (isActive == Un4seen.Bass.BASSActive.BASS_ACTIVE_PLAYING) { TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Normal); } else if (isActive == Un4seen.Bass.BASSActive.BASS_ACTIVE_PAUSED) { TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Paused); } } catch (Exception ex) { } }