App-MHFS

 view release on metacpan or  search on metacpan

lib/App/MHFS.pm  view on Meta::CPAN

        my $lockname = "$filename.lock";
        my $bytes = read_file($lockname);
        if(! defined $bytes) {
            return undef;
        }
        return $bytes;
    }

    #sub LOCK_GET_FILESIZE {
    #    my ($filename) = @_;
    #    my $lockedfilesize = LOCK_GET_LOCKDATA($filename);
    #    if(defined $lockedfilesize) {
    #
    #    }
    #}

    sub LOCK_WRITE {
        my ($filename, $lockdata) = @_;
        my $lockname = "$filename.lock";
        if(-e $lockname) {
            return 0;
        }

lib/App/MHFS.pm  view on Meta::CPAN

        if(!$is_flac) {
            $filebase =~ s/\.[^.]+$/.lossy.flac/;
            $request->{'localtrack'}{'basename'} = $filebase;
            my $tlossy = $tmpfileloc . $filebase;
            if(-e $tlossy ) {
                $is_flac = 1;
                $file = $tlossy;

                if(defined LOCK_GET_LOCKDATA($tlossy)) {
                     # unlikely
                    say "SendLocalTrack: lossy flac exists and is locked 503";
                    $request->Send503;
                    return;
                }
            }
            else {
                make_path($tmpfileloc, {chmod => 0755});
                my @cmd = ('ffmpeg', '-i', $file, '-c:a', 'flac', '-sample_fmt', 's16', $tlossy);
                my $buf;
                if(LOCK_WRITE($tlossy)) {
                    $request->{'process'} = MHFS::Process->new(\@cmd, $evp, {

lib/App/MHFS.pm  view on Meta::CPAN

                        UNLOCK_WRITE($tlossy);
                        SendLocalTrack($request,$tlossy);
                    },
                    'STDERR' => sub {
                        my ($terr) = @_;
                        read($terr, $buf, 4096);
                    }});
                }
                else {
                    # unlikely
                    say "SendLocalTrack: lossy flac is locked 503";
                    $request->Send503;
                }

                return;
            }
        }

        # everything should be flac now, grab the track info
        if(!defined($TRACKINFO{$file}))
        {

lib/App/MHFS.pm  view on Meta::CPAN

                SendTrack($request, $outfile);
            },
            'STDERR' => sub {
                my ($terr) = @_;
                my $buf;
                read($terr, $buf, 4096);
            }});
        }
        else {
            # unlikely
            say "SendLocalTrack: sox is locked 503";
            $request->Send503;
        }
        return;
    }


    sub BuildLibraries {
        my ($self) = @_;
        my @wholeLibrary;

share/public_html/static/jsmpeg.min.js  view on Meta::CPAN

var JSMpeg={Player:null,VideoElement:null,BitBuffer:null,Source:{},Demuxer:{},Decoder:{},Renderer:{},AudioOutput:{},Now:function(){return window.performance?window.performance.now()/1e3:Date.now()/1e3},CreateVideoElements:function(){var elements=docu...
src++;y|=sY[src]<<16;src++;y|=sY[src]<<24;src++;dY[dest++]=y}dest+=scan>>2;src+=scan}}}width=this.halfWidth;scan=width-8;H=motionH/2>>1;V=motionV/2>>1;oddH=(motionH/2&1)===1;oddV=(motionV/2&1)===1;src=((this.mbRow<<3)+V)*width+(this.mbCol<<3)+H;dest=...
gl.uniform1i(gl.getUniformLocation(this.program,name),index);return texture};WebGLRenderer.prototype.createProgram=function(vsh,fsh){var gl=this.gl;var program=gl.createProgram();gl.attachShader(program,this.compileShader(gl.VERTEX_SHADER,vsh));gl.at...

share/public_html/static/music_inc/music_drflac_module.cache.js  view on Meta::CPAN

    return new Promise(function(resolve) {
        obj.on(event, function() {
            resolve();
        });
    });
};

class Mutex {
    constructor() {
      this._locking = Promise.resolve();
      this._locked = false;
    }
  
    isLocked() {
      return this._locked;
    }
  
    lock() {
      this._locked = true;
      let unlockNext;
      let willLock = new Promise(resolve => unlockNext = resolve);
      willLock.then(() => this._locked = false);
      let willUnlock = this._locking.then(() => unlockNext);
      this._locking = this._locking.then(() => willLock);
      return willUnlock;
    }
  }

function makeRequest (method, url, start, end, signal) {
return new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest();
    

share/public_html/static/music_inc/music_inc_module.js  view on Meta::CPAN

    Object.defineProperty(window, name, {
        value: value,
        configurable: false,
        writable: false
    });
};

class Mutex {
    constructor() {
      this._locking = Promise.resolve();
      this._locked = false;
    }
  
    isLocked() {
      return this._locked;
    }
  
    lock() {
      this._locked = true;
      let unlockNext;
      let willLock = new Promise(resolve => unlockNext = resolve);
      willLock.then(() => this._locked = false);
      let willUnlock = this._locking.then(() => unlockNext);
      this._locking = this._locking.then(() => willLock);
      return willUnlock;
    }
}

function CreateAudioContext(options) {
    let mycontext = (window.hasWebKit) ? new webkitAudioContext(options) : (typeof AudioContext != "undefined") ? new AudioContext(options) : null;
    GainNode = mycontext.createGain();
    GainNode.connect(mycontext.destination);

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN


/*
Unlocks a spinlock.
*/
MA_API ma_result ma_spinlock_unlock(ma_spinlock* pSpinlock);


/*
Creates a mutex.

A mutex must be created from a valid context. A mutex is initially unlocked.
*/
MA_API ma_result ma_mutex_init(ma_mutex* pMutex);

/*
Deletes a mutex.
*/
MA_API void ma_mutex_uninit(ma_mutex* pMutex);

/*
Locks a mutex with an infinite timeout.

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN

#endif
#if defined(_MSC_VER)
    #define c89atomic_memory_order_relaxed  0
    #define c89atomic_memory_order_consume  1
    #define c89atomic_memory_order_acquire  2
    #define c89atomic_memory_order_release  3
    #define c89atomic_memory_order_acq_rel  4
    #define c89atomic_memory_order_seq_cst  5
    #if _MSC_VER >= 1400
        #include <intrin.h>
        #define c89atomic_exchange_explicit_8( dst, src, order) (c89atomic_uint8 )_InterlockedExchange8 ((volatile char* )dst, (char )src)
        #define c89atomic_exchange_explicit_16(dst, src, order) (c89atomic_uint16)_InterlockedExchange16((volatile short*)dst, (short)src)
        #define c89atomic_exchange_explicit_32(dst, src, order) (c89atomic_uint32)_InterlockedExchange  ((volatile long* )dst, (long )src)
    #if defined(C89ATOMIC_64BIT)
        #define c89atomic_exchange_explicit_64(dst, src, order) (c89atomic_uint64)_InterlockedExchange64((volatile long long*)dst, (long long)src)
    #endif
        #define c89atomic_fetch_add_explicit_8( dst, src, order) (c89atomic_uint8 )_InterlockedExchangeAdd8 ((volatile char* )dst, (char )src)
        #define c89atomic_fetch_add_explicit_16(dst, src, order) (c89atomic_uint16)_InterlockedExchangeAdd16((volatile short*)dst, (short)src)
        #define c89atomic_fetch_add_explicit_32(dst, src, order) (c89atomic_uint32)_InterlockedExchangeAdd  ((volatile long* )dst, (long )src)
    #if defined(C89ATOMIC_64BIT)
        #define c89atomic_fetch_add_explicit_64(dst, src, order) (c89atomic_uint64)_InterlockedExchangeAdd64((volatile long long*)dst, (long long)src)
    #endif
        #define c89atomic_compare_and_swap_8( dst, expected, desired) (c89atomic_uint8 )_InterlockedCompareExchange8 ((volatile char*     )dst, (char     )desired, (char     )expected)
        #define c89atomic_compare_and_swap_16(dst, expected, desired) (c89atomic_uint16)_InterlockedCompareExchange16((volatile short*    )dst, (short    )desired, (short    )expected)
        #define c89atomic_compare_and_swap_32(dst, expected, desired) (c89atomic_uint32)_InterlockedCompareExchange  ((volatile long*     )dst, (long     )desired, (long     )expected)
        #define c89atomic_compare_and_swap_64(dst, expected, desired) (c89atomic_uint64)_InterlockedCompareExchange64((volatile long long*)dst, (long long)desired, (long long)expected)
    #if defined(C89ATOMIC_X64)
        #define c89atomic_thread_fence(order)   __faststorefence()
    #else
        static C89ATOMIC_INLINE void c89atomic_thread_fence(c89atomic_memory_order order)
        {
            volatile c89atomic_uint32 barrier = 0;
            (void)order;
            c89atomic_fetch_add_explicit_32(&barrier, 0, order);
        }
    #endif

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN

            ma_uint32 periodSizeInBytes = ma_get_period_size_in_bytes(pDevice->capture.internalPeriodSizeInFrames, pDevice->capture.internalFormat, pDevice->capture.internalChannels);

            ((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].lpData         = (LPSTR)(pDevice->winmm.pIntermediaryBufferCapture + (periodSizeInBytes*iPeriod));
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwBufferLength = periodSizeInBytes;
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwFlags        = 0L;
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwLoops        = 0L;
            ((MA_PFN_waveInPrepareHeader)pContext->winmm.waveInPrepareHeader)((HWAVEIN)pDevice->winmm.hDeviceCapture, &((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod], sizeof(WAVEHDR));

            /*
            The user data of the WAVEHDR structure is a single flag the controls whether or not it is ready for writing. Consider it to be named "isLocked". A value of 0 means
            it's unlocked and available for writing. A value of 1 means it's locked.
            */
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwUser = 0;
        }
    }
    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        ma_uint32 iPeriod;

        if (pConfig->deviceType == ma_device_type_playback) {
            pDevice->winmm.pWAVEHDRPlayback            = pDevice->winmm._pHeapData;
            pDevice->winmm.pIntermediaryBufferPlayback = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*pDevice->playback.internalPeriods);

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN

            ma_uint32 periodSizeInBytes = ma_get_period_size_in_bytes(pDevice->playback.internalPeriodSizeInFrames, pDevice->playback.internalFormat, pDevice->playback.internalChannels);

            ((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].lpData         = (LPSTR)(pDevice->winmm.pIntermediaryBufferPlayback + (periodSizeInBytes*iPeriod));
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwBufferLength = periodSizeInBytes;
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwFlags        = 0L;
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwLoops        = 0L;
            ((MA_PFN_waveOutPrepareHeader)pContext->winmm.waveOutPrepareHeader)((HWAVEOUT)pDevice->winmm.hDevicePlayback, &((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod], sizeof(WAVEHDR));

            /*
            The user data of the WAVEHDR structure is a single flag the controls whether or not it is ready for writing. Consider it to be named "isLocked". A value of 0 means
            it's unlocked and available for writing. A value of 1 means it's locked.
            */
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwUser = 0;
        }
    }

    return MA_SUCCESS;

on_error:
    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        if (pDevice->winmm.pWAVEHDRCapture != NULL) {

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN

    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        ma_uint32 iPeriod;
        WAVEHDR* pWAVEHDR;

        if (pDevice->winmm.hDevicePlayback == NULL) {
            return MA_INVALID_ARGS;
        }

        /* We need to drain the device. To do this we just loop over each header and if it's locked just wait for the event. */
        pWAVEHDR = (WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback;
        for (iPeriod = 0; iPeriod < pDevice->playback.internalPeriods; iPeriod += 1) {
            if (pWAVEHDR[iPeriod].dwUser == 1) { /* 1 = locked. */
                if (WaitForSingleObject((HANDLE)pDevice->winmm.hEventPlayback, INFINITE) != WAIT_OBJECT_0) {
                    break;  /* An error occurred so just abandon ship and stop the device without draining. */
                }

                pWAVEHDR[iPeriod].dwUser = 0;
            }
        }

        resultMM = ((MA_PFN_waveOutReset)pDevice->pContext->winmm.waveOutReset)((HWAVEOUT)pDevice->winmm.hDevicePlayback);
        if (resultMM != MMSYSERR_NOERROR) {

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN

    if (pFramesWritten != NULL) {
        *pFramesWritten = 0;
    }

    pWAVEHDR = (WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback;

    /* Keep processing as much data as possible. */
    totalFramesWritten = 0;
    while (totalFramesWritten < frameCount) {
        /* If the current header has some space available we need to write part of it. */
        if (pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwUser == 0) { /* 0 = unlocked. */
            /*
            This header has room in it. We copy as much of it as we can. If we end up fully consuming the buffer we need to
            write it out and move on to the next iteration.
            */
            ma_uint32 bpf = ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
            ma_uint32 framesRemainingInHeader = (pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwBufferLength/bpf) - pDevice->winmm.headerFramesConsumedPlayback;

            ma_uint32 framesToCopy = ma_min(framesRemainingInHeader, (frameCount - totalFramesWritten));
            const void* pSrc = ma_offset_ptr(pPCMFrames, totalFramesWritten*bpf);
            void* pDst = ma_offset_ptr(pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].lpData, pDevice->winmm.headerFramesConsumedPlayback*bpf);
            MA_COPY_MEMORY(pDst, pSrc, framesToCopy*bpf);

            pDevice->winmm.headerFramesConsumedPlayback += framesToCopy;
            totalFramesWritten += framesToCopy;

            /* If we've consumed the buffer entirely we need to write it out to the device. */
            if (pDevice->winmm.headerFramesConsumedPlayback == (pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwBufferLength/bpf)) {
                pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwUser = 1;            /* 1 = locked. */
                pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwFlags &= ~WHDR_DONE; /* <-- Need to make sure the WHDR_DONE flag is unset. */

                /* Make sure the event is reset to a non-signaled state to ensure we don't prematurely return from WaitForSingleObject(). */
                ResetEvent((HANDLE)pDevice->winmm.hEventPlayback);

                /* The device will be started here. */
                resultMM = ((MA_PFN_waveOutWrite)pDevice->pContext->winmm.waveOutWrite)((HWAVEOUT)pDevice->winmm.hDevicePlayback, &pWAVEHDR[pDevice->winmm.iNextHeaderPlayback], sizeof(WAVEHDR));
                if (resultMM != MMSYSERR_NOERROR) {
                    result = ma_result_from_MMRESULT(resultMM);
                    ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WinMM] waveOutWrite() failed.", result);

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN

        }

        /* Getting here means there isn't enough room in the buffer and we need to wait for one to become available. */
        if (WaitForSingleObject((HANDLE)pDevice->winmm.hEventPlayback, INFINITE) != WAIT_OBJECT_0) {
            result = MA_ERROR;
            break;
        }

        /* Something happened. If the next buffer has been marked as done we need to reset a bit of state. */
        if ((pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwFlags & WHDR_DONE) != 0) {
            pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwUser = 0;    /* 0 = unlocked (make it available for writing). */
            pDevice->winmm.headerFramesConsumedPlayback = 0;
        }

        /* If the device has been stopped we need to break. */
        if (ma_device__get_state(pDevice) != MA_STATE_STARTED) {
            break;
        }
    }

    if (pFramesWritten != NULL) {

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN

    if (pFramesRead != NULL) {
        *pFramesRead = 0;
    }

    pWAVEHDR = (WAVEHDR*)pDevice->winmm.pWAVEHDRCapture;

    /* Keep processing as much data as possible. */
    totalFramesRead = 0;
    while (totalFramesRead < frameCount) {
        /* If the current header has some space available we need to write part of it. */
        if (pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwUser == 0) { /* 0 = unlocked. */
            /* The buffer is available for reading. If we fully consume it we need to add it back to the buffer. */
            ma_uint32 bpf = ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
            ma_uint32 framesRemainingInHeader = (pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwBufferLength/bpf) - pDevice->winmm.headerFramesConsumedCapture;

            ma_uint32 framesToCopy = ma_min(framesRemainingInHeader, (frameCount - totalFramesRead));
            const void* pSrc = ma_offset_ptr(pWAVEHDR[pDevice->winmm.iNextHeaderCapture].lpData, pDevice->winmm.headerFramesConsumedCapture*bpf);
            void* pDst = ma_offset_ptr(pPCMFrames, totalFramesRead*bpf);
            MA_COPY_MEMORY(pDst, pSrc, framesToCopy*bpf);

            pDevice->winmm.headerFramesConsumedCapture += framesToCopy;
            totalFramesRead += framesToCopy;

            /* If we've consumed the buffer entirely we need to add it back to the device. */
            if (pDevice->winmm.headerFramesConsumedCapture == (pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwBufferLength/bpf)) {
                pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwUser = 1;            /* 1 = locked. */
                pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwFlags &= ~WHDR_DONE; /* <-- Need to make sure the WHDR_DONE flag is unset. */

                /* Make sure the event is reset to a non-signaled state to ensure we don't prematurely return from WaitForSingleObject(). */
                ResetEvent((HANDLE)pDevice->winmm.hEventCapture);

                /* The device will be started here. */
                resultMM = ((MA_PFN_waveInAddBuffer)pDevice->pContext->winmm.waveInAddBuffer)((HWAVEIN)pDevice->winmm.hDeviceCapture, &((LPWAVEHDR)pDevice->winmm.pWAVEHDRCapture)[pDevice->winmm.iNextHeaderCapture], sizeof(WAVEHDR));
                if (resultMM != MMSYSERR_NOERROR) {
                    result = ma_result_from_MMRESULT(resultMM);
                    ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WinMM] waveInAddBuffer() failed.", result);

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN

        }

        /* Getting here means there isn't enough any data left to send to the client which means we need to wait for more. */
        if (WaitForSingleObject((HANDLE)pDevice->winmm.hEventCapture, INFINITE) != WAIT_OBJECT_0) {
            result = MA_ERROR;
            break;
        }

        /* Something happened. If the next buffer has been marked as done we need to reset a bit of state. */
        if ((pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwFlags & WHDR_DONE) != 0) {
            pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwUser = 0;    /* 0 = unlocked (make it available for reading). */
            pDevice->winmm.headerFramesConsumedCapture = 0;
        }

        /* If the device has been stopped we need to break. */
        if (ma_device__get_state(pDevice) != MA_STATE_STARTED) {
            break;
        }
    }

    if (pFramesRead != NULL) {

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN

        /* Make sure the event is reset to a non-signaled state to ensure we don't prematurely return from WaitForSingleObject(). */
        ResetEvent((HANDLE)pDevice->winmm.hEventCapture);

        /* To start the device we attach all of the buffers and then start it. As the buffers are filled with data we will get notifications. */
        for (iPeriod = 0; iPeriod < pDevice->capture.internalPeriods; ++iPeriod) {
            resultMM = ((MA_PFN_waveInAddBuffer)pDevice->pContext->winmm.waveInAddBuffer)((HWAVEIN)pDevice->winmm.hDeviceCapture, &((LPWAVEHDR)pDevice->winmm.pWAVEHDRCapture)[iPeriod], sizeof(WAVEHDR));
            if (resultMM != MMSYSERR_NOERROR) {
                return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WinMM] Failed to attach input buffers to capture device in preparation for capture.", ma_result_from_MMRESULT(resultMM));
            }

            /* Make sure all of the buffers start out locked. We don't want to access them until the backend tells us we can. */
            pWAVEHDR[iPeriod].dwUser = 1;   /* 1 = locked. */
        }

        /* Capture devices need to be explicitly started, unlike playback devices. */
        resultMM = ((MA_PFN_waveInStart)pDevice->pContext->winmm.waveInStart)((HWAVEIN)pDevice->winmm.hDeviceCapture);
        if (resultMM != MMSYSERR_NOERROR) {
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WinMM] Failed to start backend device.", ma_result_from_MMRESULT(resultMM));
        }
    }


share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

need to wait for their input attachments to complete is due to the potential for desyncs between
data sources. If the node was to terminate processing mid way through processing it's inputs,
there's a chance that some of the underlying data sources will have been read, but then others not.
That will then result in a potential desynchronization when detaching and reattaching higher-level
nodes. A possible solution to this is to have an option when detaching to terminate processing
before processing all input attachments which should be fairly simple.

Another compromise, albeit less significant, is locking when attaching and detaching nodes. This
locking is achieved by means of a spinlock in order to reduce memory overhead. A lock is present
for each input bus and output bus. When an output bus is connected to an input bus, both the output
bus and input bus is locked. This locking is specifically for attaching and detaching across
different threads and does not affect `ma_node_graph_read_pcm_frames()` in any way. The locking and
unlocking is mostly self-explanatory, but a slightly less intuitive aspect comes into it when
considering that iterating over attachments must not break as a result of attaching or detaching a
node while iteration is occuring.

Attaching and detaching are both quite simple. When an output bus of a node is attached to an input
bus of another node, it's added to a linked list. Basically, an input bus is a linked list, where
each item in the list is and output bus. We have some intentional (and convenient) restrictions on
what can done with the linked list in order to simplify the implementation. First of all, whenever
something needs to iterate over the list, it must do so in a forward direction. Backwards iteration

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

Unlocks a spinlock.
*/
MA_API ma_result ma_spinlock_unlock(volatile ma_spinlock* pSpinlock);


#ifndef MA_NO_THREADING

/*
Creates a mutex.

A mutex must be created from a valid context. A mutex is initially unlocked.
*/
MA_API ma_result ma_mutex_init(ma_mutex* pMutex);

/*
Deletes a mutex.
*/
MA_API void ma_mutex_uninit(ma_mutex* pMutex);

/*
Locks a mutex with an infinite timeout.

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

                    mov ecx, dword ptr desired + 4
                    lock cmpxchg8b qword ptr [esi]
                    mov resultEAX, eax
                    mov resultEDX, edx
                }
                return ((c89atomic_uint64)resultEDX << 32) | resultEAX;
            }
        #endif
    #else
        #if defined(C89ATOMIC_HAS_8)
            #define c89atomic_compare_and_swap_8( dst, expected, desired) (c89atomic_uint8 )_InterlockedCompareExchange8((volatile char*)dst, (char)desired, (char)expected)
        #endif
        #if defined(C89ATOMIC_HAS_16)
            #define c89atomic_compare_and_swap_16(dst, expected, desired) (c89atomic_uint16)_InterlockedCompareExchange16((volatile short*)dst, (short)desired, (short)expected)
        #endif
        #if defined(C89ATOMIC_HAS_32)
            #define c89atomic_compare_and_swap_32(dst, expected, desired) (c89atomic_uint32)_InterlockedCompareExchange((volatile long*)dst, (long)desired, (long)expected)
        #endif
        #if defined(C89ATOMIC_HAS_64)
            #define c89atomic_compare_and_swap_64(dst, expected, desired) (c89atomic_uint64)_InterlockedCompareExchange64((volatile c89atomic_int64*)dst, (c89atomic_int64)desired, (c89atomic_int64)expected)
        #endif
    #endif
    #if defined(C89ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
        #if defined(C89ATOMIC_HAS_8)
            static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_exchange_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
            {
                c89atomic_uint8 result = 0;
                (void)order;
                __asm {
                    mov ecx, dst

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

                    mov result, eax
                }
                return result;
            }
        #endif
    #else
        #if defined(C89ATOMIC_HAS_8)
            static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_exchange_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
            {
                (void)order;
                return (c89atomic_uint8)_InterlockedExchange8((volatile char*)dst, (char)src);
            }
        #endif
        #if defined(C89ATOMIC_HAS_16)
            static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_exchange_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
            {
                (void)order;
                return (c89atomic_uint16)_InterlockedExchange16((volatile short*)dst, (short)src);
            }
        #endif
        #if defined(C89ATOMIC_HAS_32)
            static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_exchange_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
            {
                (void)order;
                return (c89atomic_uint32)_InterlockedExchange((volatile long*)dst, (long)src);
            }
        #endif
        #if defined(C89ATOMIC_HAS_64) && defined(C89ATOMIC_64BIT)
            static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_exchange_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
            {
                (void)order;
                return (c89atomic_uint64)_InterlockedExchange64((volatile long long*)dst, (long long)src);
            }
        #else
        #endif
    #endif
    #if defined(C89ATOMIC_HAS_64) && !defined(C89ATOMIC_64BIT)
        static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_exchange_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
        {
            c89atomic_uint64 oldValue;
            do {
                oldValue = *dst;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

                    mov result, eax
                }
                return result;
            }
        #endif
    #else
        #if defined(C89ATOMIC_HAS_8)
            static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_fetch_add_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
            {
                (void)order;
                return (c89atomic_uint8)_InterlockedExchangeAdd8((volatile char*)dst, (char)src);
            }
        #endif
        #if defined(C89ATOMIC_HAS_16)
            static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_fetch_add_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
            {
                (void)order;
                return (c89atomic_uint16)_InterlockedExchangeAdd16((volatile short*)dst, (short)src);
            }
        #endif
        #if defined(C89ATOMIC_HAS_32)
            static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_fetch_add_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
            {
                (void)order;
                return (c89atomic_uint32)_InterlockedExchangeAdd((volatile long*)dst, (long)src);
            }
        #endif
        #if defined(C89ATOMIC_HAS_64) && defined(C89ATOMIC_64BIT)
            static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_fetch_add_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
            {
                (void)order;
                return (c89atomic_uint64)_InterlockedExchangeAdd64((volatile long long*)dst, (long long)src);
            }
        #else
        #endif
    #endif
    #if defined(C89ATOMIC_HAS_64) && !defined(C89ATOMIC_64BIT)
        static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_fetch_add_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
        {
            c89atomic_uint64 oldValue;
            c89atomic_uint64 newValue;
            do {

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            ma_uint32 periodSizeInBytes = ma_get_period_size_in_bytes(pDescriptorCapture->periodSizeInFrames, pDescriptorCapture->format, pDescriptorCapture->channels);

            ((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].lpData         = (LPSTR)(pDevice->winmm.pIntermediaryBufferCapture + (periodSizeInBytes*iPeriod));
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwBufferLength = periodSizeInBytes;
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwFlags        = 0L;
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwLoops        = 0L;
            ((MA_PFN_waveInPrepareHeader)pDevice->pContext->winmm.waveInPrepareHeader)((HWAVEIN)pDevice->winmm.hDeviceCapture, &((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod], sizeof(WAVEHDR));

            /*
            The user data of the WAVEHDR structure is a single flag the controls whether or not it is ready for writing. Consider it to be named "isLocked". A value of 0 means
            it's unlocked and available for writing. A value of 1 means it's locked.
            */
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwUser = 0;
        }
    }

    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        ma_uint32 iPeriod;

        if (pConfig->deviceType == ma_device_type_playback) {
            pDevice->winmm.pWAVEHDRPlayback            = pDevice->winmm._pHeapData;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            ma_uint32 periodSizeInBytes = ma_get_period_size_in_bytes(pDescriptorPlayback->periodSizeInFrames, pDescriptorPlayback->format, pDescriptorPlayback->channels);

            ((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].lpData         = (LPSTR)(pDevice->winmm.pIntermediaryBufferPlayback + (periodSizeInBytes*iPeriod));
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwBufferLength = periodSizeInBytes;
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwFlags        = 0L;
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwLoops        = 0L;
            ((MA_PFN_waveOutPrepareHeader)pDevice->pContext->winmm.waveOutPrepareHeader)((HWAVEOUT)pDevice->winmm.hDevicePlayback, &((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod], sizeof(WAVEHDR));

            /*
            The user data of the WAVEHDR structure is a single flag the controls whether or not it is ready for writing. Consider it to be named "isLocked". A value of 0 means
            it's unlocked and available for writing. A value of 1 means it's locked.
            */
            ((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwUser = 0;
        }
    }

    return MA_SUCCESS;

on_error:
    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        if (pDevice->winmm.pWAVEHDRCapture != NULL) {

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        ResetEvent((HANDLE)pDevice->winmm.hEventCapture);

        /* To start the device we attach all of the buffers and then start it. As the buffers are filled with data we will get notifications. */
        for (iPeriod = 0; iPeriod < pDevice->capture.internalPeriods; ++iPeriod) {
            resultMM = ((MA_PFN_waveInAddBuffer)pDevice->pContext->winmm.waveInAddBuffer)((HWAVEIN)pDevice->winmm.hDeviceCapture, &((LPWAVEHDR)pDevice->winmm.pWAVEHDRCapture)[iPeriod], sizeof(WAVEHDR));
            if (resultMM != MMSYSERR_NOERROR) {
                ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WinMM] Failed to attach input buffers to capture device in preparation for capture.");
                return ma_result_from_MMRESULT(resultMM);
            }

            /* Make sure all of the buffers start out locked. We don't want to access them until the backend tells us we can. */
            pWAVEHDR[iPeriod].dwUser = 1;   /* 1 = locked. */
        }

        /* Capture devices need to be explicitly started, unlike playback devices. */
        resultMM = ((MA_PFN_waveInStart)pDevice->pContext->winmm.waveInStart)((HWAVEIN)pDevice->winmm.hDeviceCapture);
        if (resultMM != MMSYSERR_NOERROR) {
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WinMM] Failed to start backend device.");
            return ma_result_from_MMRESULT(resultMM);
        }
    }

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        ma_uint32 iPeriod;
        WAVEHDR* pWAVEHDR;

        if (pDevice->winmm.hDevicePlayback == NULL) {
            return MA_INVALID_ARGS;
        }

        /* We need to drain the device. To do this we just loop over each header and if it's locked just wait for the event. */
        pWAVEHDR = (WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback;
        for (iPeriod = 0; iPeriod < pDevice->playback.internalPeriods; iPeriod += 1) {
            if (pWAVEHDR[iPeriod].dwUser == 1) { /* 1 = locked. */
                if (WaitForSingleObject((HANDLE)pDevice->winmm.hEventPlayback, INFINITE) != WAIT_OBJECT_0) {
                    break;  /* An error occurred so just abandon ship and stop the device without draining. */
                }

                pWAVEHDR[iPeriod].dwUser = 0;
            }
        }

        resultMM = ((MA_PFN_waveOutReset)pDevice->pContext->winmm.waveOutReset)((HWAVEOUT)pDevice->winmm.hDevicePlayback);
        if (resultMM != MMSYSERR_NOERROR) {

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    if (pFramesWritten != NULL) {
        *pFramesWritten = 0;
    }

    pWAVEHDR = (WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback;

    /* Keep processing as much data as possible. */
    totalFramesWritten = 0;
    while (totalFramesWritten < frameCount) {
        /* If the current header has some space available we need to write part of it. */
        if (pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwUser == 0) { /* 0 = unlocked. */
            /*
            This header has room in it. We copy as much of it as we can. If we end up fully consuming the buffer we need to
            write it out and move on to the next iteration.
            */
            ma_uint32 bpf = ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
            ma_uint32 framesRemainingInHeader = (pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwBufferLength/bpf) - pDevice->winmm.headerFramesConsumedPlayback;

            ma_uint32 framesToCopy = ma_min(framesRemainingInHeader, (frameCount - totalFramesWritten));
            const void* pSrc = ma_offset_ptr(pPCMFrames, totalFramesWritten*bpf);
            void* pDst = ma_offset_ptr(pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].lpData, pDevice->winmm.headerFramesConsumedPlayback*bpf);
            MA_COPY_MEMORY(pDst, pSrc, framesToCopy*bpf);

            pDevice->winmm.headerFramesConsumedPlayback += framesToCopy;
            totalFramesWritten += framesToCopy;

            /* If we've consumed the buffer entirely we need to write it out to the device. */
            if (pDevice->winmm.headerFramesConsumedPlayback == (pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwBufferLength/bpf)) {
                pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwUser = 1;            /* 1 = locked. */
                pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwFlags &= ~WHDR_DONE; /* <-- Need to make sure the WHDR_DONE flag is unset. */

                /* Make sure the event is reset to a non-signaled state to ensure we don't prematurely return from WaitForSingleObject(). */
                ResetEvent((HANDLE)pDevice->winmm.hEventPlayback);

                /* The device will be started here. */
                resultMM = ((MA_PFN_waveOutWrite)pDevice->pContext->winmm.waveOutWrite)((HWAVEOUT)pDevice->winmm.hDevicePlayback, &pWAVEHDR[pDevice->winmm.iNextHeaderPlayback], sizeof(WAVEHDR));
                if (resultMM != MMSYSERR_NOERROR) {
                    result = ma_result_from_MMRESULT(resultMM);
                    ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WinMM] waveOutWrite() failed.");

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        }

        /* Getting here means there isn't enough room in the buffer and we need to wait for one to become available. */
        if (WaitForSingleObject((HANDLE)pDevice->winmm.hEventPlayback, INFINITE) != WAIT_OBJECT_0) {
            result = MA_ERROR;
            break;
        }

        /* Something happened. If the next buffer has been marked as done we need to reset a bit of state. */
        if ((pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwFlags & WHDR_DONE) != 0) {
            pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwUser = 0;    /* 0 = unlocked (make it available for writing). */
            pDevice->winmm.headerFramesConsumedPlayback = 0;
        }

        /* If the device has been stopped we need to break. */
        if (ma_device_get_state(pDevice) != ma_device_state_started) {
            break;
        }
    }

    if (pFramesWritten != NULL) {

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    if (pFramesRead != NULL) {
        *pFramesRead = 0;
    }

    pWAVEHDR = (WAVEHDR*)pDevice->winmm.pWAVEHDRCapture;

    /* Keep processing as much data as possible. */
    totalFramesRead = 0;
    while (totalFramesRead < frameCount) {
        /* If the current header has some space available we need to write part of it. */
        if (pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwUser == 0) { /* 0 = unlocked. */
            /* The buffer is available for reading. If we fully consume it we need to add it back to the buffer. */
            ma_uint32 bpf = ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
            ma_uint32 framesRemainingInHeader = (pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwBufferLength/bpf) - pDevice->winmm.headerFramesConsumedCapture;

            ma_uint32 framesToCopy = ma_min(framesRemainingInHeader, (frameCount - totalFramesRead));
            const void* pSrc = ma_offset_ptr(pWAVEHDR[pDevice->winmm.iNextHeaderCapture].lpData, pDevice->winmm.headerFramesConsumedCapture*bpf);
            void* pDst = ma_offset_ptr(pPCMFrames, totalFramesRead*bpf);
            MA_COPY_MEMORY(pDst, pSrc, framesToCopy*bpf);

            pDevice->winmm.headerFramesConsumedCapture += framesToCopy;
            totalFramesRead += framesToCopy;

            /* If we've consumed the buffer entirely we need to add it back to the device. */
            if (pDevice->winmm.headerFramesConsumedCapture == (pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwBufferLength/bpf)) {
                pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwUser = 1;            /* 1 = locked. */
                pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwFlags &= ~WHDR_DONE; /* <-- Need to make sure the WHDR_DONE flag is unset. */

                /* Make sure the event is reset to a non-signaled state to ensure we don't prematurely return from WaitForSingleObject(). */
                ResetEvent((HANDLE)pDevice->winmm.hEventCapture);

                /* The device will be started here. */
                resultMM = ((MA_PFN_waveInAddBuffer)pDevice->pContext->winmm.waveInAddBuffer)((HWAVEIN)pDevice->winmm.hDeviceCapture, &((LPWAVEHDR)pDevice->winmm.pWAVEHDRCapture)[pDevice->winmm.iNextHeaderCapture], sizeof(WAVEHDR));
                if (resultMM != MMSYSERR_NOERROR) {
                    result = ma_result_from_MMRESULT(resultMM);
                    ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WinMM] waveInAddBuffer() failed.");

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        }

        /* Getting here means there isn't enough any data left to send to the client which means we need to wait for more. */
        if (WaitForSingleObject((HANDLE)pDevice->winmm.hEventCapture, INFINITE) != WAIT_OBJECT_0) {
            result = MA_ERROR;
            break;
        }

        /* Something happened. If the next buffer has been marked as done we need to reset a bit of state. */
        if ((pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwFlags & WHDR_DONE) != 0) {
            pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwUser = 0;    /* 0 = unlocked (make it available for reading). */
            pDevice->winmm.headerFramesConsumedCapture = 0;
        }

        /* If the device has been stopped we need to break. */
        if (ma_device_get_state(pDevice) != ma_device_state_started) {
            break;
        }
    }

    if (pFramesRead != NULL) {

share/public_html/static/music_worklet_inprogress/decoder/mhfscl.js  view on Meta::CPAN

    return new Promise(function(resolve) {
        obj.on(event, function() {
            resolve();
        });
    });
};

class Mutex {
    constructor() {
      this._locking = Promise.resolve();
      this._locked = false;
    }
  
    isLocked() {
      return this._locked;
    }
  
    lock() {
      this._locked = true;
      let unlockNext;
      let willLock = new Promise(resolve => unlockNext = resolve);
      willLock.then(() => this._locked = false);
      let willUnlock = this._locking.then(() => unlockNext);
      this._locking = this._locking.then(() => willLock);
      return willUnlock;
    }
  }

function makeRequest (method, url, start, end, signal) {
return new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest();
    

share/public_html/static/music_worklet_inprogress/player/mhfsplayer.js  view on Meta::CPAN

import { MHFSCLDecoder } from '../decoder/mhfscl.js'
import { Float32AudioRingBufferWriter, Float32AudioRingBufferReader } from './AudioWriterReader.js'

let CDIMAGE;

// FIFO mutex
class Mutex {
    constructor() {
      this._locking = Promise.resolve();
      this._locked = false;
    }
  
    isLocked() {
      return this._locked;
    }
  
    lock() {
      this._locked = true;
      let unlockNext;
      let willLock = new Promise(resolve => unlockNext = resolve);
      willLock.then(() => this._locked = false);
      let willUnlock = this._locking.then(() => unlockNext);
      this._locking = this._locking.then(() => willLock);
      return willUnlock;
    }
}

const abortablesleep = (ms, signal) => new Promise(function(resolve) {
    const onTimerDone = function() {
        resolve();
        signal.removeEventListener('abort', stoptimer);



( run in 0.602 second using v1.01-cache-2.11-cpan-49f99fa48dc )