Beispiel #1
0
 public virtual bool Stop()
 {
     if (this.EncoderHandle == 0)
     {
         return(true);
     }
     if (this._useAsyncQueue)
     {
         if (BassEnc.BASS_Encode_StopEx(this.EncoderHandle, false))
         {
             this.EncoderHandle = 0;
             return(true);
         }
         if (BassEnc.BASS_Encode_Stop(this.EncoderHandle))
         {
             this.EncoderHandle = 0;
             return(true);
         }
     }
     else if (BassEnc.BASS_Encode_Stop(this.EncoderHandle))
     {
         this.EncoderHandle = 0;
         return(true);
     }
     return(false);
 }
Beispiel #2
0
        /// <summary>
        /// Stops the playback and copies the audio stream from CD to a <see cref="Stream"/> in MP3
        /// format asynchronously. If the song was playing before copying, playback will be restored.
        /// </summary>
        /// <param name="TargetStream">The <see cref="Stream"/> where the media is written to.</param>
        /// <param param name="Progress">An <see cref="IProgress{T}"/> instance that will be used to report the save progress. Can be null.</param>
        /// <returns>A <see cref="Task"/> that represents the asynchronous process.</returns>
        public async Task <bool> SaveToAsync(Stream TargetStream, IProgress <LongOperationProgress> Progress)
        {
            bool   RequiresRestore = this.IsPlaying;
            double Position        = this.Position;

            if (this.IsPlaying)
            {
                this.Stop();
            }

            ENCODEPROC proc = new ENCODEPROC(
                (handle, channel, buffer, length, user) => {
                byte[] ManagedBuffer = new byte[length];
                Marshal.Copy(buffer, ManagedBuffer, 0, length);

                TargetStream.Write(ManagedBuffer, 0, length);
            }
                );

            int  DecodingChannel       = Bass.BASS_StreamCreateFile(this.Filename, 0, 0, BASSFlag.BASS_STREAM_DECODE);
            long DecodingChannelLength = Bass.BASS_ChannelGetLength(DecodingChannel);
            int  Handle = BassEnc.BASS_Encode_Start(DecodingChannel, (new Lame()).GetCommandLine(), BASSEncode.BASS_ENCODE_AUTOFREE, proc, IntPtr.Zero);

            LongOperationProgress Status = new LongOperationProgress {
                IsIndetermine = false,
                Maximum       = DecodingChannelLength,
                Position      = 0
            };

            Progress?.Report(Status);

            await Task.Run(() => {
                int BufferLength = 10240;
                byte[] Buffer    = new byte[BufferLength];

                while (Bass.BASS_ChannelGetPosition(DecodingChannel) < DecodingChannelLength)
                {
                    Status.Position += Bass.BASS_ChannelGetData(DecodingChannel, Buffer, BufferLength);
                    Progress?.Report(Status);
                }

                BassEnc.BASS_Encode_Stop(Handle);
            });

            this.ChannelID = Bass.BASS_StreamCreateFile(this.Filename, 0, 0, BASSFlag.BASS_DEFAULT);
            if (RequiresRestore)
            {
                this.Position = Position;
                this.Play();
            }

            return(true);
        }
        /// <summary>
        ///     Saves as wave.
        /// </summary>
        /// <param name="audioData">The audio data.</param>
        /// <param name="outFilename">The out filename.</param>
        public static void SaveAsWave(byte[] audioData, string outFilename)
        {
            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");
            }

            const BASSEncode flags = BASSEncode.BASS_ENCODE_PCM;

            BassEnc.BASS_Encode_Start(channel, outFilename, flags, null, IntPtr.Zero);

            const int startByte = 0;
            var       endByte   = Bass.BASS_ChannelBytes2Seconds(channel, Bass.BASS_ChannelGetLength(channel));

            var totalTransferLength = endByte - startByte;

            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(channel, buffer, (int)transferLength);

                if (transferred <= 1)
                {
                    break;                   // error or the end
                }
                totalTransferLength -= transferred;
            }
            BassEnc.BASS_Encode_Stop(channel);

            Bass.BASS_StreamFree(channel);
            audioDataHandle.Free();
        }
Beispiel #4
0
        private void Encode(string filename)
        {
            // Отключаем кнопки
            playButton.Enabled   = false;
            saveButton.Enabled   = false;
            selectButton.Enabled = false;

            encodeProgress.Visible = true;

            // Энкодим в мп3
            ThreadPool.QueueUserWorkItem(w =>
            {
                int encoder = BassEnc.BASS_Encode_Start(fxStream, "lame -b192 - \"" + filename + "\"", 0, null, IntPtr.Zero /*this.Handle*/);

                long i          = 0;
                long chanLenght = Bass.BASS_ChannelGetLength(fxStream);
                while (i < chanLenght - 1)
                {
                    // Так как буфер в 1сек, то и записываем по одной секунде данных в проход
                    Bass.BASS_ChannelSetPosition(fxStream, i, BASSMode.BASS_POS_BYTES);
                    long len = Bass.BASS_ChannelSeconds2Bytes(fxStream, 1);
                    Bass.BASS_ChannelUpdate(fxStream, 1000);

                    i += len;

                    this.Invoke((MethodInvoker) delegate
                    {
                        encodeProgress.Value = (int)(i * 100 / chanLenght);
                        debugInfo.Text       = Bass.BASS_ErrorGetCode().ToString() + "\n" + len + "\n" + i + "\n" + Bass.BASS_ChannelGetLength(fxStream);
                    });
                }

                // ехал инвок через инвок
                this.Invoke((MethodInvoker) delegate
                {
                    encodeProgress.Visible = false;

                    playButton.Enabled   = true;
                    saveButton.Enabled   = true;
                    selectButton.Enabled = true;
                });

                BassEnc.BASS_Encode_Stop(encoder);
            });
        }
        private void BurningThread()
        {
            log.Trace(">>>");
            List <string> outFiles = new List <string>();
            bool          bError   = false;

            foreach (DataGridViewRow row in dataGridViewBurn.Rows)
            {
                TrackData track   = bindingList[row.Index];
                string    outFile = String.Format(@"{0}\{1}.wav", tmpBurnDirectory,
                                                  Path.GetFileNameWithoutExtension(track.FullFileName));

                int stream = Bass.BASS_StreamCreateFile(track.FullFileName, 0, 0, BASSFlag.BASS_STREAM_DECODE);
                if (stream == 0)
                {
                    bError = true;
                    log.Error("Error creating stream for {0}.", track.FullFileName);
                    continue;
                }

                // In order to burn a file to CD, it must be stereo and 44kz
                // To make sure that we have that, we create a mixer channel and add our stream to it
                // The mixer will do the resampling
                int mixer = BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_STREAM_DECODE);
                if (mixer == 0)
                {
                    bError = true;
                    log.Error("Error creating mixer for {0}.", track.FullFileName);
                    continue;
                }

                // Now add the stream to the mixer
                BassMix.BASS_Mixer_StreamAddChannel(mixer, stream, 0);

                log.Info("Decoding to WAV: {0}", track.FullFileName);
                BassEnc.BASS_Encode_Start(mixer, outFile, BASSEncode.BASS_ENCODE_PCM, null, IntPtr.Zero);

                long pos        = 0;
                long chanLength = Bass.BASS_ChannelGetLength(stream);

                byte[] encBuffer = new byte[20000]; // our encoding buffer
                while (Bass.BASS_ChannelIsActive(stream) == BASSActive.BASS_ACTIVE_PLAYING)
                {
                    // getting sample data will automatically feed the encoder
                    int len = Bass.BASS_ChannelGetData(mixer, encBuffer, encBuffer.Length);
                    pos = Bass.BASS_ChannelGetPosition(mixer);
                    double percentComplete = pos / (double)chanLength * 100.0;
                    dataGridViewBurn.Rows[row.Index].Cells[0].Value = (int)percentComplete;
                }
                outFiles.Add(outFile);
                dataGridViewBurn.Rows[row.Index].Cells[0].Value = 100;
                BassEnc.BASS_Encode_Stop(mixer);
                Bass.BASS_StreamFree(stream);
                Bass.BASS_StreamFree(mixer);
            }

            burnManager.BurningFailed      += burnManager_BurningFailed;
            burnManager.BurnProgressUpdate += burnManager_BurnProgressUpdate;
            if (!bError && MediaAllowsBurning())
            {
                foreach (DataGridViewRow row in dataGridViewBurn.Rows)
                {
                    dataGridViewBurn.Rows[row.Index].Cells[0].Value = 0;
                }

                BurnResult result = burnManager.BurnAudioCd(outFiles);
                if (result == BurnResult.Successful)
                {
                    log.Info("Burning of Audio CD was successful");
                }
                else
                {
                    log.Error("Burning of Audio CD failed");
                }
            }

            log.Trace("<<<");
        }
        /// <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");
        }
Beispiel #8
0
 public static void BASSEncoderInit(Int32 format, String str)
 {
     try
     {
         string pathwithoutext = String.Format("{0}\\{1}", Properties.Settings.Default.LastExportFolder, Path.GetFileNameWithoutExtension(str));
         string ext;
         string enc;
         string args;
         int    copynum = 1;
         if (format == 1)
         {
             foreach (Process proc in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(Program.OGGEnc)))
             {
                 proc.Kill();
             }
             ext  = "ogg";
             enc  = Program.OGGEnc;
             args = String.Format(Properties.Settings.Default.EncoderOGG, Properties.Settings.Default.OverrideBitrate ? Properties.Settings.Default.Bitrate : 192);
         }
         else if (format == 2)
         {
             foreach (Process proc in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(Program.MP3Enc)))
             {
                 proc.Kill();
             }
             ext  = "mp3";
             enc  = Program.MP3Enc;
             args = String.Format(Properties.Settings.Default.EncoderMP3, Properties.Settings.Default.OverrideBitrate ? Properties.Settings.Default.Bitrate : 192);
         }
         else
         {
             ext  = "wav";
             enc  = null;
             args = "";
         }
         if (File.Exists(String.Format("{0}.{1}", pathwithoutext, ext)))
         {
             string temp;
             do
             {
                 temp = String.Format("{0} ({1} {2})", pathwithoutext, Languages.Parse("CopyText"), copynum);
                 ++copynum;
             } while (File.Exists(String.Format("{0}.{1}", temp, ext)));
             BassEnc.BASS_Encode_Stop(MainWindow.VSTs._VSTiHandle);
             BassEnc.BASS_Encode_Stop(MainWindow.KMCGlobals._recHandle);
             MainWindow.KMCGlobals._Encoder = BassEnc.BASS_Encode_Start((MainWindow.VSTs.VSTInfo[0].isInstrument ? MainWindow.VSTs._VSTiHandle : MainWindow.KMCGlobals._recHandle), EncoderString(enc, temp, ext, args), (Properties.Settings.Default.LoudMaxEnabled ? BASSEncode.BASS_ENCODE_FP_16BIT : BASSEncode.BASS_ENCODE_DEFAULT) | BASSEncode.BASS_ENCODE_AUTOFREE | IsOgg(format) | IsWav(format), null, IntPtr.Zero);
             BASSCheckError();
         }
         else
         {
             BassEnc.BASS_Encode_Stop(MainWindow.VSTs._VSTiHandle);
             BassEnc.BASS_Encode_Stop(MainWindow.KMCGlobals._recHandle);
             MainWindow.KMCGlobals._Encoder = BassEnc.BASS_Encode_Start((MainWindow.VSTs.VSTInfo[0].isInstrument ? MainWindow.VSTs._VSTiHandle : MainWindow.KMCGlobals._recHandle), EncoderString(enc, pathwithoutext, ext, args), (Properties.Settings.Default.LoudMaxEnabled ? BASSEncode.BASS_ENCODE_FP_16BIT : BASSEncode.BASS_ENCODE_DEFAULT) | BASSEncode.BASS_ENCODE_AUTOFREE | IsOgg(format) | IsWav(format), null, IntPtr.Zero);
             BASSCheckError();
         }
     }
     catch (Exception ex)
     {
         BASSCloseStreamException(ex);
     }
 }