void MixTrack(int pMixer, Track pTrack, Dictionary <AudioSample, int> pSamples) { foreach (Note n in pTrack.Notes) { //TODO: Maybe use another length instead of 0 long start = Bass.BASS_ChannelSeconds2Bytes(pMixer, PositionOfNote(n)); BassMix.BASS_Mixer_StreamAddChannelEx(pMixer, pSamples[n.Sample], 0, start, 0); } }
public void Play_With_Buildup() { Stop(); if (InitBass(HZ)) { Channel = BassMix.BASS_Mixer_StreamCreate(HZ, 2, BASSFlag.BASS_MIXER_END); point_B = GCHandle.Alloc(build_mem, GCHandleType.Pinned); point_L = GCHandle.Alloc(loop_mem, GCHandleType.Pinned); Stream_B = Bass.BASS_StreamCreateFile(point_B.AddrOfPinnedObject(), 0, build_mem.LongLength, BASSFlag.BASS_STREAM_DECODE); build_len = Bass.BASS_ChannelGetLength(Stream_B, BASSMode.BASS_POS_BYTES); Stream_L = Bass.BASS_StreamCreateFile(point_L.AddrOfPinnedObject(), 0, loop_mem.LongLength, BASSFlag.BASS_STREAM_DECODE); loop_len = Bass.BASS_ChannelGetLength(Stream_L); BassMix.BASS_Mixer_StreamAddChannel(Channel, Stream_B, BASSFlag.BASS_DEFAULT); BassMix.BASS_Mixer_StreamAddChannelEx(Channel, Stream_L, BASSFlag.BASS_MIXER_NORAMPIN, build_len, 0); _loopSync = BassMix.BASS_Mixer_ChannelSetSync(Stream_L, BASSSync.BASS_SYNC_POS | BASSSync.BASS_SYNC_MIXTIME, loop_len, _loopSyncCallback, new IntPtr(1)); } }
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); } }
//複数のサウンドを合体(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); } } }