<commit_before>// Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Runtime.InteropServices;
using ManagedBass;
using osu.Framework.Allocation;
using osu.Framework.Platform;

namespace osu.Framework.Audio.Sample
{
    /// <summary>
    /// A factory for <see cref="SampleBass"/> objects sharing a common sample ID (and thus concurrent playback).
    /// </summary>
    internal class SampleBassFactory : AudioCollectionManager<AdjustableAudioComponent>
    {
        public int SampleId { get; private set; }

        public override bool IsLoaded => SampleId != 0;

        public double Length { get; private set; }

        private NativeMemoryTracker.NativeMemoryLease memoryLease;

        public SampleBassFactory(byte[] data)
        {
            if (data.Length > 0)
            {
                EnqueueAction(() =>
                {
                    SampleId = loadSample(data);
                    memoryLease = NativeMemoryTracker.AddMemory(this, data.Length);
                });
            }
        }

        private int playbackConcurrency = Sample.DEFAULT_CONCURRENCY;

        public int PlaybackConcurrency
        {
            get => playbackConcurrency;
            set
            {
                playbackConcurrency = value;

                EnqueueAction(() =>
                {
                    if (!IsLoaded)
                        return;

                    // Todo: Broken (SEGV on SampleGetInfo())
                    // var sampleInfo = Bass.SampleGetInfo(SampleId);
                    // sampleInfo.Max = value;
                    // Bass.SampleSetInfo(SampleId, sampleInfo);
                });
            }
        }

        internal override void UpdateDevice(int deviceIndex)
        {
            if (!IsLoaded)
                return;

            // counter-intuitively, this is the correct API to use to migrate a sample to a new device.
            Bass.ChannelSetDevice(SampleId, deviceIndex);
            BassUtils.CheckFaulted(true);
        }

        private int loadSample(byte[] data)
        {
            int handle = getSampleHandle(data);
            Length = Bass.ChannelBytes2Seconds(handle, data.Length) * 1000;
            return handle;
        }

        private int getSampleHandle(byte[] data)
        {
            const BassFlags flags = BassFlags.Default | BassFlags.SampleOverrideLongestPlaying;

            if (RuntimeInfo.SupportsJIT)
                return Bass.SampleLoad(data, 0, data.Length, PlaybackConcurrency, flags);

            using (var handle = new ObjectHandle<byte[]>(data, GCHandleType.Pinned))
                return Bass.SampleLoad(handle.Address, 0, data.Length, PlaybackConcurrency, flags);
        }

        public Sample CreateSample()
        {
            var sample = new SampleBass(this);
            AddItem(sample);
            return sample;
        }

        protected override void Dispose(bool disposing)
        {
            if (IsLoaded)
            {
                Bass.SampleFree(SampleId);
                memoryLease?.Dispose();
            }

            base.Dispose(disposing);
        }
    }
}
<commit_msg>Temporarily change commenting to fix CI error<commit_after>// Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Runtime.InteropServices;
using ManagedBass;
using osu.Framework.Allocation;
using osu.Framework.Platform;

namespace osu.Framework.Audio.Sample
{
    /// <summary>
    /// A factory for <see cref="SampleBass"/> objects sharing a common sample ID (and thus concurrent playback).
    /// </summary>
    internal class SampleBassFactory : AudioCollectionManager<AdjustableAudioComponent>
    {
        public int SampleId { get; private set; }

        public override bool IsLoaded => SampleId != 0;

        public double Length { get; private set; }

        private NativeMemoryTracker.NativeMemoryLease memoryLease;

        public SampleBassFactory(byte[] data)
        {
            if (data.Length > 0)
            {
                EnqueueAction(() =>
                {
                    SampleId = loadSample(data);
                    memoryLease = NativeMemoryTracker.AddMemory(this, data.Length);
                });
            }
        }

        private int playbackConcurrency = Sample.DEFAULT_CONCURRENCY;

        public int PlaybackConcurrency
        {
            get => playbackConcurrency;
            set
            {
                playbackConcurrency = value;

                EnqueueAction(() =>
                {
                    // Todo: Broken (SEGV on SampleGetInfo())
                    // if (!IsLoaded)
                    //     return;
                    //
                    // var sampleInfo = Bass.SampleGetInfo(SampleId);
                    // sampleInfo.Max = value;
                    // Bass.SampleSetInfo(SampleId, sampleInfo);
                });
            }
        }

        internal override void UpdateDevice(int deviceIndex)
        {
            if (!IsLoaded)
                return;

            // counter-intuitively, this is the correct API to use to migrate a sample to a new device.
            Bass.ChannelSetDevice(SampleId, deviceIndex);
            BassUtils.CheckFaulted(true);
        }

        private int loadSample(byte[] data)
        {
            int handle = getSampleHandle(data);
            Length = Bass.ChannelBytes2Seconds(handle, data.Length) * 1000;
            return handle;
        }

        private int getSampleHandle(byte[] data)
        {
            const BassFlags flags = BassFlags.Default | BassFlags.SampleOverrideLongestPlaying;

            if (RuntimeInfo.SupportsJIT)
                return Bass.SampleLoad(data, 0, data.Length, PlaybackConcurrency, flags);

            using (var handle = new ObjectHandle<byte[]>(data, GCHandleType.Pinned))
                return Bass.SampleLoad(handle.Address, 0, data.Length, PlaybackConcurrency, flags);
        }

        public Sample CreateSample()
        {
            var sample = new SampleBass(this);
            AddItem(sample);
            return sample;
        }

        protected override void Dispose(bool disposing)
        {
            if (IsLoaded)
            {
                Bass.SampleFree(SampleId);
                memoryLease?.Dispose();
            }

            base.Dispose(disposing);
        }
    }
}

{'fraction_non_alphanumeric': 0.08496332518337409, 'fraction_numerical': 0.0027506112469437654, 'mean_word_length': 1.6338028169014085, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5036777', 'n_tokens_mistral': 1691, 'n_tokens_neox': 1586, 'n_words': 416}