/// <summary> /// Saves the partial as wave. /// </summary> /// <param name="inFilename">The in filename.</param> /// <param name="outFilename">The out filename.</param> /// <param name="start">The start position in seconds.</param> /// <param name="length">The length in seconds.</param> /// <param name="offset">The offset position in seconds.</param> /// <param name="gain">The gain.</param> /// <param name="bpm">The BPM.</param> /// <param name="targetBpm">The target BPM.</param> public static void SavePartialAsWave(string inFilename, string outFilename, double start, double length, double offset = 0, float gain = 0, decimal bpm = 0, decimal targetBpm = 0) { // DebugHelper.WriteLine("Saving portion of track as wave with offset - " + inFilename); var audioStream = new Sample { Filename = inFilename, Description = inFilename, Gain = gain, Bpm = bpm }; AudioStreamHelper.LoadAudio(audioStream); if (targetBpm != 0) { if (bpm == 0) { bpm = BpmHelper.GetBpmFromLoopLength(length); } var percentChange = BpmHelper.GetAdjustedBpmPercentChange(bpm, targetBpm) / 100; AudioStreamHelper.SetTempoToMatchBpm(audioStream.ChannelId, bpm, targetBpm); length = length * (double)(1 + percentChange); } const BASSEncode flags = BASSEncode.BASS_ENCODE_PCM; BassEnc.BASS_Encode_Start(audioStream.ChannelId, outFilename, flags, null, IntPtr.Zero); var startByte = Bass.BASS_ChannelSeconds2Bytes(audioStream.ChannelId, start); var endByte = Bass.BASS_ChannelSeconds2Bytes(audioStream.ChannelId, start + length); if (offset == 0 || offset == start) { TransferBytes(audioStream.ChannelId, startByte, endByte); } else { startByte = Bass.BASS_ChannelSeconds2Bytes(audioStream.ChannelId, offset); TransferBytes(audioStream.ChannelId, startByte, endByte); startByte = Bass.BASS_ChannelSeconds2Bytes(audioStream.ChannelId, start); endByte = Bass.BASS_ChannelSeconds2Bytes(audioStream.ChannelId, offset); TransferBytes(audioStream.ChannelId, startByte, endByte); } BassEnc.BASS_Encode_Stop(audioStream.ChannelId); Bass.BASS_StreamFree(audioStream.ChannelId); AudioStreamHelper.UnloadAudio(audioStream); }
/// <summary> /// Saves audio data as a mono wave. /// </summary> /// <param name="audioData">The audio data.</param> /// <param name="outFilename">The output filename.</param> /// <param name="length">The maximum length in seconds, or 0 for no limit.</param> /// <param name="gain">The gain.</param> /// <exception cref="System.Exception">Cannot load audio data</exception> public static void SaveAsMonoWave(byte[] audioData, string outFilename, double length, float gain) { // DebugHelper.WriteLine("SaveAsMonoWave"); var audioDataHandle = GCHandle.Alloc(audioData, GCHandleType.Pinned); var audioDataPointer = audioDataHandle.AddrOfPinnedObject(); var channel = Bass.BASS_StreamCreateFile(audioDataPointer, 0, audioData.Length, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_STREAM_PRESCAN); if (channel == 0) { throw new Exception("Cannot load audio data"); } // create a mono 44100Hz mixer var mixer = BassMix.BASS_Mixer_StreamCreate(44100, 1, BASSFlag.BASS_MIXER_END | BASSFlag.BASS_STREAM_DECODE); // plug in the source BassMix.BASS_Mixer_StreamAddChannel(mixer, channel, BASSFlag.BASS_MIXER_DOWNMIX | BASSFlag.BASS_MIXER_NORAMPIN); AudioStreamHelper.SetReplayGain(mixer, gain); const BASSEncode flags = BASSEncode.BASS_ENCODE_PCM; BassEnc.BASS_Encode_Start(mixer, outFilename, flags, null, IntPtr.Zero); const int startByte = 0; if (length == 0) { length = Bass.BASS_ChannelBytes2Seconds(channel, Bass.BASS_ChannelGetLength(channel)); } var totalTransferLength = Bass.BASS_ChannelSeconds2Bytes(mixer, length); Bass.BASS_ChannelSetPosition(channel, startByte, BASSMode.BASS_POS_BYTES); while (totalTransferLength > 0) { var buffer = new byte[65536]; var transferLength = totalTransferLength; if (transferLength > buffer.Length) { transferLength = buffer.Length; } // get the decoded sample data var transferred = Bass.BASS_ChannelGetData(mixer, buffer, (int)transferLength); if (transferred <= 1) { break; // error or the end } totalTransferLength -= transferred; } BassEnc.BASS_Encode_Stop(mixer); BassMix.BASS_Mixer_ChannelRemove(channel); Bass.BASS_StreamFree(channel); Bass.BASS_StreamFree(mixer); audioDataHandle.Free(); // DebugHelper.WriteLine("END SaveAsMonoWave"); }