App-MHFS

 view release on metacpan or  search on metacpan

lib/MHFS/Plugin/GetVideo.pm  view on Meta::CPAN

        }, 'ext' => 'm3u8', 'desired_audio' => 'aac',
        'player_html' => $settings->{'DOCUMENTROOT'} . '/static/hls_player.html'},

        'jsmpeg' => {'lock' => 0, 'create_cmd' => sub {
            my ($video) = @_;
            return ['ffmpeg', '-i', $video->{"src_file"}{"filepath"}, '-f', 'mpegts', '-codec:v', 'mpeg1video', '-codec:a', 'mp2', '-b', '0',  $video->{"out_filepath"}];
        }, 'ext' => 'ts', 'player_html' => $settings->{'DOCUMENTROOT'} . '/static/jsmpeg_player.html', 'minsize' => '1048576'},

        'mp4' => {'lock' => 1, 'create_cmd' => sub {
            my ($video) = @_;
            return ['ffmpeg', '-i', $video->{"src_file"}{"filepath"}, '-c:v', 'copy', '-c:a', 'aac', '-f', 'mp4', '-movflags', 'frag_keyframe+empty_moov', $video->{"out_filepath"}];
        }, 'ext' => 'mp4', 'player_html' => $settings->{'DOCUMENTROOT'} . '/static/mp4_player.html', 'minsize' => '1048576'},

        'noconv' => {'lock' => 0, 'ext' => '', 'player_html' => $settings->{'DOCUMENTROOT'} . '/static/noconv_player.html', },

        'mkvinfo' => {'lock' => 0, 'ext' => ''},
        'fmp4' => {'lock' => 0, 'ext' => ''},
    };

    $self->{'routes'} = [
        [

lib/MHFS/Plugin/GetVideo.pm  view on Meta::CPAN

    $request->SendAsJSON($obj);
}

sub get_video_fmp4 {
    my ($request, $fileabspath) = @_;
    my @command = ('ffmpeg', '-loglevel', 'fatal');
    if($request->{'qs'}{'fmp4_time'}) {
        my $formattedtime = hls_audio_formattime($request->{'qs'}{'fmp4_time'});
        push @command, ('-ss', $formattedtime);
    }
    push @command, ('-i', $fileabspath, '-c:v', 'copy', '-c:a', 'aac', '-f', 'mp4', '-movflags', 'frag_keyframe+empty_moov', '-');
    my $evp = $request->{'client'}{'server'}{'evp'};
    my $sent;
    print "$_ " foreach @command;
    $request->{'outheaders'}{'Accept-Ranges'} = 'none';

    # avoid bookkeeping, have ffmpeg output straight to the socket
    $request->{'outheaders'}{'Connection'} = 'close';
    $request->{'outheaders'}{'Content-Type'} = 'video/mp4';
    my $sock = $request->{'client'}{'sock'};
    print  $sock  "HTTP/1.0 200 OK\r\n";

lib/MHFS/Plugin/GetVideo.pm  view on Meta::CPAN

        die "unhandled block type";
    }
    my $trackno = read_and_parse_vint_from_buf(\$data);
    if((!defined $trackno) || (length($data) < 3)) {
        return undef;
    }
    my $rawts = substr($data, 0, 2, '');
    my $rawflag = substr($data, 0, 1, '');

    my $lacing = unpack('C', $rawflag) & 0x6;
    my $framecnt;
    my @sizes;
    # XIPH
    if($lacing == 0x2) {
        $framecnt = unpack('C', substr($data, 0, 1, ''))+1;
        my $firstframessize = 0;
        for(my $i = 0; $i < ($framecnt-1); $i++) {
            my $fsize = 0;
            while(1) {
                my $val = unpack('C', substr($data, 0, 1, ''));
                $fsize += $val;
                last if($val < 255);
            }
            push @sizes, $fsize;
            $firstframessize += $fsize;
        }
        push @sizes, (length($data) - $firstframessize);
    }
    # EBML
    elsif($lacing == 0x6) {
        $framecnt = unpack('C', substr($data, 0, 1, ''))+1;
        my $last = read_and_parse_vint_from_buf(\$data);
        push @sizes, $last;
        my $sum = $last;
        for(my $i = 0; $i < ($framecnt - 2); $i++) {
            my $width;
            my $offset = read_and_parse_vint_from_buf(\$data, \$width);
            # multiple by 2^bitwidth - 1 (with adjusted bitwidth)
            my $desiredbits = (8 * $width) - ($width+1);
            my $subtract = (1 << $desiredbits) - 1;
            my $result = $offset - $subtract;
            $last += $result;
            say "offset $offset width $width factor: " . sprintf("0x%X ", $subtract) . "result $result evaled $last";
            push @sizes, $last;
            $sum += $last;
        }
        my $lastlast = length($data) - $sum;
        say "lastlast $lastlast";
        push @sizes, $lastlast;
    }
    # fixed
    elsif($lacing == 0x4) {
        $framecnt = unpack('C', substr($data, 0, 1, ''))+1;
        my $framesize = length($data) / $framecnt;
        for(my $i = 0; $i < $framecnt; $i++) {
            push @sizes, $framesize;
        }
    }
    # no lacing
    else {
        push @sizes, length($data);
    }

    return {
        'trackno' => $trackno,
        'rawts' => $rawts,
        'rawflag'  => $rawflag,
        'frame_lengths' => \@sizes,
        'data' => $data,
        'ts' => unpack('s>', $rawts)
    };
}

sub telmval {
    my ($track, $stringid) = @_;
    my $constname = "EBMLID_$stringid";
    my $id = __PACKAGE__->$constname;
    return $track->{$id}{'value'}  // $track->{$id}{'data'};

lib/MHFS/Plugin/GetVideo.pm  view on Meta::CPAN

            $track{'outGetSegment'} = $CodecGetSegment{$track{'outfmt'}};

        }
        push @tracks, \%track;
    }
    if(scalar(@tracks) == 0) {
        return undef;
    }

    my $segmentelm = $ebml->{'elements'}[0];
    my %matroska = ('ebml' => $ebml, 'tsscale' => $tsval, 'rawduration' => $scaledduration, 'duration' => $duration, 'tracks' => \@tracks, 'segment_data_start' => {'size' => $segmentelm->{'size'}, 'id' => $segmentelm->{'id'}, 'fileoffset' => tell($eb...
    return \%matroska;
}

sub matroska_get_audio_track {
    my ($matroska) = @_;
    foreach my $track (@{$matroska->{'tracks'}}) {
        my $tt = $track->{&EBMLID_TrackType};
        if(defined $tt && ($tt->{'value'} == 2)) {
            return $track;
        }

lib/MHFS/Plugin/GetVideo.pm  view on Meta::CPAN

                return $block;
            }
        }
        ebml_skip($ebml);
    }
    return undef;
}

sub matroska_ts_to_sample  {
    my ($matroska, $samplerate, $ts) = @_;
    my $curframe = int(($ts * $samplerate / 1000000000)+ 0.5);
    return $curframe;
}

sub matroska_get_gop {
    my ($matroska, $track, $timeinseconds) = @_;
    my $tid = $track->{&EBMLID_TrackNumber}{'value'};

    my $prevcluster;
    my $desiredcluster;
    while(1) {
        my $cluster = matroska_read_cluster_metadata($matroska);

lib/MHFS/Plugin/GetVideo.pm  view on Meta::CPAN

                return undef;
            }
            say "revert cluster";
            $matroska->{'dc'} = $prevcluster;
            ebml_set_cluster($ebml, $matroska->{'dc'});
            next;
        }

        $prevcluster = undef;

        my $blockduration = ((1/24) * scalar(@{$block->{'frame_lengths'}}));
        if($timeinseconds < ($blocktime +  $blockduration)) {
            say 'got GOP at ' . $matroska->{'dc'}{'firstblk'};
            return {'goptime' => $matroska->{'dc'}{'firstblk'}};
            last;
        }
    }

}

sub matroska_seek_track {
    my ($matroska, $track, $pcmFrameIndex) = @_;
    my $tid = $track->{&EBMLID_TrackNumber}{'value'};
    $matroska->{'curframe'} = 0;
    $matroska->{'curpaks'} = [];
    my $samplerate = $track->{&EBMLID_AudioSampleRate};
    my $pcmFrameLen = $track->{'PCMFrameLength'};
    if(!$pcmFrameLen) {
        warn("Unknown codec");
        return undef;
    }
    my $prevcluster;
    my $desiredcluster;
    while(1) {
        my $cluster = matroska_read_cluster_metadata($matroska);
        last if(!$cluster);
        my $curframe = matroska_ts_to_sample($matroska, $samplerate, $cluster->{'ts'});
        #$curframe = int(($curframe/$pcmFrameLen)+0.5)*$pcmFrameLen; # requires revert cluster
        $curframe = ceil_div($curframe, $pcmFrameLen) * $pcmFrameLen;

        # this cluster could contain our frame, save it's info
        if($curframe <= $pcmFrameIndex) {
            $prevcluster = $desiredcluster;
            $desiredcluster = $cluster;
            $desiredcluster->{'frameIndex'} = $curframe;
            if($prevcluster) {
                $prevcluster->{'prevcluster'} = undef;
                $desiredcluster->{'prevcluster'} = $prevcluster;
            }
        }
        # this cluster is at or past the frame, breakout
        if($curframe >= $pcmFrameIndex){
            last;
        }
    }
    say "before dc check";
    return undef if(! $desiredcluster);

    say "cur rawts " . $desiredcluster->{'rawts'};
    say "last rawts " . $desiredcluster->{'prevcluster'}{'rawts'} if($desiredcluster->{'prevcluster'});

    # restore to the the cluster that probably has our audio
    my $ebml = $matroska->{'ebml'};
    ebml_set_cluster($ebml, $desiredcluster);
    $matroska->{'dc'} = $desiredcluster;

    # find a valid track block that includes pcmFrameIndex;
    my $block;
    my $blockframe;
    while(1) {
        $block = matroska_get_track_block($matroska, $tid);
        if($block) {
            $blockframe = matroska_block_calc_frame($matroska, $block, $samplerate, $pcmFrameLen);
            if($blockframe > $pcmFrameIndex) {
                $block = undef;
            }
        }
        if(! $block) {
            if(! $prevcluster) {
                return undef;
            }
            say "revert cluster";
            $matroska->{'dc'} = $prevcluster;
            ebml_set_cluster($ebml, $matroska->{'dc'});
            next;
        }

        $prevcluster = undef;

        my $pcmSampleCount = ($pcmFrameLen * scalar(@{$block->{'frame_lengths'}}));
        if($pcmFrameIndex < ($blockframe +  $pcmSampleCount)) {
            if((($pcmFrameIndex - $blockframe) % $pcmFrameLen) != 0) {
                say "Frame index does not align with block!";
                return undef;
            }
            last;
        }
    }

    # add the data to packs
    my $offset = 0;
    while($blockframe < $pcmFrameIndex) {
        my $len = shift @{$block->{'frame_lengths'}};
        $offset += $len;
        $blockframe += $pcmFrameLen;
    }
    $matroska->{'curframe'} = $pcmFrameIndex;
    foreach my $len (@{$block->{'frame_lengths'}}) {
        push @{$matroska->{'curpaks'}}, substr($block->{'data'}, $offset, $len);
        $offset += $len;
    }
    return 1;
}

sub matroska_calc_block_fullts {
    my ($matroska, $block) = @_;
    say 'clusterts ' . ($matroska->{'dc'}->{'ts'}/1000000000);
    say 'blockts ' . $block->{'ts'};
    my $time = ($matroska->{'dc'}->{'rawts'} + $block->{'ts'}) * $matroska->{'tsscale'};
    return ($time/1000000000);
}

sub matroska_block_calc_frame {
    my ($matroska, $block, $samplerate, $pcmFrameLen) = @_;
    say 'clusterts ' . ($matroska->{'dc'}->{'ts'}/1000000000);
    say 'blockts ' . $block->{'ts'};
    my $time = ($matroska->{'dc'}->{'rawts'} + $block->{'ts'}) * $matroska->{'tsscale'};
    say 'blocktime ' . ($time/1000000000);
    my $calcframe = matroska_ts_to_sample($matroska, $samplerate, $time);
    return round($calcframe/$pcmFrameLen)*$pcmFrameLen;
}

sub matroska_read_track {
    my ($matroska, $track, $pcmFrameIndex, $numsamples, $formatpacket) = @_;
    my $tid = $track->{&EBMLID_TrackNumber}{'value'};
    my $samplerate = $track->{&EBMLID_AudioSampleRate};
    my $pcmFrameLen = $track->{'PCMFrameLength'};
    if(!$pcmFrameLen) {
        warn("Unknown codec");
        return undef;
    }

    # find the cluster that might have the start of our audio
    if($matroska->{'curframe'} != $pcmFrameIndex) {
        say "do seek";
        if(!matroska_seek_track($matroska, $track, $pcmFrameIndex)) {
            return undef;
        }
    }

    my $outdata;
    my $destframe = $matroska->{'curframe'} + $numsamples;

    while(1) {
        # add read audio
        while(@{$matroska->{'curpaks'}}) {
            my $pak = shift @{$matroska->{'curpaks'}};
            $outdata .= $formatpacket->($pak, $samplerate);
            $matroska->{'curframe'} += $pcmFrameLen;
            if($matroska->{'curframe'} == $destframe) {
                say "done, read enough";
                return $outdata;
            }
        }

        # load a block
        my $block = matroska_get_track_block($matroska, $tid);
        if(! $block) {
            if(($matroska->{'ebml'}{'elements'}[0]{'id'} == EBMLID_Segment) && ($matroska->{'ebml'}{'elements'}[0]{'size'} == 0)) {
                say "done, EOF";
            }
            else {
                say "done, Error";
            }
            return $outdata;
        }

        # add the data to paks
        my $offset = 0;
        foreach my $len (@{$block->{'frame_lengths'}}) {
            push @{$matroska->{'curpaks'}}, substr($block->{'data'}, $offset, $len);
            $offset += $len;
        }
    }
}

sub video_on_streams {
    my ($video, $request, $continue) = @_;
    $video->{'audio'} = [];
    $video->{'video'} = [];

lib/MHFS/Plugin/MusicLibrary.pm  view on Meta::CPAN

        }, {
            'mime' => 'audio/wav',
            'size' => $wavsize,
        });

    }
    else {
        if($request->{'qs'}{'action'} && ($request->{'qs'}{'action'} eq 'dl')) {
            $request->{'responseopt'}{'cd_file'} = 'attachment';
        }
        # Send the total pcm frame count for mp3
        elsif(lc(substr($tosend, -4)) eq '.mp3') {
            if(HAS_MHFS_XS) {
                if(! $TRACKINFO{$tosend}) {
                    $TRACKINFO{$tosend} = { 'TOTALSAMPLES' => MHFS::XS::get_totalPCMFrameCount($tosend) };
                    say "mp3 totalPCMFrames: " . $TRACKINFO{$tosend}{'TOTALSAMPLES'};
                }
                $request->{'outheaders'}{'X-MHFS-totalPCMFrameCount'} = $TRACKINFO{$tosend}{'TOTALSAMPLES'};
            }
        }
        $request->SendLocalFile($tosend);

lib/MHFS/Plugin/Youtube.pm  view on Meta::CPAN

    $html .=  '>';
    if($request->{'qs'}{'media'}) {
        $html .= '<input type="hidden" name="media" value="' . $request->{'qs'}{'media'} . '">';
    }
    $html .= '<input type="submit" value="Search">';
    $html .= '</form>';
    return $html;
}
sub ytplayer {
    my ($self, $request) = @_;
    my $html = '<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" /><iframe src="static/250ms_silence.mp3" allow="autoplay" id="audio" style="display:none"></iframe>';
    my $url = 'get_video?fmt=yt&id=' . uri_escape($request->{'qs'}{'id'});
    $url .= '&media=' . uri_escape($request->{'qs'}{'media'}) if($request->{'qs'}{'media'});
    if($request->{'qs'}{'media'} && ($request->{'qs'}{'media'} eq 'music')) {
        $request->{'path'}{'basename'} = 'ytaudio';
        $html .= '<audio controls autoplay src="' . $url . '">Great Browser</audio>';
    }
    else {
        $request->{'path'}{'basename'} = 'yt';
        $html .= '<video controls autoplay src="' . $url . '">Great Browser</video>';
    }

share/public_html/static/hls.js  view on Meta::CPAN

  };

  /**
   * Searches for the Elementary Stream timestamp found in the ID3 data chunk
   * @param {Uint8Array} data - Block of data containing one or more ID3 tags
   * @return {number} - The timestamp
   */


  ID3.getTimeStamp = function getTimeStamp(data) {
    var frames = ID3.getID3Frames(data);
    for (var i = 0; i < frames.length; i++) {
      var frame = frames[i];
      if (ID3.isTimeStampFrame(frame)) {
        return ID3._readTimeStamp(frame);
      }
    }

    return undefined;
  };

  /**
   * Returns true if the ID3 frame is an Elementary Stream timestamp frame
   * @param {ID3 frame} frame
   */


  ID3.isTimeStampFrame = function isTimeStampFrame(frame) {
    return frame && frame.key === 'PRIV' && frame.info === 'com.apple.streaming.transportStreamTimestamp';
  };

  ID3._getFrameData = function _getFrameData(data) {
    /*
    Frame ID       $xx xx xx xx (four characters)
    Size           $xx xx xx xx
    Flags          $xx xx
    */
    var type = String.fromCharCode(data[0], data[1], data[2], data[3]);
    var size = ID3._readSize(data, 4);

    // skip frame id, size, and flags
    var offset = 10;

    return { type: type, size: size, data: data.subarray(offset, offset + size) };
  };

  /**
   * Returns an array of ID3 frames found in all the ID3 tags in the id3Data
   * @param {Uint8Array} id3Data - The ID3 data containing one or more ID3 tags
   * @return {ID3 frame[]} - Array of ID3 frame objects
   */


  ID3.getID3Frames = function getID3Frames(id3Data) {
    var offset = 0;
    var frames = [];

    while (ID3.isHeader(id3Data, offset)) {
      var size = ID3._readSize(id3Data, offset + 6);
      // skip past ID3 header
      offset += 10;
      var end = offset + size;
      // loop through frames in the ID3 tag
      while (offset + 8 < end) {
        var frameData = ID3._getFrameData(id3Data.subarray(offset));
        var frame = ID3._decodeFrame(frameData);
        if (frame) {
          frames.push(frame);
        }

        // skip frame header and frame data
        offset += frameData.size + 10;
      }

      if (ID3.isFooter(id3Data, offset)) {
        offset += 10;
      }
    }

    return frames;
  };

  ID3._decodeFrame = function _decodeFrame(frame) {
    if (frame.type === 'PRIV') {
      return ID3._decodePrivFrame(frame);
    } else if (frame.type[0] === 'T') {
      return ID3._decodeTextFrame(frame);
    } else if (frame.type[0] === 'W') {
      return ID3._decodeURLFrame(frame);
    }

    return undefined;
  };

  ID3._readTimeStamp = function _readTimeStamp(timeStampFrame) {
    if (timeStampFrame.data.byteLength === 8) {
      var data = new Uint8Array(timeStampFrame.data);
      // timestamp is 33 bit expressed as a big-endian eight-octet number,
      // with the upper 31 bits set to zero.

share/public_html/static/hls.js  view on Meta::CPAN

      if (pts33Bit) {
        timestamp += 47721858.84;
      } // 2^32 / 90

      return Math.round(timestamp);
    }

    return undefined;
  };

  ID3._decodePrivFrame = function _decodePrivFrame(frame) {
    /*
    Format: <text string>\0<binary data>
    */
    if (frame.size < 2) {
      return undefined;
    }

    var owner = ID3._utf8ArrayToStr(frame.data, true);
    var privateData = new Uint8Array(frame.data.subarray(owner.length + 1));

    return { key: frame.type, info: owner, data: privateData.buffer };
  };

  ID3._decodeTextFrame = function _decodeTextFrame(frame) {
    if (frame.size < 2) {
      return undefined;
    }

    if (frame.type === 'TXXX') {
      /*
      Format:
      [0]   = {Text Encoding}
      [1-?] = {Description}\0{Value}
      */
      var index = 1;
      var description = ID3._utf8ArrayToStr(frame.data.subarray(index));

      index += description.length + 1;
      var value = ID3._utf8ArrayToStr(frame.data.subarray(index));

      return { key: frame.type, info: description, data: value };
    } else {
      /*
      Format:
      [0]   = {Text Encoding}
      [1-?] = {Value}
      */
      var text = ID3._utf8ArrayToStr(frame.data.subarray(1));
      return { key: frame.type, data: text };
    }
  };

  ID3._decodeURLFrame = function _decodeURLFrame(frame) {
    if (frame.type === 'WXXX') {
      /*
      Format:
      [0]   = {Text Encoding}
      [1-?] = {Description}\0{URL}
      */
      if (frame.size < 2) {
        return undefined;
      }

      var index = 1;
      var description = ID3._utf8ArrayToStr(frame.data.subarray(index));

      index += description.length + 1;
      var value = ID3._utf8ArrayToStr(frame.data.subarray(index));

      return { key: frame.type, info: description, data: value };
    } else {
      /*
      Format:
      [0-?] = {URL}
      */
      var url = ID3._utf8ArrayToStr(frame.data);
      return { key: frame.type, data: url };
    }
  };

  // http://stackoverflow.com/questions/8936984/uint8array-to-string-in-javascript/22373197
  // http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt
  /* utf.js - UTF-8 <=> UTF-16 convertion
   *
   * Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
   * Version: 1.0
   * LastModified: Dec 25 1999

share/public_html/static/hls.js  view on Meta::CPAN

  adtsChanelConfig = (data[offset + 2] & 0x01) << 2;
  // byte 3
  adtsChanelConfig |= (data[offset + 3] & 0xC0) >>> 6;
  logger["b" /* logger */].log('manifest codec:' + audioCodec + ',ADTS data:type:' + adtsObjectType + ',sampleingIndex:' + adtsSampleingIndex + '[' + adtsSampleingRates[adtsSampleingIndex] + 'Hz],channelConfig:' + adtsChanelConfig);
  // firefox: freq less than 24kHz = AAC SBR (HE-AAC)
  if (/firefox/i.test(userAgent)) {
    if (adtsSampleingIndex >= 6) {
      adtsObjectType = 5;
      config = new Array(4);
      // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies
      // there is a factor 2 between frame sample rate and output sample rate
      // multiply frequency by 2 (see table below, equivalent to substract 3)
      adtsExtensionSampleingIndex = adtsSampleingIndex - 3;
    } else {
      adtsObjectType = 2;
      config = new Array(2);
      adtsExtensionSampleingIndex = adtsSampleingIndex;
    }
    // Android : always use AAC
  } else if (userAgent.indexOf('android') !== -1) {
    adtsObjectType = 2;

share/public_html/static/hls.js  view on Meta::CPAN

    adtsExtensionSampleingIndex = adtsSampleingIndex;
  } else {
    /*  for other browsers (Chrome/Vivaldi/Opera ...)
        always force audio type to be HE-AAC SBR, as some browsers do not support audio codec switch properly (like Chrome ...)
    */
    adtsObjectType = 5;
    config = new Array(4);
    // if (manifest codec is HE-AAC or HE-AACv2) OR (manifest codec not specified AND frequency less than 24kHz)
    if (audioCodec && (audioCodec.indexOf('mp4a.40.29') !== -1 || audioCodec.indexOf('mp4a.40.5') !== -1) || !audioCodec && adtsSampleingIndex >= 6) {
      // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies
      // there is a factor 2 between frame sample rate and output sample rate
      // multiply frequency by 2 (see table below, equivalent to substract 3)
      adtsExtensionSampleingIndex = adtsSampleingIndex - 3;
    } else {
      // if (manifest codec is AAC) AND (frequency less than 24kHz AND nb channel is 1) OR (manifest codec not specified and mono audio)
      // Chrome fails to play back with low frequency AAC LC mono when initialized with HE-AAC.  This is not a problem with stereo.
      if (audioCodec && audioCodec.indexOf('mp4a.40.2') !== -1 && (adtsSampleingIndex >= 6 && adtsChanelConfig === 1 || /vivaldi/i.test(userAgent)) || !audioCodec && adtsChanelConfig === 1) {
        adtsObjectType = 2;
        config = new Array(2);
      }
      adtsExtensionSampleingIndex = adtsSampleingIndex;

share/public_html/static/hls.js  view on Meta::CPAN

  // Layer bits (position 14 and 15) in header should be always 0 for ADTS
  // More info https://wiki.multimedia.cx/index.php?title=ADTS
  if (offset + 1 < data.length && isHeaderPattern(data, offset)) {
    return true;
  }

  return false;
}

function adts_probe(data, offset) {
  // same as isHeader but we also check that ADTS frame follows last ADTS frame
  // or end of data is reached
  if (offset + 1 < data.length && isHeaderPattern(data, offset)) {
    // ADTS header Length
    var headerLength = getHeaderLength(data, offset);
    // ADTS frame Length
    var frameLength = headerLength;
    if (offset + 5 < data.length) {
      frameLength = getFullFrameLength(data, offset);
    }

    var newOffset = offset + frameLength;
    if (newOffset === data.length || newOffset + 1 < data.length && isHeaderPattern(data, newOffset)) {
      return true;
    }
  }
  return false;
}

function initTrackConfig(track, observer, data, offset, audioCodec) {
  if (!track.samplerate) {
    var config = getAudioConfig(observer, data, offset, audioCodec);

share/public_html/static/hls.js  view on Meta::CPAN

    track.codec = config.codec;
    track.manifestCodec = config.manifestCodec;
    logger["b" /* logger */].log('parsed codec:' + track.codec + ',rate:' + config.samplerate + ',nb channel:' + config.channelCount);
  }
}

function getFrameDuration(samplerate) {
  return 1024 * 90000 / samplerate;
}

function parseFrameHeader(data, offset, pts, frameIndex, frameDuration) {
  var headerLength = void 0,
      frameLength = void 0,
      stamp = void 0;
  var length = data.length;

  // The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header
  headerLength = getHeaderLength(data, offset);
  // retrieve frame size
  frameLength = getFullFrameLength(data, offset);
  frameLength -= headerLength;

  if (frameLength > 0 && offset + headerLength + frameLength <= length) {
    stamp = pts + frameIndex * frameDuration;
    // logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}/${(stamp/90).toFixed(0)}`);
    return { headerLength: headerLength, frameLength: frameLength, stamp: stamp };
  }

  return undefined;
}

function appendFrame(track, data, offset, pts, frameIndex) {
  var frameDuration = getFrameDuration(track.samplerate);
  var header = parseFrameHeader(data, offset, pts, frameIndex, frameDuration);
  if (header) {
    var stamp = header.stamp;
    var headerLength = header.headerLength;
    var frameLength = header.frameLength;

    // logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}/${(stamp/90).toFixed(0)}`);
    var aacSample = {
      unit: data.subarray(offset + headerLength, offset + headerLength + frameLength),
      pts: stamp,
      dts: stamp
    };

    track.samples.push(aacSample);
    track.len += frameLength;

    return { sample: aacSample, length: frameLength + headerLength };
  }

  return undefined;
}
// EXTERNAL MODULE: ./src/demux/id3.js
var id3 = __webpack_require__(5);

// CONCATENATED MODULE: ./src/demux/aacdemuxer.js
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

share/public_html/static/hls.js  view on Meta::CPAN

  };

  // feed incoming data to the front of the parsing pipeline


  AACDemuxer.prototype.append = function append(data, timeOffset, contiguous, accurateTimeOffset) {
    var track = this._audioTrack;
    var id3Data = id3["a" /* default */].getID3Data(data, 0) || [];
    var timestamp = id3["a" /* default */].getTimeStamp(id3Data);
    var pts = timestamp ? 90 * timestamp : timeOffset * 90000;
    var frameIndex = 0;
    var stamp = pts;
    var length = data.length;
    var offset = id3Data.length;

    var id3Samples = [{ pts: stamp, dts: stamp, data: id3Data }];

    while (offset < length - 1) {
      if (isHeader(data, offset) && offset + 5 < length) {
        initTrackConfig(track, this.observer, data, offset, track.manifestCodec);
        var frame = appendFrame(track, data, offset, pts, frameIndex);
        if (frame) {
          offset += frame.length;
          stamp = frame.sample.pts;
          frameIndex++;
        } else {
          logger["b" /* logger */].log('Unable to parse AAC frame');
          break;
        }
      } else if (id3["a" /* default */].isHeader(data, offset)) {
        id3Data = id3["a" /* default */].getID3Data(data, offset);
        id3Samples.push({ pts: stamp, dts: stamp, data: id3Data });
        offset += id3Data.length;
      } else {
        // nothing found, keep looking
        offset++;
      }

share/public_html/static/hls.js  view on Meta::CPAN

  144, // Layer2
  12 // Layer1
  ]],

  BytesInSlot: [0, // Reserved
  1, // Layer3
  1, // Layer2
  4 // Layer1
  ],

  appendFrame: function appendFrame(track, data, offset, pts, frameIndex) {
    // Using http://www.datavoyage.com/mpgscript/mpeghdr.htm as a reference
    if (offset + 24 > data.length) {
      return undefined;
    }

    var header = this.parseHeader(data, offset);
    if (header && offset + header.frameLength <= data.length) {
      var frameDuration = header.samplesPerFrame * 90000 / header.sampleRate;
      var stamp = pts + frameIndex * frameDuration;
      var sample = { unit: data.subarray(offset, offset + header.frameLength), pts: stamp, dts: stamp };

      track.config = [];
      track.channelCount = header.channelCount;
      track.samplerate = header.sampleRate;
      track.samples.push(sample);
      track.len += header.frameLength;

      return { sample: sample, length: header.frameLength };
    }

    return undefined;
  },

  parseHeader: function parseHeader(data, offset) {
    var headerB = data[offset + 1] >> 3 & 3;
    var headerC = data[offset + 1] >> 1 & 3;
    var headerE = data[offset + 2] >> 4 & 15;
    var headerF = data[offset + 2] >> 2 & 3;
    var headerG = data[offset + 2] >> 1 & 1;
    if (headerB !== 1 && headerE !== 0 && headerE !== 15 && headerF !== 3) {
      var columnInBitrates = headerB === 3 ? 3 - headerC : headerC === 3 ? 3 : 4;
      var bitRate = MpegAudio.BitratesMap[columnInBitrates * 14 + headerE - 1] * 1000;
      var columnInSampleRates = headerB === 3 ? 0 : headerB === 2 ? 1 : 2;
      var sampleRate = MpegAudio.SamplingRateMap[columnInSampleRates * 3 + headerF];
      var channelCount = data[offset + 3] >> 6 === 3 ? 1 : 2; // If bits of channel mode are `11` then it is a single channel (Mono)
      var sampleCoefficient = MpegAudio.SamplesCoefficients[headerB][headerC];
      var bytesInSlot = MpegAudio.BytesInSlot[headerC];
      var samplesPerFrame = sampleCoefficient * 8 * bytesInSlot;
      var frameLength = parseInt(sampleCoefficient * bitRate / sampleRate + headerG, 10) * bytesInSlot;

      return { sampleRate: sampleRate, channelCount: channelCount, frameLength: frameLength, samplesPerFrame: samplesPerFrame };
    }

    return undefined;
  },

  isHeaderPattern: function isHeaderPattern(data, offset) {
    return data[offset] === 0xff && (data[offset + 1] & 0xe0) === 0xe0 && (data[offset + 1] & 0x06) !== 0x00;
  },

  isHeader: function isHeader(data, offset) {
    // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1
    // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III)
    // More info http://www.mp3-tech.org/programmer/frame_header.html
    if (offset + 1 < data.length && this.isHeaderPattern(data, offset)) {
      return true;
    }

    return false;
  },

  probe: function probe(data, offset) {
    // same as isHeader but we also check that MPEG frame follows last MPEG frame
    // or end of data is reached
    if (offset + 1 < data.length && this.isHeaderPattern(data, offset)) {
      // MPEG header Length
      var headerLength = 4;
      // MPEG frame Length
      var header = this.parseHeader(data, offset);
      var frameLength = headerLength;
      if (header && header.frameLength) {
        frameLength = header.frameLength;
      }

      var newOffset = offset + frameLength;
      if (newOffset === data.length || newOffset + 1 < data.length && this.isHeaderPattern(data, newOffset)) {
        return true;
      }
    }
    return false;
  }
};

/* harmony default export */ var mpegaudio = (MpegAudio);
// CONCATENATED MODULE: ./src/demux/exp-golomb.js

share/public_html/static/hls.js  view on Meta::CPAN

        deltaScale = this.readEG();
        nextScale = (lastScale + deltaScale + 256) % 256;
      }
      lastScale = nextScale === 0 ? lastScale : nextScale;
    }
  };

  /**
   * Read a sequence parameter set and return some interesting video
   * properties. A sequence parameter set is the H264 metadata that
   * describes the properties of upcoming video frames.
   * @param data {Uint8Array} the bytes of a sequence parameter set
   * @return {object} an object with configuration parsed from the
   * sequence parameter set, including the dimensions of the
   * associated video frames.
   */


  ExpGolomb.prototype.readSPS = function readSPS() {
    var frameCropLeftOffset = 0,
        frameCropRightOffset = 0,
        frameCropTopOffset = 0,
        frameCropBottomOffset = 0,
        profileIdc = void 0,
        profileCompat = void 0,
        levelIdc = void 0,
        numRefFramesInPicOrderCntCycle = void 0,
        picWidthInMbsMinus1 = void 0,
        picHeightInMapUnitsMinus1 = void 0,
        frameMbsOnlyFlag = void 0,
        scalingListCount = void 0,
        i = void 0,
        readUByte = this.readUByte.bind(this),
        readBits = this.readBits.bind(this),
        readUEG = this.readUEG.bind(this),
        readBoolean = this.readBoolean.bind(this),
        skipBits = this.skipBits.bind(this),
        skipEG = this.skipEG.bind(this),
        skipUEG = this.skipUEG.bind(this),
        skipScalingList = this.skipScalingList.bind(this);

share/public_html/static/hls.js  view on Meta::CPAN

            // seq_scaling_list_present_flag[ i ]
            if (i < 6) {
              skipScalingList(16);
            } else {
              skipScalingList(64);
            }
          }
        }
      }
    }
    skipUEG(); // log2_max_frame_num_minus4
    var picOrderCntType = readUEG();
    if (picOrderCntType === 0) {
      readUEG(); // log2_max_pic_order_cnt_lsb_minus4
    } else if (picOrderCntType === 1) {
      skipBits(1); // delta_pic_order_always_zero_flag
      skipEG(); // offset_for_non_ref_pic
      skipEG(); // offset_for_top_to_bottom_field
      numRefFramesInPicOrderCntCycle = readUEG();
      for (i = 0; i < numRefFramesInPicOrderCntCycle; i++) {
        skipEG();
      } // offset_for_ref_frame[ i ]
    }
    skipUEG(); // max_num_ref_frames
    skipBits(1); // gaps_in_frame_num_value_allowed_flag
    picWidthInMbsMinus1 = readUEG();
    picHeightInMapUnitsMinus1 = readUEG();
    frameMbsOnlyFlag = readBits(1);
    if (frameMbsOnlyFlag === 0) {
      skipBits(1);
    } // mb_adaptive_frame_field_flag

    skipBits(1); // direct_8x8_inference_flag
    if (readBoolean()) {
      // frame_cropping_flag
      frameCropLeftOffset = readUEG();
      frameCropRightOffset = readUEG();
      frameCropTopOffset = readUEG();
      frameCropBottomOffset = readUEG();
    }
    var pixelRatio = [1, 1];
    if (readBoolean()) {
      // vui_parameters_present_flag
      if (readBoolean()) {
        // aspect_ratio_info_present_flag
        var aspectRatioIdc = readUByte();
        switch (aspectRatioIdc) {
          case 1:
            pixelRatio = [1, 1];break;

share/public_html/static/hls.js  view on Meta::CPAN

            pixelRatio = [2, 1];break;
          case 255:
            {
              pixelRatio = [readUByte() << 8 | readUByte(), readUByte() << 8 | readUByte()];
              break;
            }
        }
      }
    }
    return {
      width: Math.ceil((picWidthInMbsMinus1 + 1) * 16 - frameCropLeftOffset * 2 - frameCropRightOffset * 2),
      height: (2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 - (frameMbsOnlyFlag ? 2 : 4) * (frameCropTopOffset + frameCropBottomOffset),
      pixelRatio: pixelRatio
    };
  };

  ExpGolomb.prototype.readSliceType = function readSliceType() {
    // skip NALu type
    this.readUByte();
    // discard first_mb_in_slice
    this.readUEG();
    // return slice_type

share/public_html/static/hls.js  view on Meta::CPAN

        // payload size : remove PES header + PES extension
        pesLen -= pesHdrLen + 3;
      }
      return { data: pesData, pts: pesPts, dts: pesDts, len: pesLen };
    } else {
      return null;
    }
  };

  TSDemuxer.prototype.pushAccesUnit = function pushAccesUnit(avcSample, avcTrack) {
    if (avcSample.units.length && avcSample.frame) {
      var samples = avcTrack.samples;
      var nbSamples = samples.length;
      // only push AVC sample if starting with a keyframe is not mandatory OR
      //    if keyframe already found in this fragment OR
      //       keyframe found in last fragment (track.sps) AND
      //          samples already appended (we already found a keyframe in this fragment) OR fragment is contiguous
      if (!this.config.forceKeyFrameOnDiscontinuity || avcSample.key === true || avcTrack.sps && (nbSamples || this.contiguous)) {
        avcSample.id = nbSamples;
        samples.push(avcSample);
      } else {
        // dropped samples, track it
        avcTrack.dropped++;
      }
    }
    if (avcSample.debug.length) {
      logger["b" /* logger */].log(avcSample.pts + '/' + avcSample.dts + ':' + avcSample.debug);

share/public_html/static/hls.js  view on Meta::CPAN

        case 1:
          push = true;
          if (!avcSample) {
            avcSample = _this.avcSample = createAVCSample(true, pes.pts, pes.dts, '');
          }

          if (debug) {
            avcSample.debug += 'NDR ';
          }

          avcSample.frame = true;
          var data = unit.data;
          // only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)
          if (spsfound && data.length > 4) {
            // retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR
            var sliceType = new exp_golomb(data).readSliceType();
            // 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice
            // SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.
            // An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.
            // I slice: A slice that is not an SI slice that is decoded using intra prediction only.
            // if (sliceType === 2 || sliceType === 7) {
            if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) {
              avcSample.key = true;
            }
          }

share/public_html/static/hls.js  view on Meta::CPAN

          // handle PES not starting with AUD
          if (!avcSample) {
            avcSample = _this.avcSample = createAVCSample(true, pes.pts, pes.dts, '');
          }

          if (debug) {
            avcSample.debug += 'IDR ';
          }

          avcSample.key = true;
          avcSample.frame = true;
          break;
        // SEI
        case 6:
          push = true;
          if (debug && avcSample) {
            avcSample.debug += 'SEI ';
          }

          expGolombDecoder = new exp_golomb(_this.discardEPB(unit.data));

          // skip frameType
          expGolombDecoder.readUByte();

          var payloadType = 0;
          var payloadSize = 0;
          var endOfCaptions = false;
          var b = 0;

          while (!endOfCaptions && expGolombDecoder.bytesAvailable > 1) {
            payloadType = 0;
            do {

share/public_html/static/hls.js  view on Meta::CPAN

    return newData;
  };

  TSDemuxer.prototype._parseAACPES = function _parseAACPES(pes) {
    var track = this._audioTrack,
        data = pes.data,
        pts = pes.pts,
        startOffset = 0,
        aacOverFlow = this.aacOverFlow,
        aacLastPTS = this.aacLastPTS,
        frameDuration = void 0,
        frameIndex = void 0,
        offset = void 0,
        stamp = void 0,
        len = void 0;
    if (aacOverFlow) {
      var tmp = new Uint8Array(aacOverFlow.byteLength + data.byteLength);
      tmp.set(aacOverFlow, 0);
      tmp.set(data, aacOverFlow.byteLength);
      // logger.log(`AAC: append overflowing ${aacOverFlow.byteLength} bytes to beginning of new PES`);
      data = tmp;
    }

share/public_html/static/hls.js  view on Meta::CPAN

        fatal = true;
      }
      logger["b" /* logger */].warn('parsing error:' + reason);
      this.observer.trigger(events["a" /* default */].ERROR, { type: errors["b" /* ErrorTypes */].MEDIA_ERROR, details: errors["a" /* ErrorDetails */].FRAG_PARSING_ERROR, fatal: fatal, reason: reason });
      if (fatal) {
        return;
      }
    }

    initTrackConfig(track, this.observer, data, offset, this.audioCodec);
    frameIndex = 0;
    frameDuration = getFrameDuration(track.samplerate);

    // if last AAC frame is overflowing, we should ensure timestamps are contiguous:
    // first sample PTS should be equal to last sample PTS + frameDuration
    if (aacOverFlow && aacLastPTS) {
      var newPTS = aacLastPTS + frameDuration;
      if (Math.abs(newPTS - pts) > 1) {
        logger["b" /* logger */].log('AAC: align PTS for overlapping frames by ' + Math.round((newPTS - pts) / 90));
        pts = newPTS;
      }
    }

    // scan for aac samples
    while (offset < len) {
      if (isHeader(data, offset) && offset + 5 < len) {
        var frame = appendFrame(track, data, offset, pts, frameIndex);
        if (frame) {
          // logger.log(`${Math.round(frame.sample.pts)} : AAC`);
          offset += frame.length;
          stamp = frame.sample.pts;
          frameIndex++;
        } else {
          // logger.log('Unable to parse AAC frame');
          break;
        }
      } else {
        // nothing found, keep looking
        offset++;
      }
    }

    if (offset < len) {
      aacOverFlow = data.subarray(offset, len);

share/public_html/static/hls.js  view on Meta::CPAN

      aacOverFlow = null;
    }

    this.aacOverFlow = aacOverFlow;
    this.aacLastPTS = stamp;
  };

  TSDemuxer.prototype._parseMPEGPES = function _parseMPEGPES(pes) {
    var data = pes.data;
    var length = data.length;
    var frameIndex = 0;
    var offset = 0;
    var pts = pes.pts;

    while (offset < length) {
      if (mpegaudio.isHeader(data, offset)) {
        var frame = mpegaudio.appendFrame(this._audioTrack, data, offset, pts, frameIndex);
        if (frame) {
          offset += frame.length;
          frameIndex++;
        } else {
          // logger.log('Unable to parse Mpeg audio frame');
          break;
        }
      } else {
        // nothing found, keep looking
        offset++;
      }
    }
  };

  TSDemuxer.prototype._parseID3PES = function _parseID3PES(pes) {

share/public_html/static/hls.js  view on Meta::CPAN

  MP3Demuxer.prototype.resetTimeStamp = function resetTimeStamp() {};

  MP3Demuxer.probe = function probe(data) {
    // check if data contains ID3 timestamp and MPEG sync word
    var offset = void 0,
        length = void 0;
    var id3Data = id3["a" /* default */].getID3Data(data, 0);
    if (id3Data && id3["a" /* default */].getTimeStamp(id3Data) !== undefined) {
      // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1
      // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III)
      // More info http://www.mp3-tech.org/programmer/frame_header.html
      for (offset = id3Data.length, length = Math.min(data.length - 1, offset + 100); offset < length; offset++) {
        if (mpegaudio.probe(data, offset)) {
          logger["b" /* logger */].log('MPEG Audio sync word found !');
          return true;
        }
      }
    }
    return false;
  };

  // feed incoming data to the front of the parsing pipeline


  MP3Demuxer.prototype.append = function append(data, timeOffset, contiguous, accurateTimeOffset) {
    var id3Data = id3["a" /* default */].getID3Data(data, 0);
    var timestamp = id3["a" /* default */].getTimeStamp(id3Data);
    var pts = timestamp ? 90 * timestamp : timeOffset * 90000;
    var offset = id3Data.length;
    var length = data.length;
    var frameIndex = 0,
        stamp = 0;
    var track = this._audioTrack;

    var id3Samples = [{ pts: pts, dts: pts, data: id3Data }];

    while (offset < length) {
      if (mpegaudio.isHeader(data, offset)) {
        var frame = mpegaudio.appendFrame(track, data, offset, pts, frameIndex);
        if (frame) {
          offset += frame.length;
          stamp = frame.sample.pts;
          frameIndex++;
        } else {
          // logger.log('Unable to parse Mpeg audio frame');
          break;
        }
      } else if (id3["a" /* default */].isHeader(data, offset)) {
        id3Data = id3["a" /* default */].getID3Data(data, offset);
        id3Samples.push({ pts: stamp, dts: stamp, data: id3Data });
        offset += id3Data.length;
      } else {
        // nothing found, keep looking
        offset++;
      }

share/public_html/static/hls.js  view on Meta::CPAN

    0x00, 0x00, 0x00, // reserved
    0x00, 0x01, // data_reference_index
    0x00, 0x00, // pre_defined
    0x00, 0x00, // reserved
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined
    width >> 8 & 0xFF, width & 0xff, // width
    height >> 8 & 0xFF, height & 0xff, // height
    0x00, 0x48, 0x00, 0x00, // horizresolution
    0x00, 0x48, 0x00, 0x00, // vertresolution
    0x00, 0x00, 0x00, 0x00, // reserved
    0x00, 0x01, // frame_count
    0x12, 0x64, 0x61, 0x69, 0x6C, // dailymotion/hls.js
    0x79, 0x6D, 0x6F, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x68, 0x6C, 0x73, 0x2E, 0x6A, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // compressorname
    0x00, 0x18, // depth = 24
    0x11, 0x11]), // pre_defined = -1
    avcc, MP4.box(MP4.types.btrt, new Uint8Array([0x00, 0x1c, 0x9c, 0x80, // bufferSizeDB
    0x00, 0x2d, 0xc6, 0xc0, // maxBitrate
    0x00, 0x2d, 0xc6, 0xc0])), // avgBitrate
    MP4.box(MP4.types.pasp, new Uint8Array([hSpacing >> 24, // hSpacing
    hSpacing >> 16 & 0xFF, hSpacing >> 8 & 0xFF, hSpacing & 0xFF, vSpacing >> 24, // vSpacing
    vSpacing >> 16 & 0xFF, vSpacing >> 8 & 0xFF, vSpacing & 0xFF])));

share/public_html/static/hls.js  view on Meta::CPAN

        computePTSDTS = this._initPTS === undefined,
        initPTS = void 0,
        initDTS = void 0;

    if (computePTSDTS) {
      initPTS = initDTS = Infinity;
    }

    if (audioTrack.config && audioSamples.length) {
      // let's use audio sampling rate as MP4 time scale.
      // rationale is that there is a integer nb of audio frames per audio sample (1024 for AAC)
      // using audio sampling rate here helps having an integer MP4 frame duration
      // this avoids potential rounding issue and AV sync issue
      audioTrack.timescale = audioTrack.samplerate;
      logger["b" /* logger */].log('audio sampling rate : ' + audioTrack.samplerate);
      if (!audioTrack.isAAC) {
        if (typeSupported.mpeg) {
          // Chrome and Safari
          container = 'audio/mpeg';
          audioTrack.codec = '';
        } else if (typeSupported.mp3) {
          // Firefox

share/public_html/static/hls.js  view on Meta::CPAN

        }
      };
      if (computePTSDTS) {
        // remember first PTS of this demuxing context. for audio, PTS = DTS
        initPTS = initDTS = audioSamples[0].pts - audioTrack.inputTimeScale * timeOffset;
      }
    }

    if (videoTrack.sps && videoTrack.pps && videoSamples.length) {
      // let's use input time scale as MP4 video timescale
      // we use input time scale straight away to avoid rounding issues on frame duration / cts computation
      var inputTimeScale = videoTrack.inputTimeScale;
      videoTrack.timescale = inputTimeScale;
      tracks.video = {
        container: 'video/mp4',
        codec: videoTrack.codec,
        initSegment: mp4_generator.initSegment([videoTrack]),
        metadata: {
          width: videoTrack.width,
          height: videoTrack.height
        }

share/public_html/static/hls.js  view on Meta::CPAN

        if (_i2 < nbSamples - 1) {
          mp4SampleDuration = inputSamples[_i2 + 1].dts - avcSample.dts;
        } else {
          var config = this.config,
              lastFrameDuration = avcSample.dts - inputSamples[_i2 > 0 ? _i2 - 1 : _i2].dts;
          if (config.stretchShortVideoTrack) {
            // In some cases, a segment's audio track duration may exceed the video track duration.
            // Since we've already remuxed audio, and we know how long the audio track is, we look to
            // see if the delta to the next segment is longer than maxBufferHole.
            // If so, playback would potentially get stuck, so we artificially inflate
            // the duration of the last frame to minimize any potential gap between segments.
            var maxBufferHole = config.maxBufferHole,
                gapTolerance = Math.floor(maxBufferHole * timeScale),
                deltaToFrameEnd = (audioTrackLength ? firstPTS + audioTrackLength * timeScale : this.nextAudioPts) - avcSample.pts;
            if (deltaToFrameEnd > gapTolerance) {
              // We subtract lastFrameDuration from deltaToFrameEnd to try to prevent any video
              // frame overlap. maxBufferHole should be >> lastFrameDuration anyway.
              mp4SampleDuration = deltaToFrameEnd - lastFrameDuration;
              if (mp4SampleDuration < 0) {
                mp4SampleDuration = lastFrameDuration;
              }

              logger["b" /* logger */].log('It is approximately ' + deltaToFrameEnd / 90 + ' ms to the next segment; using duration ' + mp4SampleDuration / 90 + ' ms for the last video frame.');
            } else {
              mp4SampleDuration = lastFrameDuration;
            }
          } else {
            mp4SampleDuration = lastFrameDuration;
          }
        }
        compositionTimeOffset = Math.round(avcSample.pts - avcSample.dts);
      } else {
        compositionTimeOffset = Math.max(0, mp4SampleDuration * Math.round((avcSample.pts - avcSample.dts) / mp4SampleDuration));

share/public_html/static/hls.js  view on Meta::CPAN

        firstPTS = void 0,
        lastPTS = void 0,
        inputSamples = track.samples,
        outputSamples = [],
        nextAudioPts = this.nextAudioPts;

    // for audio samples, also consider consecutive fragments as being contiguous (even if a level switch occurs),
    // for sake of clarity:
    // consecutive fragments are frags with
    //  - less than 100ms gaps between new time offset (if accurate) and next expected PTS OR
    //  - less than 20 audio frames distance
    // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1)
    // this helps ensuring audio continuity
    // and this also avoids audio glitches/cut when switching quality, or reporting wrong duration on first audio frame
    contiguous |= inputSamples.length && nextAudioPts && (accurateTimeOffset && Math.abs(timeOffset - nextAudioPts / inputTimeScale) < 0.1 || Math.abs(inputSamples[0].pts - nextAudioPts - initDTS) < 20 * inputSampleDuration);

    // compute normalized PTS
    inputSamples.forEach(function (sample) {
      sample.pts = sample.dts = ptsNormalize(sample.pts - initDTS, timeOffset * inputTimeScale);
    });

    // filter out sample with negative PTS that are not playable anyway
    // if we don't remove these negative samples, they will shift all audio samples forward.
    // leading to audio overlap between current / next fragment

share/public_html/static/hls.js  view on Meta::CPAN

    if (!contiguous) {
      if (!accurateTimeOffset) {
        // if frag are mot contiguous and if we cant trust time offset, let's use first sample PTS as next audio PTS
        nextAudioPts = inputSamples[0].pts;
      } else {
        // if timeOffset is accurate, let's use it as predicted next audio PTS
        nextAudioPts = timeOffset * inputTimeScale;
      }
    }

    // If the audio track is missing samples, the frames seem to get "left-shifted" within the
    // resulting mp4 segment, causing sync issues and leaving gaps at the end of the audio segment.
    // In an effort to prevent this from happening, we inject frames here where there are gaps.
    // When possible, we inject a silent frame; when that's not possible, we duplicate the last
    // frame.

    if (track.isAAC) {
      var maxAudioFramesDrift = this.config.maxAudioFramesDrift;
      for (var i = 0, nextPts = nextAudioPts; i < inputSamples.length;) {
        // First, let's see how far off this frame is from where we expect it to be
        var sample = inputSamples[i],
            delta;
        var pts = sample.pts;
        delta = pts - nextPts;

        var duration = Math.abs(1000 * delta / inputTimeScale);

        // If we're overlapping by more than a duration, drop this sample
        if (delta <= -maxAudioFramesDrift * inputSampleDuration) {
          logger["b" /* logger */].warn('Dropping 1 audio frame @ ' + (nextPts / inputTimeScale).toFixed(3) + 's due to ' + Math.round(duration) + ' ms overlap.');
          inputSamples.splice(i, 1);
          track.len -= sample.unit.length;
          // Don't touch nextPtsNorm or i
        } // eslint-disable-line brace-style

        // Insert missing frames if:
        // 1: We're more than maxAudioFramesDrift frame away
        // 2: Not more than MAX_SILENT_FRAME_DURATION away
        // 3: currentTime (aka nextPtsNorm) is not 0
        else if (delta >= maxAudioFramesDrift * inputSampleDuration && duration < MAX_SILENT_FRAME_DURATION && nextPts) {
            var missing = Math.round(delta / inputSampleDuration);
            logger["b" /* logger */].warn('Injecting ' + missing + ' audio frame @ ' + (nextPts / inputTimeScale).toFixed(3) + 's due to ' + Math.round(1000 * delta / inputTimeScale) + ' ms gap.');
            for (var j = 0; j < missing; j++) {
              var newStamp = Math.max(nextPts, 0);
              fillFrame = aac_helper.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
              if (!fillFrame) {
                logger["b" /* logger */].log('Unable to get silent frame for given audio codec; duplicating last frame instead.');
                fillFrame = sample.unit.subarray();
              }
              inputSamples.splice(i, 0, { unit: fillFrame, pts: newStamp, dts: newStamp });
              track.len += fillFrame.length;
              nextPts += inputSampleDuration;
              i++;
            }

            // Adjust sample to next expected pts
            sample.pts = sample.dts = nextPts;
            nextPts += inputSampleDuration;
            i++;
          } else {
            // Otherwise, just adjust pts
            if (Math.abs(delta) > 0.1 * inputSampleDuration) {
              // logger.log(`Invalid frame delta ${Math.round(delta + inputSampleDuration)} at PTS ${Math.round(pts / 90)} (should be ${Math.round(inputSampleDuration)}).`);
            }
            sample.pts = sample.dts = nextPts;
            nextPts += inputSampleDuration;
            i++;
          }
      }
    }

    for (var _j2 = 0, _nbSamples = inputSamples.length; _j2 < _nbSamples; _j2++) {
      var audioSample = inputSamples[_j2];

share/public_html/static/hls.js  view on Meta::CPAN

              numMissingFrames = Math.round((_pts - nextAudioPts) / inputSampleDuration);
              logger["b" /* logger */].log(_delta + ' ms hole between AAC samples detected,filling it');
              if (numMissingFrames > 0) {
                fillFrame = aac_helper.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
                if (!fillFrame) {
                  fillFrame = unit.subarray();
                }

                track.len += numMissingFrames * fillFrame.length;
              }
              // if we have frame overlap, overlapping for more than half a frame duraion
            } else if (_delta < -12) {
              // drop overlapping audio frames... browser will deal with it
              logger["b" /* logger */].log('drop overlapping AAC sample, expected/parsed/delta:' + (nextAudioPts / inputTimeScale).toFixed(3) + 's/' + (_pts / inputTimeScale).toFixed(3) + 's/' + -_delta + 'ms');
              track.len -= unit.byteLength;
              continue;
            }
            // set PTS/DTS to expected PTS/DTS
            _pts = nextAudioPts;
          }
        }
        // remember first PTS of our audioSamples
        firstPTS = _pts;

share/public_html/static/hls.js  view on Meta::CPAN

            view.setUint32(0, mdatSize);
            mdat.set(mp4_generator.types.mdat, 4);
          }
        } else {
          // no audio samples
          return;
        }
        for (var _i3 = 0; _i3 < numMissingFrames; _i3++) {
          fillFrame = aac_helper.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
          if (!fillFrame) {
            logger["b" /* logger */].log('Unable to get silent frame for given audio codec; duplicating this frame instead.');
            fillFrame = unit.subarray();
          }
          mdat.set(fillFrame, offset);
          offset += fillFrame.byteLength;
          mp4Sample = {
            size: fillFrame.byteLength,
            cts: 0,
            duration: 1024,
            flags: {
              isLeading: 0,

share/public_html/static/hls.js  view on Meta::CPAN

        scaleFactor = inputTimeScale / mp4timeScale,
        nextAudioPts = this.nextAudioPts,


    // sync with video's timestamp
    startDTS = (nextAudioPts !== undefined ? nextAudioPts : videoData.startDTS * inputTimeScale) + this._initDTS,
        endDTS = videoData.endDTS * inputTimeScale + this._initDTS,

    // one sample's duration value
    sampleDuration = 1024,
        frameDuration = scaleFactor * sampleDuration,


    // samples count of this segment's duration
    nbSamples = Math.ceil((endDTS - startDTS) / frameDuration),


    // silent frame
    silentFrame = aac_helper.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);

    logger["b" /* logger */].warn('remux empty Audio');
    // Can't remux if we can't generate a silent frame...
    if (!silentFrame) {
      logger["b" /* logger */].trace('Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec!');
      return;
    }

    var samples = [];
    for (var i = 0; i < nbSamples; i++) {
      var stamp = startDTS + i * frameDuration;
      samples.push({ unit: silentFrame, pts: stamp, dts: stamp });
      track.len += silentFrame.length;
    }
    track.samples = samples;

    this.remuxAudio(track, timeOffset, contiguous);
  };

  MP4Remuxer.prototype.remuxID3 = function remuxID3(track, timeOffset) {
    var length = track.samples.length,

share/public_html/static/hls.js  view on Meta::CPAN

    if (bufferedFrags.length === 0) {
      return null;
    } else {
      // https://github.com/video-dev/hls.js/pull/1545#discussion_r166229566
      var bufferedFragKey = bufferedFrags.pop();
      return fragments[bufferedFragKey].body;
    }
  };

  /**
   * Partial fragments effected by coded frame eviction will be removed
   * The browser will unload parts of the buffer to free up memory for new buffer data
   * Fragments will need to be reloaded when the buffer is freed up, removing partial fragments will allow them to reload(since there might be parts that are still playable)
   * @param {String} elementaryStream The elementaryStream of media this is (eg. video/audio)
   * @param {TimeRanges} timeRange TimeRange object from a sourceBuffer
   */


  FragmentTracker.prototype.detectEvictedFragments = function detectEvictedFragments(elementaryStream, timeRange) {
    var _this2 = this;

share/public_html/static/hls.js  view on Meta::CPAN

      var curSNIdx = frag.sn - levelDetails.startSN;
      var sameLevel = fragPrevious && frag.level === fragPrevious.level;
      var prevFrag = fragments[curSNIdx - 1];
      var nextFrag = fragments[curSNIdx + 1];
      // logger.log('find SN matching with pos:' +  bufferEnd + ':' + frag.sn);
      if (fragPrevious && frag.sn === fragPrevious.sn) {
        if (sameLevel && !frag.backtracked) {
          if (frag.sn < levelDetails.endSN) {
            var deltaPTS = fragPrevious.deltaPTS;
            // if there is a significant delta between audio and video, larger than max allowed hole,
            // and if previous remuxed fragment did not start with a keyframe. (fragPrevious.dropped)
            // let's try to load previous fragment again to get last keyframe
            // then we will reload again current fragment (that way we should be able to fill the buffer hole ...)
            if (deltaPTS && deltaPTS > config.maxBufferHole && fragPrevious.dropped && curSNIdx) {
              frag = prevFrag;
              logger["b" /* logger */].warn('SN just loaded, with large PTS gap between audio and video, maybe frag is not starting with a keyframe ? load previous one to try to overcome this');
            } else {
              frag = nextFrag;
              logger["b" /* logger */].log('SN just loaded, load next one: ' + frag.sn);
            }
          } else {
            frag = null;
          }
        } else if (frag.backtracked) {
          // Only backtrack a max of 1 consecutive fragment to prevent sliding back too far when little or no frags start with keyframes
          if (nextFrag && nextFrag.backtracked) {
            logger["b" /* logger */].warn('Already backtracked from fragment ' + nextFrag.sn + ', will not backtrack to fragment ' + frag.sn + '. Loading fragment ' + nextFrag.sn);
            frag = nextFrag;
          } else {
            // If a fragment has dropped frames and it's in a same level/sequence, load the previous fragment to try and find the keyframe
            // Reset the dropped count now since it won't be reset until we parse the fragment again, which prevents infinite backtracking on the same segment
            logger["b" /* logger */].warn('Loaded fragment with dropped frames, backtracking 1 segment to find a keyframe');
            frag.dropped = 0;
            if (prevFrag) {
              frag = prevFrag;
              frag.backtracked = true;
            } else if (curSNIdx) {
              // can't backtrack on very first fragment
              frag = null;
            }
          }
        }

share/public_html/static/hls.js  view on Meta::CPAN

        wrong position after a media decode error
      */
      if (currentTime > this.lastCurrentTime) {
        this.lastCurrentTime = currentTime;
      }

      if (BufferHelper.isBuffered(video, currentTime)) {
        fragPlayingCurrent = this.getBufferedFrag(currentTime);
      } else if (BufferHelper.isBuffered(video, currentTime + 0.1)) {
        /* ensure that FRAG_CHANGED event is triggered at startup,
          when first video frame is displayed and playback is paused.
          add a tolerance of 100ms, in case current position is not buffered,
          check if current pos+100ms is buffered and use that buffer range
          for FRAG_CHANGED event reporting */
        fragPlayingCurrent = this.getBufferedFrag(currentTime + 0.1);
      }
      if (fragPlayingCurrent) {
        var fragPlaying = fragPlayingCurrent;
        if (fragPlaying !== this.fragPlaying) {
          this.hls.trigger(events["a" /* default */].FRAG_CHANGED, { frag: fragPlaying });
          var fragPlayingLevel = fragPlaying.level;

share/public_html/static/hls.js  view on Meta::CPAN

  StreamController.prototype.nextLevelSwitch = function nextLevelSwitch() {
    var media = this.media;
    // ensure that media is defined and that metadata are available (to retrieve currentTime)
    if (media && media.readyState) {
      var fetchdelay = void 0,
          fragPlayingCurrent = void 0,
          nextBufferedFrag = void 0;
      fragPlayingCurrent = this.getBufferedFrag(media.currentTime);
      if (fragPlayingCurrent && fragPlayingCurrent.startPTS > 1) {
        // flush buffer preceding current fragment (flush until current fragment start offset)
        // minus 1s to avoid video freezing, that could happen if we flush keyframe of current video ...
        this.flushMainBuffer(0, fragPlayingCurrent.startPTS - 1);
      }
      if (!media.paused) {
        // add a safety delay of 1s
        var nextLevelId = this.hls.nextLoadLevel,
            nextLevel = this.levels[nextLevelId],
            fragLastKbps = this.fragLastKbps;
        if (fragLastKbps && this.fragCurrent) {
          fetchdelay = this.fragCurrent.duration * nextLevel.bitrate / (1000 * fragLastKbps) + 1;
        } else {

share/public_html/static/hls.js  view on Meta::CPAN

      if (data.hasAudio === true) {
        frag.addElementaryStream(loader_fragment.ElementaryStreamTypes.AUDIO);
      }

      if (data.hasVideo === true) {
        frag.addElementaryStream(loader_fragment.ElementaryStreamTypes.VIDEO);
      }

      logger["b" /* logger */].log('Parsed ' + data.type + ',PTS:[' + data.startPTS.toFixed(3) + ',' + data.endPTS.toFixed(3) + '],DTS:[' + data.startDTS.toFixed(3) + '/' + data.endDTS.toFixed(3) + '],nb:' + data.nb + ',dropped:' + (data.dropped || 0...

      // Detect gaps in a fragment  and try to fix it by finding a keyframe in the previous fragment (see _findFragments)
      if (data.type === 'video') {
        frag.dropped = data.dropped;
        if (frag.dropped) {
          if (!frag.backtracked) {
            var levelDetails = level.details;
            if (levelDetails && frag.sn === levelDetails.startSN) {
              logger["b" /* logger */].warn('missing video frame(s) on first frag, appending with gap', frag.sn);
            } else {
              logger["b" /* logger */].warn('missing video frame(s), backtracking fragment', frag.sn);
              // Return back to the IDLE state without appending to buffer
              // Causes findFragments to backtrack a segment and find the keyframe
              // Audio fragments arriving before video sets the nextLoadPosition, causing _findFragments to skip the backtracked fragment
              this.fragmentTracker.removeFragment(frag);
              frag.backtracked = true;
              this.nextLoadPosition = data.startPTS;
              this.state = State.IDLE;
              this.fragPrevious = frag;
              this.tick();
              return;
            }
          } else {
            logger["b" /* logger */].warn('Already backtracked on this fragment, appending with the gap', frag.sn);
          }
        } else {
          // Only reset the backtracked flag if we've loaded the frag without any dropped frames
          frag.backtracked = false;
        }
      }

      var drift = updateFragPTSDTS(level.details, frag, data.startPTS, data.endPTS, data.startDTS, data.endDTS),
          hls = this.hls;
      hls.trigger(events["a" /* default */].LEVEL_PTS_UPDATED, { details: level.details, level: this.level, drift: drift, type: data.type, start: data.startPTS, end: data.endPTS });
      // has remuxer dropped video frames located before first keyframe ?
      [data.data1, data.data2].forEach(function (buffer) {
        // only append in PARSING state (rationale is that an appending error could happen synchronously on first segment appending)
        // in that case it is useless to append following segments
        if (buffer && buffer.length && _this2.state === State.PARSING) {
          _this2.appended = true;
          // arm pending Buffering flag before appending a segment
          _this2.pendingBuffering = true;
          hls.trigger(events["a" /* default */].BUFFER_APPENDING, { type: data.type, data: buffer, parent: 'main', content: 'data' });
        }
      });

share/public_html/static/hls.js  view on Meta::CPAN

      this.id3Track = this.getID3Track(this.media.textTracks);
      this.id3Track.mode = 'hidden';
    }

    // Attempt to recreate Safari functionality by creating
    // WebKitDataCue objects when available and store the decoded
    // ID3 data in the value property of the cue
    var Cue = window.WebKitDataCue || window.VTTCue || window.TextTrackCue;

    for (var i = 0; i < samples.length; i++) {
      var frames = id3["a" /* default */].getID3Frames(samples[i].data);
      if (frames) {
        var startTime = samples[i].pts;
        var endTime = i < samples.length - 1 ? samples[i + 1].pts : fragment.endPTS;

        // Give a slight bump to the endTime if it's equal to startTime to avoid a SyntaxError in IE
        if (startTime === endTime) {
          endTime += 0.0001;
        }

        for (var j = 0; j < frames.length; j++) {
          var frame = frames[j];
          // Safari doesn't put the timestamp frame in the TextTrack
          if (!id3["a" /* default */].isTimeStampFrame(frame)) {
            var cue = new Cue(startTime, endTime, '');
            cue.value = frame;
            this.id3Track.addCue(cue);
          }
        }
      }
    }
  };

  return ID3TrackController;
}(event_handler);

share/public_html/static/hls.js  view on Meta::CPAN



  AbrController.prototype._findBestLevel = function _findBestLevel(currentLevel, currentFragDuration, currentBw, minAutoLevel, maxAutoLevel, maxFetchDuration, bwFactor, bwUpFactor, levels) {
    for (var i = maxAutoLevel; i >= minAutoLevel; i--) {
      var levelInfo = levels[i],
          levelDetails = levelInfo.details,
          avgDuration = levelDetails ? levelDetails.totalduration / levelDetails.fragments.length : currentFragDuration,
          live = levelDetails ? levelDetails.live : false,
          adjustedbw = void 0;
      // follow algorithm captured from stagefright :
      // https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/httplive/LiveSession.cpp
      // Pick the highest bandwidth stream below or equal to estimated bandwidth.
      // consider only 80% of the available bandwidth, but if we are switching up,
      // be even more conservative (70%) to avoid overestimating and immediately
      // switching back.
      if (i <= currentLevel) {
        adjustedbw = bwFactor * currentBw;
      } else {
        adjustedbw = bwUpFactor * currentBw;
      }

share/public_html/static/hls.js  view on Meta::CPAN

  }

  BufferController.prototype.destroy = function destroy() {
    event_handler.prototype.destroy.call(this);
  };

  BufferController.prototype.onLevelPtsUpdated = function onLevelPtsUpdated(data) {
    var type = data.type;
    var audioTrack = this.tracks.audio;

    // Adjusting `SourceBuffer.timestampOffset` (desired point in the timeline where the next frames should be appended)
    // in Chrome browser when we detect MPEG audio container and time delta between level PTS and `SourceBuffer.timestampOffset`
    // is greater than 100ms (this is enough to handle seek for VOD or level change for LIVE videos). At the time of change we issue
    // `SourceBuffer.abort()` and adjusting `SourceBuffer.timestampOffset` if `SourceBuffer.updating` is false or awaiting `updateend`
    // event if SB is in updating state.
    // More info here: https://github.com/video-dev/hls.js/issues/332#issuecomment-257986486

    if (type === 'audio' && audioTrack && audioTrack.container === 'audio/mpeg') {
      // Chrome audio mp3 track
      var audioBuffer = this.sourceBuffer.audio;
      var delta = Math.abs(audioBuffer.timestampOffset - data.start);

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/Makefile  view on Meta::CPAN

# source ~/emsdk/emsdk_env.sh
CC:=emcc
SRCDIR?=src
OUTDIR?=.
TARGET:=$(OUTDIR)/drflac.js

CFLAGS:=-s 'EXPORTED_FUNCTIONS=["_network_drflac_open_mem", "_network_drflac_read_pcm_frames_f32_mem", "_network_drflac_close", \
"_network_drflac_totalPCMFrameCount", "_network_drflac_sampleRate", "_network_drflac_bitsPerSample", "_network_drflac_channels", \
"_network_drflac_mem_create", "_network_drflac_mem_free", "_network_drflac_mem_add_block", "_network_drflac_mem_bufptr", \
"_network_drflac_create_error", "_network_drflac_free_error", "_network_drflac_error_code", "_network_drflac_extra_data"]'
CFLAGS += -s 'EXPORTED_RUNTIME_METHODS=["cwrap", "ccall"]'
CFLAGS += -s 'EXPORT_ES6=1'
CFLAGS += -s 'ASSERTIONS=1'
CFLAGS += -s 'ALLOW_MEMORY_GROWTH=1'
CFLAGS += -s 'MODULARIZE=1'

all: CFLAGS += -O3

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

async function Module(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?....
;return moduleRtn}export default Module;

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

        if(that.ptr){
            DrFlac.network_drflac_close(that.ptr);
            that.ptr = null;
        }        
        if(that.memptr) {
            DrFlac.network_drflac_mem_free(that.memptr);
            that.memptr = null;
        }            
    };

    that.read_pcm_frames_to_AudioBuffer_f32_mem = async function(start, count, mysignal, audiocontext) {
        const f32_size = 4;
        const pcm_float_frame_size = f32_size * that.channels;

        while(1) {       
              
        // attempt to decode the samples
        let destdata = DrFlac.Module._malloc(count*pcm_float_frame_size);
        let err_ptr = DrFlac.network_drflac_create_error();  
        const samples = DrFlac.network_drflac_read_pcm_frames_f32_mem(that.ptr, start, count, destdata, err_ptr);
        const err = that.freeError(err_ptr);   
        
        if(err.code !== NDRFLAC_SUCCESS)
        {
            DrFlac.Module._free(destdata);  
            if(err.code !== NDRFLAC_MEM_NEED_MORE)
            {
                throw("network_drflac_read_pcm_frames_f32_mem failed");
            }
            // download more data
            await that.downloadChunk(err.extradata, mysignal);

            // reopen drflac
            DrFlac.network_drflac_close(that.ptr);
            let err_ptr = DrFlac.network_drflac_create_error();            
            that.ptr = DrFlac.network_drflac_open_mem(that.filesize, that.memptr, err_ptr);
            that.freeError(err_ptr);            
            if(!that.ptr) {

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

        for( let i = 0; i < that.channels; i++) {
            let buf = new Float32Array(DrFlac.Module.HEAPU8.buffer, destdata+(chansize*i), samples);
            audiobuffer.getChannelData(i).set(buf);        
        }

        DrFlac.Module._free(destdata);
        return audiobuffer;
        };       
    };

    that.read_pcm_frames_to_AudioBuffer = async function(start, count, mysignal, audiocontext) {
        //return that.read_pcm_frames_to_AudioBuffer_wav(start, count, mysignal, audiocontext);
        return that.read_pcm_frames_to_AudioBuffer_f32_mem(start, count, mysignal, audiocontext);
    };

    // open drflac for the first time   
    for(let start = 0; ;) {
        try {
            await that.downloadChunk(start, gsignal);
        } catch(error) {
            that.close();
            throw(error); 
        }

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

    DrFlac.network_drflac_sampleRate = DrFlacMod.cwrap('network_drflac_sampleRate', "number", ["number"]);

    DrFlac.network_drflac_bitsPerSample = DrFlacMod.cwrap('network_drflac_bitsPerSample', "number", ["number"]);

    DrFlac.network_drflac_channels = DrFlacMod.cwrap('network_drflac_channels', "number", ["number"]);   

    DrFlac.network_drflac_close = DrFlacMod.cwrap('network_drflac_close', null, ["number"]);    

    DrFlac.network_drflac_open_mem = DrFlacMod.cwrap('network_drflac_open_mem', "number", ["number", "number", "number"]);

    DrFlac.network_drflac_read_pcm_frames_f32_mem = DrFlacMod.cwrap('network_drflac_read_pcm_frames_f32_mem', "number", ["number", "number", "number", "number", "number"]);

    DrFlac.network_drflac_create_error = DrFlacMod.cwrap('network_drflac_create_error', "number");

    DrFlac.network_drflac_free_error = DrFlacMod.cwrap('network_drflac_free_error', null, ["number"]);

    DrFlac.network_drflac_error_code = DrFlacMod.cwrap('network_drflac_error_code', "number", ["number"]);
    
    DrFlac.network_drflac_extra_data = DrFlacMod.cwrap('network_drflac_extra_data', "number", ["number"]);

    DrFlac.network_drflac_mem_create = DrFlacMod.cwrap('network_drflac_mem_create', "number", ["number", "number"]);

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

                    console.log('handling aborted sleep');
                    unlock();                     
                    return;
                }
            }
            
            // decode
            let buffer;
            for(let failedcount = 0;!buffer;) {
                try {
                    buffer = await NWDRFLAC.read_pcm_frames_to_AudioBuffer(dectime, todec, mysignal, MainAudioContext);
                    if(mysignal.aborted) {
                        console.log('aborted decodeaudiodata success');
                        unlock();                        
                        return;
                    }
                    if(buffer.duration !== (todec / NWDRFLAC.sampleRate)) {                       
                        buffer = null;
                        throw('network error? buffer wrong length');
                    }                        
                }
                catch(error) {
                    console.error(error);
                    if(mysignal.aborted) {
                        console.log('aborted read_pcm_frames decodeaudiodata catch');
                        unlock();                        
                        return;
                    }                   
                    failedcount++;
                    if(failedcount == 2) {
                        console.log('Encountered error twice, advancing to next track');
                         // assume it's corrupted. force free it
                        await NWDRFLAC.close();
                        NWDRFLAC = null;                      
                        continue TRACKLOOP;

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

Every API that opens a drflac object now takes this extra parameter. These include the following:

    drflac_open()
    drflac_open_relaxed()
    drflac_open_with_metadata()
    drflac_open_with_metadata_relaxed()
    drflac_open_file()
    drflac_open_file_with_metadata()
    drflac_open_memory()
    drflac_open_memory_with_metadata()
    drflac_open_and_read_pcm_frames_s32()
    drflac_open_and_read_pcm_frames_s16()
    drflac_open_and_read_pcm_frames_f32()
    drflac_open_file_and_read_pcm_frames_s32()
    drflac_open_file_and_read_pcm_frames_s16()
    drflac_open_file_and_read_pcm_frames_f32()
    drflac_open_memory_and_read_pcm_frames_s32()
    drflac_open_memory_and_read_pcm_frames_s16()
    drflac_open_memory_and_read_pcm_frames_f32()



Optimizations
-------------
Seeking performance has been greatly improved. A new binary search based seeking algorithm has been introduced which significantly
improves performance over the brute force method which was used when no seek table was present. Seek table based seeking also takes
advantage of the new binary search seeking system to further improve performance there as well. Note that this depends on CRC which
means it will be disabled when DR_FLAC_NO_CRC is used.

The SSE4.1 pipeline has been cleaned up and optimized. You should see some improvements with decoding speed of 24-bit files in
particular. 16-bit streams should also see some improvement.

drflac_read_pcm_frames_s16() has been optimized. Previously this sat on top of drflac_read_pcm_frames_s32() and performed it's s32
to s16 conversion in a second pass. This is now all done in a single pass. This includes SSE2 and ARM NEON optimized paths.

A minor optimization has been implemented for drflac_read_pcm_frames_s32(). This will now use an SSE2 optimized pipeline for stereo
channel reconstruction which is the last part of the decoding process.

The ARM build has seen a few improvements. The CLZ (count leading zeroes) and REV (byte swap) instructions are now used when
compiling with GCC and Clang which is achieved using inline assembly. The CLZ instruction requires ARM architecture version 5 at
compile time and the REV instruction requires ARM architecture version 6.

An ARM NEON optimized pipeline has been implemented. To enable this you'll need to add -mfpu=neon to the command line when compiling.


Removed APIs
------------
The following APIs were deprecated in version 0.11.0 and have been completely removed in version 0.12.0:

    drflac_read_s32()                   -> drflac_read_pcm_frames_s32()
    drflac_read_s16()                   -> drflac_read_pcm_frames_s16()
    drflac_read_f32()                   -> drflac_read_pcm_frames_f32()
    drflac_seek_to_sample()             -> drflac_seek_to_pcm_frame()
    drflac_open_and_decode_s32()        -> drflac_open_and_read_pcm_frames_s32()
    drflac_open_and_decode_s16()        -> drflac_open_and_read_pcm_frames_s16()
    drflac_open_and_decode_f32()        -> drflac_open_and_read_pcm_frames_f32()
    drflac_open_and_decode_file_s32()   -> drflac_open_file_and_read_pcm_frames_s32()
    drflac_open_and_decode_file_s16()   -> drflac_open_file_and_read_pcm_frames_s16()
    drflac_open_and_decode_file_f32()   -> drflac_open_file_and_read_pcm_frames_f32()
    drflac_open_and_decode_memory_s32() -> drflac_open_memory_and_read_pcm_frames_s32()
    drflac_open_and_decode_memory_s16() -> drflac_open_memory_and_read_pcm_frames_s16()
    drflac_open_and_decode_memory_f32() -> drflac_open_memroy_and_read_pcm_frames_f32()

Prior versions of dr_flac operated on a per-sample basis whereas now it operates on PCM frames. The removed APIs all relate
to the old per-sample APIs. You now need to use the "pcm_frame" versions.
*/


/*
Introduction
============
dr_flac is a single file library. To use it, do something like the following in one .c file.

    ```c
    #define DR_FLAC_IMPLEMENTATION

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


You can then #include this file in other parts of the program as you would with any other header file. To decode audio data, do something like the following:

    ```c
    drflac* pFlac = drflac_open_file("MySong.flac", NULL);
    if (pFlac == NULL) {
        // Failed to open FLAC file
    }

    drflac_int32* pSamples = malloc(pFlac->totalPCMFrameCount * pFlac->channels * sizeof(drflac_int32));
    drflac_uint64 numberOfInterleavedSamplesActuallyRead = drflac_read_pcm_frames_s32(pFlac, pFlac->totalPCMFrameCount, pSamples);
    ```

The drflac object represents the decoder. It is a transparent type so all the information you need, such as the number of channels and the bits per sample,
should be directly accessible - just make sure you don't change their values. Samples are always output as interleaved signed 32-bit PCM. In the example above
a native FLAC stream was opened, however dr_flac has seamless support for Ogg encapsulated FLAC streams as well.

You do not need to decode the entire stream in one go - you just specify how many samples you'd like at any given time and the decoder will give you as many
samples as it can, up to the amount requested. Later on when you need the next batch of samples, just call it again. Example:

    ```c
    while (drflac_read_pcm_frames_s32(pFlac, chunkSizeInPCMFrames, pChunkSamples) > 0) {
        do_something();
    }
    ```

You can seek to a specific PCM frame with `drflac_seek_to_pcm_frame()`.

If you just want to quickly decode an entire FLAC file in one go you can do something like this:

    ```c
    unsigned int channels;
    unsigned int sampleRate;
    drflac_uint64 totalPCMFrameCount;
    drflac_int32* pSampleData = drflac_open_file_and_read_pcm_frames_s32("MySong.flac", &channels, &sampleRate, &totalPCMFrameCount, NULL);
    if (pSampleData == NULL) {
        // Failed to open and decode FLAC file.
    }

    ...

    drflac_free(pSampleData);
    ```

You can read samples as signed 16-bit integer and 32-bit floating-point PCM with the *_s16() and *_f32() family of APIs respectively, but note that these

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

The rationale for keeping these APIs separate is that they're slightly slower than the normal versions and also just a little bit harder to use. dr_flac
reports metadata to the application through the use of a callback, and every metadata block is reported before `drflac_open_with_metdata()` returns.

The main opening APIs (`drflac_open()`, etc.) will fail if the header is not present. The presents a problem in certain scenarios such as broadcast style
streams or internet radio where the header may not be present because the user has started playback mid-stream. To handle this, use the relaxed APIs:
    
    `drflac_open_relaxed()`
    `drflac_open_with_metadata_relaxed()`

It is not recommended to use these APIs for file based streams because a missing header would usually indicate a corrupt or perverse file. In addition, these
APIs can take a long time to initialize because they may need to spend a lot of time finding the first frame.



Build Options
=============
#define these options before including this file.

#define DR_FLAC_NO_STDIO
  Disable `drflac_open_file()` and family.

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

{
    drflac_seek_origin_start,
    drflac_seek_origin_current
} drflac_seek_origin;

/* Packing is important on this structure because we map this directly to the raw data within the SEEKTABLE metadata block. */
#pragma pack(2)
typedef struct
{
    drflac_uint64 firstPCMFrame;
    drflac_uint64 flacFrameOffset;   /* The offset from the first byte of the header of the first frame. */
    drflac_uint16 pcmFrameCount;
} drflac_seekpoint;
#pragma pack()

typedef struct
{
    drflac_uint16 minBlockSizeInPCMFrames;
    drflac_uint16 maxBlockSizeInPCMFrames;
    drflac_uint32 minFrameSizeInPCMFrames;
    drflac_uint32 maxFrameSizeInPCMFrames;

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

Return Value
------------
Whether or not the seek was successful.


Remarks
-------
The offset will never be negative. Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which will be
either drflac_seek_origin_start or drflac_seek_origin_current.

When seeking to a PCM frame using drflac_seek_to_pcm_frame(), dr_flac may call this with an offset beyond the end of the FLAC stream. This needs to be detected
and handled by returning DRFLAC_FALSE.
*/
typedef drflac_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin);

/*
Callback for when a metadata block is read.


Parameters
----------

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


    /*
    The cached data which was most recently read from the client. There are two levels of cache. Data flows as such:
    Client -> L2 -> L1. The L2 -> L1 movement is aligned and runs on a fast path in just a few instructions.
    */
    drflac_cache_t cacheL2[DR_FLAC_BUFFER_SIZE/sizeof(drflac_cache_t)];
    drflac_cache_t cache;

    /*
    CRC-16. This is updated whenever bits are read from the bit stream. Manually set this to 0 to reset the CRC. For FLAC, this
    is reset to 0 at the beginning of each frame.
    */
    drflac_uint16 crc16;
    drflac_cache_t crc16Cache;              /* A cache for optimizing CRC calculations. This is filled when when the L1 cache is reloaded. */
    drflac_uint32 crc16CacheIgnoredBytes;   /* The number of bytes to ignore when updating the CRC-16 from the CRC-16 cache. */
} drflac_bs;

typedef struct
{
    /* The type of the subframe: SUBFRAME_CONSTANT, SUBFRAME_VERBATIM, SUBFRAME_FIXED or SUBFRAME_LPC. */
    drflac_uint8 subframeType;

    /* The number of wasted bits per sample as specified by the sub-frame header. */
    drflac_uint8 wastedBitsPerSample;

    /* The order to use for the prediction stage for SUBFRAME_FIXED and SUBFRAME_LPC. */
    drflac_uint8 lpcOrder;

    /* A pointer to the buffer containing the decoded samples in the subframe. This pointer is an offset from drflac::pExtraData. */
    drflac_int32* pSamplesS32;
} drflac_subframe;

typedef struct
{
    /*
    If the stream uses variable block sizes, this will be set to the index of the first PCM frame. If fixed block sizes are used, this will
    always be set to 0. This is 64-bit because the decoded PCM frame number will be 36 bits.
    */
    drflac_uint64 pcmFrameNumber;

    /*
    If the stream uses fixed block sizes, this will be set to the frame number. If variable block sizes are used, this will always be 0. This
    is 32-bit because in fixed block sizes, the maximum frame number will be 31 bits.
    */
    drflac_uint32 flacFrameNumber;

    /* The sample rate of this frame. */
    drflac_uint32 sampleRate;

    /* The number of PCM frames in each sub-frame within this frame. */
    drflac_uint16 blockSizeInPCMFrames;

    /*
    The channel assignment of this frame. This is not always set to the channel count. If interchannel decorrelation is being used this
    will be set to DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE, DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE or DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE.
    */
    drflac_uint8 channelAssignment;

    /* The number of bits per sample within this frame. */
    drflac_uint8 bitsPerSample;

    /* The frame's CRC. */
    drflac_uint8 crc8;
} drflac_frame_header;

typedef struct
{
    /* The header. */
    drflac_frame_header header;

    /*
    The number of PCM frames left to be read in this FLAC frame. This is initially set to the block size. As PCM frames are read,
    this will be decremented. When it reaches 0, the decoder will see this frame as fully consumed and load the next frame.
    */
    drflac_uint32 pcmFramesRemaining;

    /* The list of sub-frames within the frame. There is one sub-frame for each channel, and there's a maximum of 8 channels. */
    drflac_subframe subframes[8];
} drflac_frame;

typedef struct
{
    /* The function to call when a metadata block is read. */
    drflac_meta_proc onMeta;

    /* The user data posted to the metadata callback function. */
    void* pUserDataMD;

    /* Memory allocation callbacks. */

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

    drflac_uint8 channels;

    /* The bits per sample. Will be set to something like 16, 24, etc. */
    drflac_uint8 bitsPerSample;

    /* The maximum block size, in samples. This number represents the number of samples in each channel (not combined). */
    drflac_uint16 maxBlockSizeInPCMFrames;

    /*
    The total number of PCM Frames making up the stream. Can be 0 in which case it's still a valid stream, but just means
    the total PCM frame count is unknown. Likely the case with streams like internet radio.
    */
    drflac_uint64 totalPCMFrameCount;


    /* The container type. This is set based on whether or not the decoder was opened from a native or Ogg stream. */
    drflac_container container;

    /* The number of seekpoints in the seektable. */
    drflac_uint32 seekpointCount;


    /* Information about the frame the decoder is currently sitting on. */
    drflac_frame currentFLACFrame;


    /* The index of the PCM frame the decoder is currently sitting on. This is only used for seeking. */
    drflac_uint64 currentPCMFrame;

    /* The position of the first FLAC frame in the stream. This is only ever used for seeking. */
    drflac_uint64 firstFLACFramePosInBytes;


    /* A hack to avoid a malloc() when opening a decoder with drflac_open_memory(). */
    drflac__memory_stream memoryStream;


    /* A pointer to the decoded sample data. This is an offset of pExtraData. */
    drflac_int32* pDecodedSamples;

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

A pointer to an object representing the decoder.


Remarks
-------
The same as drflac_open(), except attempts to open the stream even when a header block is not present.

Because the header is not necessarily available, the caller must explicitly define the container (Native or Ogg). Do not set this to `drflac_container_unknown`
as that is for internal use only.

Opening in relaxed mode will continue reading data from onRead until it finds a valid frame. If a frame is never found it will continue forever. To abort,
force your `onRead` callback to return 0, which dr_flac will use as an indicator that the end of the stream was found.
*/
DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);

/*
Opens a FLAC decoder and notifies the caller of the metadata chunks (album art, etc.).


Parameters
----------

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


/*
Reads sample data from the given FLAC decoder, output as interleaved signed 32-bit PCM.


Parameters
----------
pFlac (in)
    The decoder.

framesToRead (in)
    The number of PCM frames to read.

pBufferOut (out, optional)
    A pointer to the buffer that will receive the decoded samples.


Return Value
------------
Returns the number of PCM frames actually read. If the return value is less than `framesToRead` it has reached the end.


Remarks
-------
pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames seeked.
*/
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut);


/*
Reads sample data from the given FLAC decoder, output as interleaved signed 16-bit PCM.


Parameters
----------
pFlac (in)
    The decoder.

framesToRead (in)
    The number of PCM frames to read.

pBufferOut (out, optional)
    A pointer to the buffer that will receive the decoded samples.


Return Value
------------
Returns the number of PCM frames actually read. If the return value is less than `framesToRead` it has reached the end.


Remarks
-------
pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames seeked.

Note that this is lossy for streams where the bits per sample is larger than 16.
*/
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut);

/*
Reads sample data from the given FLAC decoder, output as interleaved 32-bit floating point PCM.


Parameters
----------
pFlac (in)
    The decoder.

framesToRead (in)
    The number of PCM frames to read.

pBufferOut (out, optional)
    A pointer to the buffer that will receive the decoded samples.


Return Value
------------
Returns the number of PCM frames actually read. If the return value is less than `framesToRead` it has reached the end.


Remarks
-------
pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames seeked.

Note that this should be considered lossy due to the nature of floating point numbers not being able to exactly represent every possible number.
*/
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut);

/*
Seeks to the PCM frame at the given index.


Parameters
----------
pFlac (in)
    The decoder.

pcmFrameIndex (in)
    The index of the PCM frame to seek to. See notes below.


Return Value
-------------
`DRFLAC_TRUE` if successful; `DRFLAC_FALSE` otherwise.
*/
DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex);



#ifndef DR_FLAC_NO_STDIO
/*
Opens a FLAC decoder from the file at the given path.


Parameters
----------

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

pointer to the sample data as interleaved signed 32-bit PCM. The returned data must be freed with drflac_free().

You can pass in custom memory allocation callbacks via the pAllocationCallbacks parameter. This can be NULL in which
case it will use DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE.

Sometimes a FLAC file won't keep track of the total sample count. In this situation the function will continuously
read samples into a dynamically sized buffer on the heap until no samples are left.

Do not call this function on a broadcast type of stream (like internet radio streams and whatnot).
*/
DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pA...

/* Same as drflac_open_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pA...

/* Same as drflac_open_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocati...

#ifndef DR_FLAC_NO_STDIO
/* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a file. */
DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);

/* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);

/* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
#endif

/* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a block of memory. */
DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);

/* Same as drflac_open_memory_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
DRFLAC_API drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);

/* Same as drflac_open_memory_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
DRFLAC_API float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);

/*
Frees memory that was allocated internally by dr_flac.

Set pAllocationCallbacks to the same object that was passed to drflac_open_*_and_read_pcm_frames_*(). If you originally passed in NULL, pass in NULL for this.
*/
DRFLAC_API void drflac_free(void* p, const drflac_allocation_callbacks* pAllocationCallbacks);


/* Structure representing an iterator for vorbis comments in a VORBIS_COMMENT metadata block. */
typedef struct
{
    drflac_uint32 countRemaining;
    const char* pRunningData;
} drflac_vorbis_comment_iterator;

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

            }
            bitsToSeek = 0; /* <-- Necessary for the assert below. */
        }

        DRFLAC_ASSERT(bitsToSeek == 0);
        return DRFLAC_TRUE;
    }
}


/* This function moves the bit streamer to the first bit after the sync code (bit 15 of the of the frame header). It will also update the CRC-16. */
static drflac_bool32 drflac__find_and_seek_to_next_sync_code(drflac_bs* bs)
{
    DRFLAC_ASSERT(bs != NULL);

    /*
    The sync code is always aligned to 8 bits. This is convenient for us because it means we can do byte-aligned movements. The first
    thing to do is align to the next byte.
    */
    if (!drflac__seek_bits(bs, DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) {
        return DRFLAC_FALSE;

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

        } else {
            pSamplesOut[i] += drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + i);
        }
    }

    return DRFLAC_TRUE;
}


/*
Reads and decodes the residual for the sub-frame the decoder is currently sitting on. This function should be called
when the decoder is sitting at the very start of the RESIDUAL block. The first <order> residuals will be ignored. The
<blockSize> and <order> parameters are used to determine how many residual values need to be decoded.
*/
static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 blockSize, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
{
    drflac_uint8 residualMethod;
    drflac_uint8 partitionOrder;
    drflac_uint32 samplesInPartition;
    drflac_uint32 partitionsRemaining;

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


        if (partitionOrder != 0) {
            samplesInPartition = blockSize / (1 << partitionOrder);
        }
    }

    return DRFLAC_TRUE;
}

/*
Reads and seeks past the residual for the sub-frame the decoder is currently sitting on. This function should be called
when the decoder is sitting at the very start of the RESIDUAL block. The first <order> residuals will be set to 0. The
<blockSize> and <order> parameters are used to determine how many residual values need to be decoded.
*/
static drflac_bool32 drflac__read_and_seek_residual(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 order)
{
    drflac_uint8 residualMethod;
    drflac_uint8 partitionOrder;
    drflac_uint32 samplesInPartition;
    drflac_uint32 partitionsRemaining;

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

        }

        partitionsRemaining -= 1;
        samplesInPartition = blockSize / (1 << partitionOrder);
    }

    return DRFLAC_TRUE;
}


static drflac_bool32 drflac__decode_samples__constant(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
{
    drflac_uint32 i;

    /* Only a single sample needs to be decoded here. */
    drflac_int32 sample;
    if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
        return DRFLAC_FALSE;
    }

    /*
    We don't really need to expand this, but it does simplify the process of reading samples. If this becomes a performance issue (unlikely)
    we'll want to look at a more efficient way.
    */
    for (i = 0; i < blockSize; ++i) {
        pDecodedSamples[i] = sample;
    }

    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
{
    drflac_uint32 i;

    for (i = 0; i < blockSize; ++i) {
        drflac_int32 sample;
        if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
            return DRFLAC_FALSE;
        }

        pDecodedSamples[i] = sample;
    }

    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__decode_samples__fixed(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
{
    drflac_uint32 i;

    static drflac_int32 lpcCoefficientsTable[5][4] = {
        {0,  0, 0,  0},
        {1,  0, 0,  0},
        {2, -1, 0,  0},
        {3, -3, 1,  0},
        {4, -6, 4, -1}
    };

    /* Warm up samples and coefficients. */
    for (i = 0; i < lpcOrder; ++i) {
        drflac_int32 sample;
        if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
            return DRFLAC_FALSE;
        }

        pDecodedSamples[i] = sample;
    }

    if (!drflac__decode_samples_with_residual(bs, subframeBitsPerSample, blockSize, lpcOrder, 0, lpcCoefficientsTable[lpcOrder], pDecodedSamples)) {
        return DRFLAC_FALSE;
    }

    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__decode_samples__lpc(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
{
    drflac_uint8 i;
    drflac_uint8 lpcPrecision;

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

    }

    if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, lpcShift, coefficients, pDecodedSamples)) {
        return DRFLAC_FALSE;
    }

    return DRFLAC_TRUE;
}


static drflac_bool32 drflac__read_next_flac_frame_header(drflac_bs* bs, drflac_uint8 streaminfoBitsPerSample, drflac_frame_header* header)
{
    const drflac_uint32 sampleRateTable[12]  = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
    const drflac_uint8 bitsPerSampleTable[8] = {0, 8, 12, (drflac_uint8)-1, 16, 20, 24, (drflac_uint8)-1};   /* -1 = reserved. */

    DRFLAC_ASSERT(bs != NULL);
    DRFLAC_ASSERT(header != NULL);

    /* Keep looping until we find a valid sync code. */
    for (;;) {
        drflac_uint8 crc8 = 0xCE; /* 0xCE = drflac_crc8(0, 0x3FFE, 14); */

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


#ifndef DR_FLAC_NO_CRC
        if (header->crc8 != crc8) {
            continue;    /* CRC mismatch. Loop back to the top and find the next sync code. */
        }
#endif
        return DRFLAC_TRUE;
    }
}

static drflac_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe)
{
    drflac_uint8 header;
    int type;

    if (!drflac__read_uint8(bs, 8, &header)) {
        return DRFLAC_FALSE;
    }

    /* First bit should always be 0. */
    if ((header & 0x80) != 0) {
        return DRFLAC_FALSE;
    }

    type = (header & 0x7E) >> 1;
    if (type == 0) {
        pSubframe->subframeType = DRFLAC_SUBFRAME_CONSTANT;
    } else if (type == 1) {
        pSubframe->subframeType = DRFLAC_SUBFRAME_VERBATIM;
    } else {
        if ((type & 0x20) != 0) {
            pSubframe->subframeType = DRFLAC_SUBFRAME_LPC;
            pSubframe->lpcOrder = (drflac_uint8)(type & 0x1F) + 1;
        } else if ((type & 0x08) != 0) {
            pSubframe->subframeType = DRFLAC_SUBFRAME_FIXED;
            pSubframe->lpcOrder = (drflac_uint8)(type & 0x07);
            if (pSubframe->lpcOrder > 4) {
                pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED;
                pSubframe->lpcOrder = 0;
            }
        } else {
            pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED;
        }
    }

    if (pSubframe->subframeType == DRFLAC_SUBFRAME_RESERVED) {
        return DRFLAC_FALSE;
    }

    /* Wasted bits per sample. */
    pSubframe->wastedBitsPerSample = 0;
    if ((header & 0x01) == 1) {
        unsigned int wastedBitsPerSample;
        if (!drflac__seek_past_next_set_bit(bs, &wastedBitsPerSample)) {
            return DRFLAC_FALSE;
        }
        pSubframe->wastedBitsPerSample = (drflac_uint8)wastedBitsPerSample + 1;
    }

    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, drflac_int32* pDecodedSamplesOut)
{
    drflac_subframe* pSubframe;
    drflac_uint32 subframeBitsPerSample;

    DRFLAC_ASSERT(bs != NULL);
    DRFLAC_ASSERT(frame != NULL);

    pSubframe = frame->subframes + subframeIndex;
    if (!drflac__read_subframe_header(bs, pSubframe)) {
        return DRFLAC_FALSE;
    }

    /* Side channels require an extra bit per sample. Took a while to figure that one out... */
    subframeBitsPerSample = frame->header.bitsPerSample;
    if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
        subframeBitsPerSample += 1;
    } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
        subframeBitsPerSample += 1;
    }

    /* Need to handle wasted bits per sample. */
    if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
        return DRFLAC_FALSE;
    }
    subframeBitsPerSample -= pSubframe->wastedBitsPerSample;

    pSubframe->pSamplesS32 = pDecodedSamplesOut;

    switch (pSubframe->subframeType)
    {
        case DRFLAC_SUBFRAME_CONSTANT:
        {
            drflac__decode_samples__constant(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
        } break;

        case DRFLAC_SUBFRAME_VERBATIM:
        {
            drflac__decode_samples__verbatim(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
        } break;

        case DRFLAC_SUBFRAME_FIXED:
        {
            drflac__decode_samples__fixed(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
        } break;

        case DRFLAC_SUBFRAME_LPC:
        {
            drflac__decode_samples__lpc(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
        } break;

        default: return DRFLAC_FALSE;
    }

    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex)
{
    drflac_subframe* pSubframe;
    drflac_uint32 subframeBitsPerSample;

    DRFLAC_ASSERT(bs != NULL);
    DRFLAC_ASSERT(frame != NULL);

    pSubframe = frame->subframes + subframeIndex;
    if (!drflac__read_subframe_header(bs, pSubframe)) {
        return DRFLAC_FALSE;
    }

    /* Side channels require an extra bit per sample. Took a while to figure that one out... */
    subframeBitsPerSample = frame->header.bitsPerSample;
    if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
        subframeBitsPerSample += 1;
    } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
        subframeBitsPerSample += 1;
    }

    /* Need to handle wasted bits per sample. */
    if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
        return DRFLAC_FALSE;
    }
    subframeBitsPerSample -= pSubframe->wastedBitsPerSample;

    pSubframe->pSamplesS32 = NULL;

    switch (pSubframe->subframeType)
    {
        case DRFLAC_SUBFRAME_CONSTANT:
        {
            if (!drflac__seek_bits(bs, subframeBitsPerSample)) {
                return DRFLAC_FALSE;
            }
        } break;

        case DRFLAC_SUBFRAME_VERBATIM:
        {
            unsigned int bitsToSeek = frame->header.blockSizeInPCMFrames * subframeBitsPerSample;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }
        } break;

        case DRFLAC_SUBFRAME_FIXED:
        {
            unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }

            if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
                return DRFLAC_FALSE;
            }
        } break;

        case DRFLAC_SUBFRAME_LPC:
        {
            drflac_uint8 lpcPrecision;

            unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }

            if (!drflac__read_uint8(bs, 4, &lpcPrecision)) {
                return DRFLAC_FALSE;
            }
            if (lpcPrecision == 15) {
                return DRFLAC_FALSE;    /* Invalid. */
            }
            lpcPrecision += 1;


            bitsToSeek = (pSubframe->lpcOrder * lpcPrecision) + 5;    /* +5 for shift. */
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }

            if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
                return DRFLAC_FALSE;
            }
        } break;

        default: return DRFLAC_FALSE;
    }

    return DRFLAC_TRUE;
}


static DRFLAC_INLINE drflac_uint8 drflac__get_channel_count_from_channel_assignment(drflac_int8 channelAssignment)
{
    drflac_uint8 lookup[] = {1, 2, 3, 4, 5, 6, 7, 8, 2, 2, 2};

    DRFLAC_ASSERT(channelAssignment <= 10);
    return lookup[channelAssignment];
}

static drflac_result drflac__decode_flac_frame(drflac* pFlac)
{
    int channelCount;
    int i;
    drflac_uint8 paddingSizeInBits;
    drflac_uint16 desiredCRC16;
#ifndef DR_FLAC_NO_CRC
    drflac_uint16 actualCRC16;
#endif

    /* This function should be called while the stream is sitting on the first byte after the frame header. */
    DRFLAC_ZERO_MEMORY(pFlac->currentFLACFrame.subframes, sizeof(pFlac->currentFLACFrame.subframes));

    /* The frame block size must never be larger than the maximum block size defined by the FLAC stream. */
    if (pFlac->currentFLACFrame.header.blockSizeInPCMFrames > pFlac->maxBlockSizeInPCMFrames) {
        return DRFLAC_ERROR;
    }

    /* The number of channels in the frame must match the channel count from the STREAMINFO block. */
    channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
    if (channelCount != (int)pFlac->channels) {
        return DRFLAC_ERROR;
    }

    for (i = 0; i < channelCount; ++i) {
        if (!drflac__decode_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i, pFlac->pDecodedSamples + (pFlac->currentFLACFrame.header.blockSizeInPCMFrames * i))) {
            return DRFLAC_ERROR;
        }
    }

    paddingSizeInBits = (drflac_uint8)(DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7);
    if (paddingSizeInBits > 0) {
        drflac_uint8 padding = 0;
        if (!drflac__read_uint8(&pFlac->bs, paddingSizeInBits, &padding)) {
            return DRFLAC_AT_END;
        }

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

    if (actualCRC16 != desiredCRC16) {
        return DRFLAC_CRC_MISMATCH;    /* CRC mismatch. */
    }
#endif

    pFlac->currentFLACFrame.pcmFramesRemaining = pFlac->currentFLACFrame.header.blockSizeInPCMFrames;

    return DRFLAC_SUCCESS;
}

static drflac_result drflac__seek_flac_frame(drflac* pFlac)
{
    int channelCount;
    int i;
    drflac_uint16 desiredCRC16;
#ifndef DR_FLAC_NO_CRC
    drflac_uint16 actualCRC16;
#endif

    channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
    for (i = 0; i < channelCount; ++i) {
        if (!drflac__seek_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i)) {
            return DRFLAC_ERROR;
        }
    }

    /* Padding. */
    if (!drflac__seek_bits(&pFlac->bs, DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7)) {
        return DRFLAC_ERROR;
    }

    /* CRC. */

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


#ifndef DR_FLAC_NO_CRC
    if (actualCRC16 != desiredCRC16) {
        return DRFLAC_CRC_MISMATCH;    /* CRC mismatch. */
    }
#endif

    return DRFLAC_SUCCESS;
}

static drflac_bool32 drflac__read_and_decode_next_flac_frame(drflac* pFlac)
{
    DRFLAC_ASSERT(pFlac != NULL);

    for (;;) {
        drflac_result result;
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }

        result = drflac__decode_flac_frame(pFlac);
        if (result != DRFLAC_SUCCESS) {
            if (result == DRFLAC_CRC_MISMATCH) {
                continue;   /* CRC mismatch. Skip to the next frame. */
            } else {
                return DRFLAC_FALSE;
            }
        }

        return DRFLAC_TRUE;
    }
}

static void drflac__get_pcm_frame_range_of_current_flac_frame(drflac* pFlac, drflac_uint64* pFirstPCMFrame, drflac_uint64* pLastPCMFrame)
{
    drflac_uint64 firstPCMFrame;
    drflac_uint64 lastPCMFrame;

    DRFLAC_ASSERT(pFlac != NULL);

    firstPCMFrame = pFlac->currentFLACFrame.header.pcmFrameNumber;
    if (firstPCMFrame == 0) {
        firstPCMFrame = ((drflac_uint64)pFlac->currentFLACFrame.header.flacFrameNumber) * pFlac->maxBlockSizeInPCMFrames;
    }

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

    }

    if (pFirstPCMFrame) {
        *pFirstPCMFrame = firstPCMFrame;
    }
    if (pLastPCMFrame) {
        *pLastPCMFrame = lastPCMFrame;
    }
}

static drflac_bool32 drflac__seek_to_first_frame(drflac* pFlac)
{
    drflac_bool32 result;

    DRFLAC_ASSERT(pFlac != NULL);

    result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes);

    DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
    pFlac->currentPCMFrame = 0;

    return result;
}

static DRFLAC_INLINE drflac_result drflac__seek_to_next_flac_frame(drflac* pFlac)
{
    /* This function should only ever be called while the decoder is sitting on the first byte past the FRAME_HEADER section. */
    DRFLAC_ASSERT(pFlac != NULL);
    return drflac__seek_flac_frame(pFlac);
}


static drflac_uint64 drflac__seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 pcmFramesToSeek)
{
    drflac_uint64 pcmFramesRead = 0;
    while (pcmFramesToSeek > 0) {
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;  /* Couldn't read the next frame, so just break from the loop and return. */
            }
        } else {
            if (pFlac->currentFLACFrame.pcmFramesRemaining > pcmFramesToSeek) {
                pcmFramesRead   += pcmFramesToSeek;
                pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)pcmFramesToSeek;   /* <-- Safe cast. Will always be < currentFrame.pcmFramesRemaining < 65536. */
                pcmFramesToSeek  = 0;
            } else {
                pcmFramesRead   += pFlac->currentFLACFrame.pcmFramesRemaining;
                pcmFramesToSeek -= pFlac->currentFLACFrame.pcmFramesRemaining;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
            }
        }
    }

    pFlac->currentPCMFrame += pcmFramesRead;
    return pcmFramesRead;
}


static drflac_bool32 drflac__seek_to_pcm_frame__brute_force(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_bool32 isMidFrame = DRFLAC_FALSE;
    drflac_uint64 runningPCMFrameCount;

    DRFLAC_ASSERT(pFlac != NULL);

    /* If we are seeking forward we start from the current position. Otherwise we need to start all the way from the start of the file. */
    if (pcmFrameIndex >= pFlac->currentPCMFrame) {
        /* Seeking forward. Need to seek from the current position. */
        runningPCMFrameCount = pFlac->currentPCMFrame;

        /* The frame header for the first frame may not yet have been read. We need to do that if necessary. */
        if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                return DRFLAC_FALSE;
            }
        } else {
            isMidFrame = DRFLAC_TRUE;
        }
    } else {
        /* Seeking backwards. Need to seek from the start of the file. */
        runningPCMFrameCount = 0;

        /* Move back to the start. */
        if (!drflac__seek_to_first_frame(pFlac)) {
            return DRFLAC_FALSE;
        }

        /* Decode the first frame in preparation for sample-exact seeking below. */
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }

    /*
    We need to as quickly as possible find the frame that contains the target sample. To do this, we iterate over each frame and inspect its
    header. If based on the header we can determine that the frame contains the sample, we do a full decode of that frame.
    */
    for (;;) {
        drflac_uint64 pcmFrameCountInThisFLACFrame;
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
        drflac_uint64 lastPCMFrameInFLACFrame = 0;

        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);

        pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
            /*
            The sample should be in this frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend
            it never existed and keep iterating.
            */
            drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;

            if (!isMidFrame) {
                drflac_result result = drflac__decode_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
                    return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;  /* <-- If this fails, something bad has happened (it should never fail). */
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;   /* CRC mismatch. Pretend this frame never existed. */
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                /* We started seeking mid-frame which means we need to skip the frame decoding part. */
                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
            }
        } else {
            /*
            It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
            frame never existed and leave the running sample count untouched.
            */
            if (!isMidFrame) {
                drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;   /* CRC mismatch. Pretend this frame never existed. */
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                /*
                We started seeking mid-frame which means we need to seek by reading to the end of the frame instead of with
                drflac__seek_to_next_flac_frame() which only works if the decoder is sitting on the byte just after the frame header.
                */
                runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
                isMidFrame = DRFLAC_FALSE;
            }

            /* If we are seeking to the end of the file and we've just hit it, we're done. */
            if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
                return DRFLAC_TRUE;
            }
        }

    next_iteration:
        /* Grab the next frame in preparation for the next iteration. */
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }
}


#if !defined(DR_FLAC_NO_CRC)
/*
We use an average compression ratio to determine our approximate start location. FLAC files are generally about 50%-70% the size of their
uncompressed counterparts so we'll use this as a basis. I'm going to split the middle and use a factor of 0.6 to determine the starting
location.
*/
#define DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO 0.6f

static drflac_bool32 drflac__seek_to_approximate_flac_frame_to_byte(drflac* pFlac, drflac_uint64 targetByte, drflac_uint64 rangeLo, drflac_uint64 rangeHi, drflac_uint64* pLastSuccessfulSeekOffset)
{
    DRFLAC_ASSERT(pFlac != NULL);
    DRFLAC_ASSERT(pLastSuccessfulSeekOffset != NULL);
    DRFLAC_ASSERT(targetByte >= rangeLo);
    DRFLAC_ASSERT(targetByte <= rangeHi);

    *pLastSuccessfulSeekOffset = pFlac->firstFLACFramePosInBytes;

    for (;;) {
        /* after rangeLo == rangeHi == targetByte fails, we need to break out */
        drflac_uint64 lastTargetByte = targetByte;

        /* When seeking to a byte, failure probably means we've attempted to seek beyond the end of the stream. To counter this we just halve it each attempt. */
        if (!drflac__seek_to_byte(&pFlac->bs, targetByte)) {
            /* If we couldn't even seek to the first byte in the stream we have a problem. Just abandon the whole thing. */
            if (targetByte == 0) {
                drflac__seek_to_first_frame(pFlac); /* Try to recover. */
                return DRFLAC_FALSE;
            }

            /* Halve the byte location and continue. */
            targetByte = rangeLo + ((rangeHi - rangeLo)/2);
            rangeHi = targetByte;
        } else {
            /* Getting here should mean that we have seeked to an appropriate byte. */

            /* Clear the details of the FLAC frame so we don't misreport data. */
            DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));

            /*
            Now seek to the next FLAC frame. We need to decode the entire frame (not just the header) because it's possible for the header to incorrectly pass the
            CRC check and return bad data. We need to decode the entire frame to be more certain. Although this seems unlikely, this has happened to me in testing
            so it needs to stay this way for now.
            */
#if 1
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                /* Halve the byte location and continue. */
                targetByte = rangeLo + ((rangeHi - rangeLo)/2);
                rangeHi = targetByte;
            } else {
                break;
            }
#else
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                /* Halve the byte location and continue. */
                targetByte = rangeLo + ((rangeHi - rangeLo)/2);
                rangeHi = targetByte;
            } else {
                break;
            }
#endif
        }

        // we already tried this byte and there are no more to try, break out
        if(targetByte == lastTargetByte)
        {
            return DRFLAC_FALSE;
        }
    }

    /* The current PCM frame needs to be updated based on the frame we just seeked to. */
    drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);

    DRFLAC_ASSERT(targetByte <= rangeHi);

    *pLastSuccessfulSeekOffset = targetByte;
    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 offset)
{
    /* This section of code would be used if we were only decoding the FLAC frame header when calling drflac__seek_to_approximate_flac_frame_to_byte(). */
#if 0
    if (drflac__decode_flac_frame(pFlac) != DRFLAC_SUCCESS) {
        /* We failed to decode this frame which may be due to it being corrupt. We'll just use the next valid FLAC frame. */
        if (drflac__read_and_decode_next_flac_frame(pFlac) == DRFLAC_FALSE) {
            return DRFLAC_FALSE;
        }
    }
#endif

    return drflac__seek_forward_by_pcm_frames(pFlac, offset) == offset;
}


static drflac_bool32 drflac__seek_to_pcm_frame__binary_search_internal(drflac* pFlac, drflac_uint64 pcmFrameIndex, drflac_uint64 byteRangeLo, drflac_uint64 byteRangeHi)
{
    /* This assumes pFlac->currentPCMFrame is sitting on byteRangeLo upon entry. */

    drflac_uint64 targetByte;
    drflac_uint64 pcmRangeLo = pFlac->totalPCMFrameCount;
    drflac_uint64 pcmRangeHi = 0;
    drflac_uint64 lastSuccessfulSeekOffset = (drflac_uint64)-1;
    drflac_uint64 closestSeekOffsetBeforeTargetPCMFrame = byteRangeLo;
    drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;

    targetByte = byteRangeLo + (drflac_uint64)(((drflac_int64)((pcmFrameIndex - pFlac->currentPCMFrame) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO);
    if (targetByte > byteRangeHi) {
        targetByte = byteRangeHi;
    }

    for (;;) {
        if (drflac__seek_to_approximate_flac_frame_to_byte(pFlac, targetByte, byteRangeLo, byteRangeHi, &lastSuccessfulSeekOffset)) {
            /* We found a FLAC frame. We need to check if it contains the sample we're looking for. */
            drflac_uint64 newPCMRangeLo;
            drflac_uint64 newPCMRangeHi;
            drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &newPCMRangeLo, &newPCMRangeHi);

            /* If we selected the same frame, it means we should be pretty close. Just decode the rest. */
            if (pcmRangeLo == newPCMRangeLo) {
                if (!drflac__seek_to_approximate_flac_frame_to_byte(pFlac, closestSeekOffsetBeforeTargetPCMFrame, closestSeekOffsetBeforeTargetPCMFrame, byteRangeHi, &lastSuccessfulSeekOffset)) {
                    break;  /* Failed to seek to closest frame. */
                }

                if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
                    return DRFLAC_TRUE;
                } else {
                    break;  /* Failed to seek forward. */
                }
            }

            pcmRangeLo = newPCMRangeLo;
            pcmRangeHi = newPCMRangeHi;

            if (pcmRangeLo <= pcmFrameIndex && pcmRangeHi >= pcmFrameIndex) {
                /* The target PCM frame is in this FLAC frame. */
                if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame) ) {
                    return DRFLAC_TRUE;
                } else {
                    break;  /* Failed to seek to FLAC frame. */
                }
            } else {
                const float approxCompressionRatio = (drflac_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / ((drflac_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0f);

                if (pcmRangeLo > pcmFrameIndex) {
                    /* We seeked too far forward. We need to move our target byte backward and try again. */
                    byteRangeHi = lastSuccessfulSeekOffset;
                    if (byteRangeLo > byteRangeHi) {
                        byteRangeLo = byteRangeHi;
                    }

                    targetByte = byteRangeLo + ((byteRangeHi - byteRangeLo) / 2);
                    if (targetByte < byteRangeLo) {
                        targetByte = byteRangeLo;
                    }
                } else /*if (pcmRangeHi < pcmFrameIndex)*/ {
                    /* We didn't seek far enough. We need to move our target byte forward and try again. */

                    /* If we're close enough we can just seek forward. */
                    if ((pcmFrameIndex - pcmRangeLo) < seekForwardThreshold) {
                        if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
                            return DRFLAC_TRUE;
                        } else {
                            break;  /* Failed to seek to FLAC frame. */
                        }
                    } else {
                        byteRangeLo = lastSuccessfulSeekOffset;
                        if (byteRangeHi < byteRangeLo) {
                            byteRangeHi = byteRangeLo;
                        }

                        targetByte = lastSuccessfulSeekOffset + (drflac_uint64)(((drflac_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * approxCompressionRatio);
                        if (targetByte > byteRangeHi) {
                            targetByte = byteRangeHi;
                        }

                        if (closestSeekOffsetBeforeTargetPCMFrame < lastSuccessfulSeekOffset) {
                            closestSeekOffsetBeforeTargetPCMFrame = lastSuccessfulSeekOffset;
                        }
                    }
                }
            }
        } else {
            /* Getting here is really bad. We just recover as best we can, but moving to the first frame in the stream, and then abort. */
            break;
        }
    }

    drflac__seek_to_first_frame(pFlac); /* <-- Try to recover. */
    return DRFLAC_FALSE;
}

static drflac_bool32 drflac__seek_to_pcm_frame__binary_search(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_uint64 byteRangeLo;
    drflac_uint64 byteRangeHi;
    drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;

    /* Our algorithm currently assumes the FLAC stream is currently sitting at the start. */
    if (drflac__seek_to_first_frame(pFlac) == DRFLAC_FALSE) {
        return DRFLAC_FALSE;
    }

    /* If we're close enough to the start, just move to the start and seek forward. */
    if (pcmFrameIndex < seekForwardThreshold) {
        return drflac__seek_forward_by_pcm_frames(pFlac, pcmFrameIndex) == pcmFrameIndex;
    }

    /*
    Our starting byte range is the byte position of the first FLAC frame and the approximate end of the file as if it were completely uncompressed. This ensures
    the entire file is included, even though most of the time it'll exceed the end of the actual stream. This is OK as the frame searching logic will handle it.
    */
    byteRangeLo = pFlac->firstFLACFramePosInBytes;
    byteRangeHi = pFlac->firstFLACFramePosInBytes + (drflac_uint64)((drflac_int64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample)/8.0f);

    return drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi);
}
#endif  /* !DR_FLAC_NO_CRC */

static drflac_bool32 drflac__seek_to_pcm_frame__seek_table(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_uint32 iClosestSeekpoint = 0;
    drflac_bool32 isMidFrame = DRFLAC_FALSE;
    drflac_uint64 runningPCMFrameCount;
    drflac_uint32 iSeekpoint;


    DRFLAC_ASSERT(pFlac != NULL);

    if (pFlac->pSeekpoints == NULL || pFlac->seekpointCount == 0) {

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

            if (pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset >= pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset || pFlac->pSeekpoints[iNextSeekpoint].pcmFrameCount == 0) {
                return DRFLAC_FALSE;    /* The next seekpoint doesn't look right. The seek table cannot be trusted from here. Abort. */
            }

            if (pFlac->pSeekpoints[iNextSeekpoint].firstPCMFrame != (((drflac_uint64)0xFFFFFFFF << 32) | 0xFFFFFFFF)) { /* Make sure it's not a placeholder seekpoint. */
                byteRangeHi = pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset - 1; /* byteRangeHi must be zero based. */
            }
        }

        if (drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
            if (drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);

                if (drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi)) {
                    return DRFLAC_TRUE;
                }
            }
        }
    }
#endif  /* !DR_FLAC_NO_CRC */

    /* Getting here means we need to use a slower algorithm because the binary search method failed or cannot be used. */

    /*
    If we are seeking forward and the closest seekpoint is _before_ the current sample, we just seek forward from where we are. Otherwise we start seeking
    from the seekpoint's first sample.
    */
    if (pcmFrameIndex >= pFlac->currentPCMFrame && pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame <= pFlac->currentPCMFrame) {
        /* Optimized case. Just seek forward from where we are. */
        runningPCMFrameCount = pFlac->currentPCMFrame;

        /* The frame header for the first frame may not yet have been read. We need to do that if necessary. */
        if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                return DRFLAC_FALSE;
            }
        } else {
            isMidFrame = DRFLAC_TRUE;
        }
    } else {
        /* Slower case. Seek to the start of the seekpoint and then seek forward from there. */
        runningPCMFrameCount = pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame;

        if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
            return DRFLAC_FALSE;
        }

        /* Grab the frame the seekpoint is sitting on in preparation for the sample-exact seeking below. */
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }

    for (;;) {
        drflac_uint64 pcmFrameCountInThisFLACFrame;
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
        drflac_uint64 lastPCMFrameInFLACFrame = 0;

        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);

        pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
            /*
            The sample should be in this frame. We need to fully decode it, but if it's an invalid frame (a CRC mismatch) we need to pretend
            it never existed and keep iterating.
            */
            drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;

            if (!isMidFrame) {
                drflac_result result = drflac__decode_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
                    return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;  /* <-- If this fails, something bad has happened (it should never fail). */
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;   /* CRC mismatch. Pretend this frame never existed. */
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                /* We started seeking mid-frame which means we need to skip the frame decoding part. */
                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
            }
        } else {
            /*
            It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
            frame never existed and leave the running sample count untouched.
            */
            if (!isMidFrame) {
                drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;   /* CRC mismatch. Pretend this frame never existed. */
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                /*
                We started seeking mid-frame which means we need to seek by reading to the end of the frame instead of with
                drflac__seek_to_next_flac_frame() which only works if the decoder is sitting on the byte just after the frame header.
                */
                runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
                isMidFrame = DRFLAC_FALSE;
            }

            /* If we are seeking to the end of the file and we've just hit it, we're done. */
            if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
                return DRFLAC_TRUE;
            }
        }

    next_iteration:
        /* Grab the next frame in preparation for the next iteration. */
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }
}


#ifndef DR_FLAC_NO_OGG
typedef struct
{
    drflac_uint8 capturePattern[4];  /* Should be "OggS" */

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

    void* pUserDataMD;
    drflac_uint32 sampleRate;
    drflac_uint8  channels;
    drflac_uint8  bitsPerSample;
    drflac_uint64 totalPCMFrameCount;
    drflac_uint16 maxBlockSizeInPCMFrames;
    drflac_uint64 runningFilePos;
    drflac_bool32 hasStreamInfoBlock;
    drflac_bool32 hasMetadataBlocks;
    drflac_bs bs;                           /* <-- A bit streamer is required for loading data during initialization. */
    drflac_frame_header firstFrameHeader;   /* <-- The header of the first frame that was read during relaxed initalization. Only set if there is no STREAMINFO block. */

#ifndef DR_FLAC_NO_OGG
    drflac_uint32 oggSerial;
    drflac_uint64 oggFirstBytePos;
    drflac_ogg_page_header oggBosHeader;
#endif
} drflac_init_info;

static DRFLAC_INLINE void drflac__decode_block_header(drflac_uint32 blockHeader, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize)
{

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

        return DRFLAC_FALSE;
    }

    drflac__decode_block_header(blockHeader, isLastBlock, blockType, blockSize);
    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo)
{
    drflac_uint32 blockSizes;
    drflac_uint64 frameSizes = 0;
    drflac_uint64 importantProps;
    drflac_uint8 md5[16];

    /* min/max block size. */
    if (onRead(pUserData, &blockSizes, 4) != 4) {
        return DRFLAC_FALSE;
    }

    /* min/max frame size. */
    if (onRead(pUserData, &frameSizes, 6) != 6) {
        return DRFLAC_FALSE;
    }

    /* Sample rate, channels, bits per sample and total sample count. */
    if (onRead(pUserData, &importantProps, 8) != 8) {
        return DRFLAC_FALSE;
    }

    /* MD5 */
    if (onRead(pUserData, md5, sizeof(md5)) != sizeof(md5)) {
        return DRFLAC_FALSE;
    }

    blockSizes     = drflac__be2host_32(blockSizes);
    frameSizes     = drflac__be2host_64(frameSizes);
    importantProps = drflac__be2host_64(importantProps);

    pStreamInfo->minBlockSizeInPCMFrames = (drflac_uint16)((blockSizes & 0xFFFF0000) >> 16);
    pStreamInfo->maxBlockSizeInPCMFrames = (drflac_uint16) (blockSizes & 0x0000FFFF);
    pStreamInfo->minFrameSizeInPCMFrames = (drflac_uint32)((frameSizes     &  (((drflac_uint64)0x00FFFFFF << 16) << 24)) >> 40);
    pStreamInfo->maxFrameSizeInPCMFrames = (drflac_uint32)((frameSizes     &  (((drflac_uint64)0x00FFFFFF << 16) <<  0)) >> 16);
    pStreamInfo->sampleRate              = (drflac_uint32)((importantProps &  (((drflac_uint64)0x000FFFFF << 16) << 28)) >> 44);
    pStreamInfo->channels                = (drflac_uint8 )((importantProps &  (((drflac_uint64)0x0000000E << 16) << 24)) >> 41) + 1;
    pStreamInfo->bitsPerSample           = (drflac_uint8 )((importantProps &  (((drflac_uint64)0x0000001F << 16) << 20)) >> 36) + 1;
    pStreamInfo->totalPCMFrameCount      =                ((importantProps & ((((drflac_uint64)0x0000000F << 16) << 16) | 0xFFFFFFFF)));
    DRFLAC_COPY_MEMORY(pStreamInfo->md5, md5, sizeof(md5));

    return DRFLAC_TRUE;
}


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

    if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
        return DRFLAC_FALSE;
    }

    if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) {
        if (!relaxed) {
            /* We're opening in strict mode and the first block is not the STREAMINFO block. Error. */
            return DRFLAC_FALSE;
        } else {
            /*
            Relaxed mode. To open from here we need to just find the first frame and set the sample rate, etc. to whatever is defined
            for that frame.
            */
            pInit->hasStreamInfoBlock = DRFLAC_FALSE;
            pInit->hasMetadataBlocks  = DRFLAC_FALSE;

            if (!drflac__read_next_flac_frame_header(&pInit->bs, 0, &pInit->firstFrameHeader)) {
                return DRFLAC_FALSE;    /* Couldn't find a frame. */
            }

            if (pInit->firstFrameHeader.bitsPerSample == 0) {
                return DRFLAC_FALSE;    /* Failed to initialize because the first frame depends on the STREAMINFO block, which does not exist. */
            }

            pInit->sampleRate              = pInit->firstFrameHeader.sampleRate;
            pInit->channels                = drflac__get_channel_count_from_channel_assignment(pInit->firstFrameHeader.channelAssignment);
            pInit->bitsPerSample           = pInit->firstFrameHeader.bitsPerSample;
            pInit->maxBlockSizeInPCMFrames = 65535;   /* <-- See notes here: https://xiph.org/flac/format.html#metadata_block_streaminfo */
            return DRFLAC_TRUE;
        }
    } else {
        drflac_streaminfo streaminfo;

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

            if ((oggbs->currentPageHeader.headerType & 0x01) == 0) {
                return DRFLAC_TRUE;
            }
        } else {
            /* We're at the next packet. */
            return DRFLAC_TRUE;
        }
    }
}

static drflac_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs)
{
    /* The bitstream should be sitting on the first byte just after the header of the frame. */

    /* What we're actually doing here is seeking to the start of the next packet. */
    return drflac_oggbs__seek_to_next_packet(oggbs);
}
#endif

static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytesToRead)
{
    drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
    drflac_uint8* pRunningBufferOut = (drflac_uint8*)bufferOut;

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

        if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
            /* Failed to go to the next page. We either hit the end of the stream or had a CRC mismatch. */
            return DRFLAC_FALSE;
        }
    }

    return DRFLAC_TRUE;
}


static drflac_bool32 drflac_ogg__seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
    drflac_uint64 originalBytePos;
    drflac_uint64 runningGranulePosition;
    drflac_uint64 runningFrameBytePos;
    drflac_uint64 runningPCMFrameCount;

    DRFLAC_ASSERT(oggbs != NULL);

    originalBytePos = oggbs->currentBytePos;   /* For recovery. Points to the OggS identifier. */

    /* First seek to the first frame. */
    if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes)) {
        return DRFLAC_FALSE;
    }
    oggbs->bytesRemainingInPage = 0;

    runningGranulePosition = 0;
    for (;;) {
        if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
            drflac_oggbs__seek_physical(oggbs, originalBytePos, drflac_seek_origin_start);
            return DRFLAC_FALSE;   /* Never did find that sample... */

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

        /*
        At this point we know the sample is not in the previous page. It could possibly be in this page. For simplicity we
        disregard any pages that do not begin a fresh packet.
        */
        if ((oggbs->currentPageHeader.headerType & 0x01) == 0) {    /* <-- Is it a fresh page? */
            if (oggbs->currentPageHeader.segmentTable[0] >= 2) {
                drflac_uint8 firstBytesInPage[2];
                firstBytesInPage[0] = oggbs->pageData[0];
                firstBytesInPage[1] = oggbs->pageData[1];

                if ((firstBytesInPage[0] == 0xFF) && (firstBytesInPage[1] & 0xFC) == 0xF8) {    /* <-- Does the page begin with a frame's sync code? */
                    runningGranulePosition = oggbs->currentPageHeader.granulePosition;
                }

                continue;
            }
        }
    }

    /*
    We found the page that that is closest to the sample, so now we need to find it. The first thing to do is seek to the
    start of that page. In the loop above we checked that it was a fresh page which means this page is also the start of
    a new frame. This property means that after we've seeked to the page we can immediately start looping over frames until
    we find the one containing the target sample.
    */
    if (!drflac_oggbs__seek_physical(oggbs, runningFrameBytePos, drflac_seek_origin_start)) {
        return DRFLAC_FALSE;
    }
    if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
        return DRFLAC_FALSE;
    }

    /*
    At this point we'll be sitting on the first byte of the frame header of the first frame in the page. We just keep
    looping over these frames until we find the one containing the sample we're after.
    */
    runningPCMFrameCount = runningGranulePosition;
    for (;;) {
        /*
        There are two ways to find the sample and seek past irrelevant frames:
          1) Use the native FLAC decoder.
          2) Use Ogg's framing system.

        Both of these options have their own pros and cons. Using the native FLAC decoder is slower because it needs to
        do a full decode of the frame. Using Ogg's framing system is faster, but more complicated and involves some code
        duplication for the decoding of frame headers.

        Another thing to consider is that using the Ogg framing system will perform direct seeking of the physical Ogg
        bitstream. This is important to consider because it means we cannot read data from the drflac_bs object using the
        standard drflac__*() APIs because that will read in extra data for its own internal caching which in turn breaks
        the positioning of the read pointer of the physical Ogg bitstream. Therefore, anything that would normally be read
        using the native FLAC decoding APIs, such as drflac__read_next_flac_frame_header(), need to be re-implemented so as to
        avoid the use of the drflac_bs object.

        Considering these issues, I have decided to use the slower native FLAC decoding method for the following reasons:
          1) Seeking is already partially accelerated using Ogg's paging system in the code block above.
          2) Seeking in an Ogg encapsulated FLAC stream is probably quite uncommon.
          3) Simplicity.
        */
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
        drflac_uint64 lastPCMFrameInFLACFrame = 0;
        drflac_uint64 pcmFrameCountInThisFrame;

        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }

        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);

        pcmFrameCountInThisFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;

        /* If we are seeking to the end of the file and we've just hit it, we're done. */
        if (pcmFrameIndex == pFlac->totalPCMFrameCount && (runningPCMFrameCount + pcmFrameCountInThisFrame) == pFlac->totalPCMFrameCount) {
            drflac_result result = drflac__decode_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                pFlac->currentPCMFrame = pcmFrameIndex;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
                return DRFLAC_TRUE;
            } else {
                return DRFLAC_FALSE;
            }
        }

        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFrame)) {
            /*
            The sample should be in this FLAC frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend
            it never existed and keep iterating.
            */
            drflac_result result = drflac__decode_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
                drflac_uint64 pcmFramesToDecode = (size_t)(pcmFrameIndex - runningPCMFrameCount);    /* <-- Safe cast because the maximum number of samples in a frame is 65535. */
                if (pcmFramesToDecode == 0) {
                    return DRFLAC_TRUE;
                }

                pFlac->currentPCMFrame = runningPCMFrameCount;

                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;  /* <-- If this fails, something bad has happened (it should never fail). */
            } else {
                if (result == DRFLAC_CRC_MISMATCH) {
                    continue;   /* CRC mismatch. Pretend this frame never existed. */
                } else {
                    return DRFLAC_FALSE;
                }
            }
        } else {
            /*
            It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
            frame never existed and leave the running sample count untouched.
            */
            drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                runningPCMFrameCount += pcmFrameCountInThisFrame;
            } else {
                if (result == DRFLAC_CRC_MISMATCH) {
                    continue;   /* CRC mismatch. Pretend this frame never existed. */
                } else {
                    return DRFLAC_FALSE;
                }
            }
        }
    }
}



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

        allocationCallbacks.pUserData = NULL;
        allocationCallbacks.onMalloc  = drflac__malloc_default;
        allocationCallbacks.onRealloc = drflac__realloc_default;
        allocationCallbacks.onFree    = drflac__free_default;
    }


    /*
    The size of the allocation for the drflac object needs to be large enough to fit the following:
      1) The main members of the drflac structure
      2) A block of memory large enough to store the decoded samples of the largest frame in the stream
      3) If the container is Ogg, a drflac_oggbs object

    The complicated part of the allocation is making sure there's enough room the decoded samples, taking into consideration
    the different SIMD instruction sets.
    */
    allocationSize = sizeof(drflac);

    /*
    The allocation size for decoded frames depends on the number of 32-bit integers that fit inside the largest SIMD vector
    we are supporting.
    */
    if ((init.maxBlockSizeInPCMFrames % (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) == 0) {
        wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32)));
    } else {
        wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) + 1;
    }

    decodedSamplesAllocationSize = wholeSIMDVectorCountPerChannel * DRFLAC_MAX_SIMD_VECTOR_SIZE * init.channels;

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

                /* Failed to seek to the seektable. Ominous sign, but for now we can just pretend we don't have one. */
                pFlac->pSeekpoints = NULL;
                pFlac->seekpointCount = 0;
            }
        }
    }


    /*
    If we get here, but don't have a STREAMINFO block, it means we've opened the stream in relaxed mode and need to decode
    the first frame.
    */
    if (!init.hasStreamInfoBlock) {
        pFlac->currentFLACFrame.header = init.firstFrameHeader;
        for (;;) {
            drflac_result result = drflac__decode_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                break;
            } else {
                if (result == DRFLAC_CRC_MISMATCH) {
                    if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                        drflac__free_from_callbacks(pFlac, &allocationCallbacks);
                        return NULL;
                    }
                    continue;
                } else {
                    drflac__free_from_callbacks(pFlac, &allocationCallbacks);
                    return NULL;
                }
            }
        }

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

        }
    }
#endif
#endif

    drflac__free_from_callbacks(pFlac, &pFlac->allocationCallbacks);
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutpu...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int32)left0;
        pOutputSamples[i*8+1] = (drflac_int32)right0;
        pOutputSamples[i*8+2] = (drflac_int32)left1;
        pOutputSamples[i*8+3] = (drflac_int32)right1;
        pOutputSamples[i*8+4] = (drflac_int32)left2;
        pOutputSamples[i*8+5] = (drflac_int32)right2;
        pOutputSamples[i*8+6] = (drflac_int32)left3;
        pOutputSamples[i*8+7] = (drflac_int32)right3;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i right = _mm_sub_epi32(left, side);

        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t left;
        uint32x4_t side;
        uint32x4_t right;

        left  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        right = vsubq_u32(left, side);

        drflac__vst2q_u32((drflac_uint32*)pOutputSamples + i*8, vzipq_u32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutp...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputS...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int32)left0;
        pOutputSamples[i*8+1] = (drflac_int32)right0;
        pOutputSamples[i*8+2] = (drflac_int32)left1;
        pOutputSamples[i*8+3] = (drflac_int32)right1;
        pOutputSamples[i*8+4] = (drflac_int32)left2;
        pOutputSamples[i*8+5] = (drflac_int32)right2;
        pOutputSamples[i*8+6] = (drflac_int32)left3;
        pOutputSamples[i*8+7] = (drflac_int32)right3;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    for (i = 0; i < frameCount4; ++i) {
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i left  = _mm_add_epi32(right, side);

        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t side;
        uint32x4_t right;
        uint32x4_t left;

        side  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        right = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        left  = vaddq_u32(right, side);

        drflac__vst2q_u32((drflac_uint32*)pOutputSamples + i*8, vzipq_u32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutput...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

        mid = (mid << 1) | (side & 0x01);

        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_int32 shift = unusedBitsPerSample;

    if (shift > 0) {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;

            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;

            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);

            temp0L = (mid0 + side0) << shift;
            temp1L = (mid1 + side1) << shift;
            temp2L = (mid2 + side2) << shift;
            temp3L = (mid3 + side3) << shift;

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

            pOutputSamples[i*8+0] = (drflac_int32)temp0L;
            pOutputSamples[i*8+1] = (drflac_int32)temp0R;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R;
        }
    } else {
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;

            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;

            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);

            temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
            temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
            temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
            temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);

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

            pOutputSamples[i*8+1] = (drflac_int32)temp0R;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R;
        }
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

        mid = (mid << 1) | (side & 0x01);

        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_int32 shift = unusedBitsPerSample;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;

            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));

            left  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
            right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);

            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int32)(mid + side) >> 1;
            pOutputSamples[i*2+1] = (drflac_int32)(mid - side) >> 1;
        }
    } else {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;

            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));

            left  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
            right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);

            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
        }
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_int32 shift = unusedBitsPerSample;
    int32x4_t  wbpsShift0_4; /* wbps = Wasted Bits Per Sample */
    int32x4_t  wbpsShift1_4; /* wbps = Wasted Bits Per Sample */
    uint32x4_t one4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
    wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
    one4         = vdupq_n_u32(1);

    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;

            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);

            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, one4));

            left  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
            right = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);

            drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int32)(mid + side) >> 1;
            pOutputSamples[i*2+1] = (drflac_int32)(mid - side) >> 1;
        }
    } else {
        int32x4_t shift4;

        shift -= 1;
        shift4 = vdupq_n_s32(shift);

        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;

            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);

            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, one4));

            left  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
            right = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));

            drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
        }
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int3...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample));
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample));
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* ...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;

        pOutputSamples[i*8+0] = (drflac_int32)tempL0;
        pOutputSamples[i*8+1] = (drflac_int32)tempR0;
        pOutputSamples[i*8+2] = (drflac_int32)tempL1;
        pOutputSamples[i*8+3] = (drflac_int32)tempR1;
        pOutputSamples[i*8+4] = (drflac_int32)tempL2;
        pOutputSamples[i*8+5] = (drflac_int32)tempR2;
        pOutputSamples[i*8+6] = (drflac_int32)tempL3;
        pOutputSamples[i*8+7] = (drflac_int32)tempR3;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);

        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    int32x4_t shift4_0 = vdupq_n_s32(shift0);
    int32x4_t shift4_1 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        int32x4_t left;
        int32x4_t right;

        left  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift4_0));
        right = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift4_1));

        drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputS...
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut)
{
    drflac_uint64 framesRead;
    drflac_uint32 unusedBitsPerSample;

    if (pFlac == NULL || framesToRead == 0) {
        return 0;
    }

    if (pBufferOut == NULL) {
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
    }

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;

    framesRead = 0;
    while (framesToRead > 0) {
        /* If we've run out of samples in this frame, go to the next. */
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;  /* Couldn't read the next frame, so just break from the loop and return. */
            }
        } else {
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
            drflac_uint64 frameCountThisIteration = framesToRead;

            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
            }

            if (channelCount == 2) {
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;

                switch (pFlac->currentFLACFrame.header.channelAssignment)
                {
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
                    {
                        drflac_read_pcm_frames_s32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
                    {
                        drflac_read_pcm_frames_s32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
                    {
                        drflac_read_pcm_frames_s32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
                    default:
                    {
                        drflac_read_pcm_frames_s32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                }
            } else {
                /* Generic interleaving. */
                drflac_uint64 i;
                for (i = 0; i < frameCountThisIteration; ++i) {
                    unsigned int j;
                    for (j = 0; j < channelCount; ++j) {
                        pBufferOut[(i*channelCount)+j] = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
                    }
                }
            }

            framesRead                += frameCountThisIteration;
            pBufferOut                += frameCountThisIteration * channelCount;
            framesToRead              -= frameCountThisIteration;
            pFlac->currentPCMFrame    += frameCountThisIteration;
            pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
        }
    }

    return framesRead;
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutpu...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 right = left - side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int16)left0;
        pOutputSamples[i*8+1] = (drflac_int16)right0;
        pOutputSamples[i*8+2] = (drflac_int16)left1;
        pOutputSamples[i*8+3] = (drflac_int16)right1;
        pOutputSamples[i*8+4] = (drflac_int16)left2;
        pOutputSamples[i*8+5] = (drflac_int16)right2;
        pOutputSamples[i*8+6] = (drflac_int16)left3;
        pOutputSamples[i*8+7] = (drflac_int16)right3;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i right = _mm_sub_epi32(left, side);

        left  = _mm_srai_epi32(left,  16);
        right = _mm_srai_epi32(right, 16);

        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t left;
        uint32x4_t side;
        uint32x4_t right;

        left  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        right = vsubq_u32(left, side);

        left  = vshrq_n_u32(left,  16);
        right = vshrq_n_u32(right, 16);

        drflac__vst2q_u16((drflac_uint16*)pOutputSamples + i*8, vzip_u16(vmovn_u32(left), vmovn_u32(right)));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s16__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutp...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 left  = right + side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputS...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int16)left0;
        pOutputSamples[i*8+1] = (drflac_int16)right0;
        pOutputSamples[i*8+2] = (drflac_int16)left1;
        pOutputSamples[i*8+3] = (drflac_int16)right1;
        pOutputSamples[i*8+4] = (drflac_int16)left2;
        pOutputSamples[i*8+5] = (drflac_int16)right2;
        pOutputSamples[i*8+6] = (drflac_int16)left3;
        pOutputSamples[i*8+7] = (drflac_int16)right3;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    for (i = 0; i < frameCount4; ++i) {
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i left  = _mm_add_epi32(right, side);

        left  = _mm_srai_epi32(left,  16);
        right = _mm_srai_epi32(right, 16);

        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t side;
        uint32x4_t right;
        uint32x4_t left;

        side  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        right = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        left  = vaddq_u32(right, side);

        left  = vshrq_n_u32(left,  16);
        right = vshrq_n_u32(right, 16);

        drflac__vst2q_u16((drflac_uint16*)pOutputSamples + i*8, vzip_u16(vmovn_u32(left), vmovn_u32(right)));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s16__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutput...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        drflac_uint32 mid  = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

        mid = (mid << 1) | (side & 0x01);

        pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;

    if (shift > 0) {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;

            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;

            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);

            temp0L = (mid0 + side0) << shift;
            temp1L = (mid1 + side1) << shift;
            temp2L = (mid2 + side2) << shift;
            temp3L = (mid3 + side3) << shift;

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

            pOutputSamples[i*8+0] = (drflac_int16)temp0L;
            pOutputSamples[i*8+1] = (drflac_int16)temp0R;
            pOutputSamples[i*8+2] = (drflac_int16)temp1L;
            pOutputSamples[i*8+3] = (drflac_int16)temp1R;
            pOutputSamples[i*8+4] = (drflac_int16)temp2L;
            pOutputSamples[i*8+5] = (drflac_int16)temp2R;
            pOutputSamples[i*8+6] = (drflac_int16)temp3L;
            pOutputSamples[i*8+7] = (drflac_int16)temp3R;
        }
    } else {
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;

            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;

            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);

            temp0L = ((drflac_int32)(mid0 + side0) >> 1);
            temp1L = ((drflac_int32)(mid1 + side1) >> 1);
            temp2L = ((drflac_int32)(mid2 + side2) >> 1);
            temp3L = ((drflac_int32)(mid3 + side3) >> 1);

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

            pOutputSamples[i*8+1] = (drflac_int16)temp0R;
            pOutputSamples[i*8+2] = (drflac_int16)temp1L;
            pOutputSamples[i*8+3] = (drflac_int16)temp1R;
            pOutputSamples[i*8+4] = (drflac_int16)temp2L;
            pOutputSamples[i*8+5] = (drflac_int16)temp2R;
            pOutputSamples[i*8+6] = (drflac_int16)temp3L;
            pOutputSamples[i*8+7] = (drflac_int16)temp3R;
        }
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

        mid = (mid << 1) | (side & 0x01);

        pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;

            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));

            left  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
            right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);

            left  = _mm_srai_epi32(left,  16);
            right = _mm_srai_epi32(right, 16);

            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
        }
    } else {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;

            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));

            left  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
            right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);

            left  = _mm_srai_epi32(left,  16);
            right = _mm_srai_epi32(right, 16);

            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
        }
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;
    int32x4_t wbpsShift0_4; /* wbps = Wasted Bits Per Sample */
    int32x4_t wbpsShift1_4; /* wbps = Wasted Bits Per Sample */

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
    wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;

            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);

            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));

            left  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
            right = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);

            left  = vshrq_n_s32(left,  16);
            right = vshrq_n_s32(right, 16);

            drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
        }
    } else {
        int32x4_t shift4;

        shift -= 1;
        shift4 = vdupq_n_s32(shift);

        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;

            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);

            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));

            left  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
            right = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));

            left  = vshrq_n_s32(left,  16);
            right = vshrq_n_s32(right, 16);

            drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
        }
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s16__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int1...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) >> 16);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* ...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int16)tempL0;
        pOutputSamples[i*8+1] = (drflac_int16)tempR0;
        pOutputSamples[i*8+2] = (drflac_int16)tempL1;
        pOutputSamples[i*8+3] = (drflac_int16)tempR1;
        pOutputSamples[i*8+4] = (drflac_int16)tempL2;
        pOutputSamples[i*8+5] = (drflac_int16)tempR2;
        pOutputSamples[i*8+6] = (drflac_int16)tempL3;
        pOutputSamples[i*8+7] = (drflac_int16)tempR3;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);

        left  = _mm_srai_epi32(left,  16);
        right = _mm_srai_epi32(right, 16);

        /* At this point we have results. We can now pack and interleave these into a single __m128i object and then store the in the output buffer. */
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    int32x4_t shift0_4 = vdupq_n_s32(shift0);
    int32x4_t shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        int32x4_t left;
        int32x4_t right;

        left  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4));
        right = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4));

        left  = vshrq_n_s32(left,  16);
        right = vshrq_n_s32(right, 16);

        drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputS...
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s16__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}

DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut)
{
    drflac_uint64 framesRead;
    drflac_uint32 unusedBitsPerSample;

    if (pFlac == NULL || framesToRead == 0) {
        return 0;
    }

    if (pBufferOut == NULL) {
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
    }

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;

    framesRead = 0;
    while (framesToRead > 0) {
        /* If we've run out of samples in this frame, go to the next. */
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;  /* Couldn't read the next frame, so just break from the loop and return. */
            }
        } else {
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
            drflac_uint64 frameCountThisIteration = framesToRead;

            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
            }

            if (channelCount == 2) {
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;

                switch (pFlac->currentFLACFrame.header.channelAssignment)
                {
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
                    {
                        drflac_read_pcm_frames_s16__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
                    {
                        drflac_read_pcm_frames_s16__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
                    {
                        drflac_read_pcm_frames_s16__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
                    default:
                    {
                        drflac_read_pcm_frames_s16__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                }
            } else {
                /* Generic interleaving. */
                drflac_uint64 i;
                for (i = 0; i < frameCountThisIteration; ++i) {
                    unsigned int j;
                    for (j = 0; j < channelCount; ++j) {
                        drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
                        pBufferOut[(i*channelCount)+j] = (drflac_int16)(sampleS32 >> 16);
                    }
                }
            }

            framesRead                += frameCountThisIteration;
            pBufferOut                += frameCountThisIteration * channelCount;
            framesToRead              -= frameCountThisIteration;
            pFlac->currentPCMFrame    += frameCountThisIteration;
            pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
        }
    }

    return framesRead;
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSample...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (float)((drflac_int32)left  / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    float factor = 1 / 2147483648.0;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int32)left0  * factor;
        pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
        pOutputSamples[i*8+2] = (drflac_int32)left1  * factor;
        pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
        pOutputSamples[i*8+4] = (drflac_int32)left2  * factor;
        pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
        pOutputSamples[i*8+6] = (drflac_int32)left3  * factor;
        pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left  * factor;
        pOutputSamples[i*2+1] = (drflac_int32)right * factor;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    __m128 factor;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    factor = _mm_set1_ps(1.0f / 8388608.0f);

    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i right = _mm_sub_epi32(left, side);
        __m128 leftf  = _mm_mul_ps(_mm_cvtepi32_ps(left),  factor);
        __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);

        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    float32x4_t factor4;
    int32x4_t shift0_4;
    int32x4_t shift1_4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    factor4  = vdupq_n_f32(1.0f / 8388608.0f);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t left;
        uint32x4_t side;
        uint32x4_t right;
        float32x4_t leftf;
        float32x4_t rightf;

        left   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        side   = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        right  = vsubq_u32(left, side);
        leftf  = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(left)),  factor4);
        rightf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(right)), factor4);

        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_f32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSampl...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (float)((drflac_int32)left  / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    float factor = 1 / 2147483648.0;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int32)left0  * factor;
        pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
        pOutputSamples[i*8+2] = (drflac_int32)left1  * factor;
        pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
        pOutputSamples[i*8+4] = (drflac_int32)left2  * factor;
        pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
        pOutputSamples[i*8+6] = (drflac_int32)left3  * factor;
        pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left  * factor;
        pOutputSamples[i*2+1] = (drflac_int32)right * factor;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    __m128 factor;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    factor = _mm_set1_ps(1.0f / 8388608.0f);

    for (i = 0; i < frameCount4; ++i) {
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i left  = _mm_add_epi32(right, side);
        __m128 leftf  = _mm_mul_ps(_mm_cvtepi32_ps(left),  factor);
        __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);

        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    float32x4_t factor4;
    int32x4_t shift0_4;
    int32x4_t shift1_4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    factor4  = vdupq_n_f32(1.0f / 8388608.0f);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t side;
        uint32x4_t right;
        uint32x4_t left;
        float32x4_t leftf;
        float32x4_t rightf;

        side   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        right  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        left   = vaddq_u32(right, side);
        leftf  = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(left)),  factor4);
        rightf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(right)), factor4);

        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_f32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        drflac_uint32 mid  = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

        mid = (mid << 1) | (side & 0x01);

        pOutputSamples[i*2+0] = (float)((((drflac_int32)(mid + side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((((drflac_int32)(mid - side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;
    float factor = 1 / 2147483648.0;

    if (shift > 0) {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;

            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;

            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);

            temp0L = (mid0 + side0) << shift;
            temp1L = (mid1 + side1) << shift;
            temp2L = (mid2 + side2) << shift;
            temp3L = (mid3 + side3) << shift;

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

            pOutputSamples[i*8+0] = (drflac_int32)temp0L * factor;
            pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
        }
    } else {
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;

            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;

            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);

            temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
            temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
            temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
            temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);

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

            pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
        }
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

        mid = (mid << 1) | (side & 0x01);

        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) * factor;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample - 8;
    float factor;
    __m128 factor128;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    factor = 1.0f / 8388608.0f;
    factor128 = _mm_set1_ps(factor);

    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i tempL;
            __m128i tempR;
            __m128  leftf;
            __m128  rightf;

            mid    = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

            mid    = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));

            tempL  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
            tempR  = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);

            leftf  = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
            rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);

            _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
            _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
            pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
        }
    } else {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i tempL;
            __m128i tempR;
            __m128 leftf;
            __m128 rightf;

            mid    = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

            mid    = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));

            tempL  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
            tempR  = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);

            leftf  = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
            rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);

            _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
            _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
        }
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample - 8;
    float factor;
    float32x4_t factor4;
    int32x4_t shift4;
    int32x4_t wbps0_4;  /* Wasted Bits Per Sample */
    int32x4_t wbps1_4;  /* Wasted Bits Per Sample */

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    factor  = 1.0f / 8388608.0f;
    factor4 = vdupq_n_f32(factor);
    wbps0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
    wbps1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            int32x4_t lefti;
            int32x4_t righti;
            float32x4_t leftf;
            float32x4_t rightf;

            uint32x4_t mid  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbps0_4);
            uint32x4_t side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbps1_4);

            mid    = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));

            lefti  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
            righti = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);

            leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
            rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);

            drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
            pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
        }
    } else {
        shift -= 1;
        shift4 = vdupq_n_s32(shift);
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t lefti;
            int32x4_t righti;
            float32x4_t leftf;
            float32x4_t rightf;

            mid    = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbps0_4);
            side   = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbps1_4);

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


            lefti  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
            righti = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));

            leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
            rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);

            drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
        }
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_f32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}

#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOut...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (float)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) / 2147483648.0);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutput...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    float factor = 1 / 2147483648.0;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;

        pOutputSamples[i*8+0] = (drflac_int32)tempL0 * factor;
        pOutputSamples[i*8+1] = (drflac_int32)tempR0 * factor;
        pOutputSamples[i*8+2] = (drflac_int32)tempL1 * factor;
        pOutputSamples[i*8+3] = (drflac_int32)tempR1 * factor;
        pOutputSamples[i*8+4] = (drflac_int32)tempL2 * factor;
        pOutputSamples[i*8+5] = (drflac_int32)tempR2 * factor;
        pOutputSamples[i*8+6] = (drflac_int32)tempL3 * factor;
        pOutputSamples[i*8+7] = (drflac_int32)tempR3 * factor;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;

    float factor = 1.0f / 8388608.0f;
    __m128 factor128 = _mm_set1_ps(factor);

    for (i = 0; i < frameCount4; ++i) {
        __m128i lefti;
        __m128i righti;
        __m128 leftf;
        __m128 rightf;

        lefti  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        righti = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);

        leftf  = _mm_mul_ps(_mm_cvtepi32_ps(lefti),  factor128);
        rightf = _mm_mul_ps(_mm_cvtepi32_ps(righti), factor128);

        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;

    float factor = 1.0f / 8388608.0f;
    float32x4_t factor4 = vdupq_n_f32(factor);
    int32x4_t shift0_4  = vdupq_n_s32(shift0);
    int32x4_t shift1_4  = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        int32x4_t lefti;
        int32x4_t righti;
        float32x4_t leftf;
        float32x4_t rightf;

        lefti  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4));
        righti = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4));

        leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
        rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);

        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_f32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}

DRFLAC_API drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut)
{
    drflac_uint64 framesRead;
    drflac_uint32 unusedBitsPerSample;

    if (pFlac == NULL || framesToRead == 0) {
        return 0;
    }

    if (pBufferOut == NULL) {
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
    }

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;

    framesRead = 0;
    while (framesToRead > 0) {
        /* If we've run out of samples in this frame, go to the next. */
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;  /* Couldn't read the next frame, so just break from the loop and return. */
            }
        } else {
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
            drflac_uint64 frameCountThisIteration = framesToRead;

            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
            }

            if (channelCount == 2) {
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;

                switch (pFlac->currentFLACFrame.header.channelAssignment)
                {
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
                    {
                        drflac_read_pcm_frames_f32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
                    {
                        drflac_read_pcm_frames_f32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
                    {
                        drflac_read_pcm_frames_f32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
                    default:
                    {
                        drflac_read_pcm_frames_f32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                }
            } else {
                /* Generic interleaving. */
                drflac_uint64 i;
                for (i = 0; i < frameCountThisIteration; ++i) {
                    unsigned int j;
                    for (j = 0; j < channelCount; ++j) {
                        drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
                        pBufferOut[(i*channelCount)+j] = (float)(sampleS32 / 2147483648.0);
                    }
                }
            }

            framesRead                += frameCountThisIteration;
            pBufferOut                += frameCountThisIteration * channelCount;
            framesToRead              -= frameCountThisIteration;
            pFlac->currentPCMFrame    += frameCountThisIteration;
            pFlac->currentFLACFrame.pcmFramesRemaining -= (unsigned int)frameCountThisIteration;
        }
    }

    return framesRead;
}


DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    if (pFlac == NULL) {
        return DRFLAC_FALSE;
    }

    /* Don't do anything if we're already on the seek point. */
    if (pFlac->currentPCMFrame == pcmFrameIndex) {
        return DRFLAC_TRUE;
    }

    /*
    If we don't know where the first frame begins then we can't seek. This will happen when the STREAMINFO block was not present
    when the decoder was opened.
    */
    if (pFlac->firstFLACFramePosInBytes == 0) {
        return DRFLAC_FALSE;
    }

    if (pcmFrameIndex == 0) {
        pFlac->currentPCMFrame = 0;
        return drflac__seek_to_first_frame(pFlac);
    } else {
        drflac_bool32 wasSuccessful = DRFLAC_FALSE;

        /* Clamp the sample to the end. */
        if (pcmFrameIndex > pFlac->totalPCMFrameCount) {
            pcmFrameIndex = pFlac->totalPCMFrameCount;
        }

        /* If the target sample and the current sample are in the same frame we just move the position forward. */
        if (pcmFrameIndex > pFlac->currentPCMFrame) {
            /* Forward. */
            drflac_uint32 offset = (drflac_uint32)(pcmFrameIndex - pFlac->currentPCMFrame);
            if (pFlac->currentFLACFrame.pcmFramesRemaining >  offset) {
                pFlac->currentFLACFrame.pcmFramesRemaining -= offset;
                pFlac->currentPCMFrame = pcmFrameIndex;
                return DRFLAC_TRUE;
            }
        } else {
            /* Backward. */

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

            }
        }

        /*
        Different techniques depending on encapsulation. Using the native FLAC seektable with Ogg encapsulation is a bit awkward so
        we'll instead use Ogg's natural seeking facility.
        */
#ifndef DR_FLAC_NO_OGG
        if (pFlac->container == drflac_container_ogg)
        {
            wasSuccessful = drflac_ogg__seek_to_pcm_frame(pFlac, pcmFrameIndex);
        }
        else
#endif
        {
            /* First try seeking via the seek table. If this fails, fall back to a brute force seek which is much slower. */
            if (/*!wasSuccessful && */!pFlac->_noSeekTableSeek) {
                wasSuccessful = drflac__seek_to_pcm_frame__seek_table(pFlac, pcmFrameIndex);
            }

#if !defined(DR_FLAC_NO_CRC)
            /* Fall back to binary search if seek table seeking fails. This requires the length of the stream to be known. */
            if (!wasSuccessful && !pFlac->_noBinarySearchSeek && pFlac->totalPCMFrameCount > 0) {
                wasSuccessful = drflac__seek_to_pcm_frame__binary_search(pFlac, pcmFrameIndex);
            }
#endif

            /* Fall back to brute force if all else fails. */
            if (!wasSuccessful && !pFlac->_noBruteForceSeek) {
                wasSuccessful = drflac__seek_to_pcm_frame__brute_force(pFlac, pcmFrameIndex);
            }
        }

        pFlac->currentPCMFrame = pcmFrameIndex;
        return wasSuccessful;
    }
}



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

    if (totalPCMFrameCount == 0) {                                                                                                                                  \
        type buffer[4096];                                                                                                                                          \
        drflac_uint64 pcmFramesRead;                                                                                                                                \
        size_t sampleDataBufferSize = sizeof(buffer);                                                                                                               \
                                                                                                                                                                    \
        pSampleData = (type*)drflac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks);                                                      \
        if (pSampleData == NULL) {                                                                                                                                  \
            goto on_error;                                                                                                                                          \
        }                                                                                                                                                           \
                                                                                                                                                                    \
        while ((pcmFramesRead = (drflac_uint64)drflac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) {          \
            if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) {                                                   \
                type* pNewSampleData;                                                                                                                               \
                size_t newSampleDataBufferSize;                                                                                                                     \
                                                                                                                                                                    \
                newSampleDataBufferSize = sampleDataBufferSize * 2;                                                                                                 \
                pNewSampleData = (type*)drflac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks);    \
                if (pNewSampleData == NULL) {                                                                                                                       \
                    drflac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks);                                                                          \
                    goto on_error;                                                                                                                                  \
                }                                                                                                                                                   \

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

        drflac_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type);                                                                                   \
        if (dataSize > DRFLAC_SIZE_MAX) {                                                                                                                           \
            goto on_error;  /* The decoded data is too big. */                                                                                                      \
        }                                                                                                                                                           \
                                                                                                                                                                    \
        pSampleData = (type*)drflac__malloc_from_callbacks((size_t)dataSize, &pFlac->allocationCallbacks);    /* <-- Safe cast as per the check above. */           \
        if (pSampleData == NULL) {                                                                                                                                  \
            goto on_error;                                                                                                                                          \
        }                                                                                                                                                           \
                                                                                                                                                                    \
        totalPCMFrameCount = drflac_read_pcm_frames_##extension(pFlac, pFlac->totalPCMFrameCount, pSampleData);                                                     \
    }                                                                                                                                                               \
                                                                                                                                                                    \
    if (sampleRateOut) *sampleRateOut = pFlac->sampleRate;                                                                                                          \
    if (channelsOut) *channelsOut = pFlac->channels;                                                                                                                \
    if (totalPCMFrameCountOut) *totalPCMFrameCountOut = totalPCMFrameCount;                                                                                         \
                                                                                                                                                                    \
    drflac_close(pFlac);                                                                                                                                            \
    return pSampleData;                                                                                                                                             \
                                                                                                                                                                    \
on_error:                                                                                                                                                           \
    drflac_close(pFlac);                                                                                                                                            \
    return NULL;                                                                                                                                                    \
}

DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s32, drflac_int32)
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s16, drflac_int16)
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(f32, float)

DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_call...
{
    drflac* pFlac;

    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalPCMFrameCountOut) {

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

    }

    pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_s32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}

DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_call...
{
    drflac* pFlac;

    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalPCMFrameCountOut) {

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

    }

    pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_s16(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}

DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* ...
{
    drflac* pFlac;

    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalPCMFrameCountOut) {

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


    pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_f32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}

#ifndef DR_FLAC_NO_STDIO
DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;

    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {

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

    }

    pFlac = drflac_open_file(filename, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
}

DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;

    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {

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

    }

    pFlac = drflac_open_file(filename, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
}

DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;

    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {

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


    pFlac = drflac_open_file(filename, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_f32(pFlac, channels, sampleRate, totalPCMFrameCount);
}
#endif

DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;

    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {

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

    }

    pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
}

DRFLAC_API drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;

    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {

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

    }

    pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
}

DRFLAC_API float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;

    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {

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

  - API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
    routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs:
    - drflac_open()
    - drflac_open_relaxed()
    - drflac_open_with_metadata()
    - drflac_open_with_metadata_relaxed()
    - drflac_open_file()
    - drflac_open_file_with_metadata()
    - drflac_open_memory()
    - drflac_open_memory_with_metadata()
    - drflac_open_and_read_pcm_frames_s32()
    - drflac_open_and_read_pcm_frames_s16()
    - drflac_open_and_read_pcm_frames_f32()
    - drflac_open_file_and_read_pcm_frames_s32()
    - drflac_open_file_and_read_pcm_frames_s16()
    - drflac_open_file_and_read_pcm_frames_f32()
    - drflac_open_memory_and_read_pcm_frames_s32()
    - drflac_open_memory_and_read_pcm_frames_s16()
    - drflac_open_memory_and_read_pcm_frames_f32()
    Set this extra parameter to NULL to use defaults which is the same as the previous behaviour. Setting this NULL will use
    DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE.
  - Remove deprecated APIs:
    - drflac_read_s32()
    - drflac_read_s16()
    - drflac_read_f32()
    - drflac_seek_to_sample()
    - drflac_open_and_decode_s32()
    - drflac_open_and_decode_s16()
    - drflac_open_and_decode_f32()
    - drflac_open_and_decode_file_s32()
    - drflac_open_and_decode_file_s16()
    - drflac_open_and_decode_file_f32()
    - drflac_open_and_decode_memory_s32()
    - drflac_open_and_decode_memory_s16()
    - drflac_open_and_decode_memory_f32()
  - Remove drflac.totalSampleCount which is now replaced with drflac.totalPCMFrameCount. You can emulate drflac.totalSampleCount
    by doing pFlac->totalPCMFrameCount*pFlac->channels.
  - Rename drflac.currentFrame to drflac.currentFLACFrame to remove ambiguity with PCM frames.
  - Fix errors when seeking to the end of a stream.
  - Optimizations to seeking.
  - SSE improvements and optimizations.
  - ARM NEON optimizations.
  - Optimizations to drflac_read_pcm_frames_s16().
  - Optimizations to drflac_read_pcm_frames_s32().

v0.11.10 - 2019-06-26
  - Fix a compiler error.

v0.11.9 - 2019-06-16
  - Silence some ThreadSanitizer warnings.

v0.11.8 - 2019-05-21
  - Fix warnings.

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

  - Silence warnings with GCC.

v0.11.2 - 2019-03-10
  - Fix a warning.

v0.11.1 - 2019-02-17
  - Fix a potential bug with seeking.

v0.11.0 - 2018-12-16
  - API CHANGE: Deprecated drflac_read_s32(), drflac_read_s16() and drflac_read_f32() and replaced them with
    drflac_read_pcm_frames_s32(), drflac_read_pcm_frames_s16() and drflac_read_pcm_frames_f32(). The new APIs take
    and return PCM frame counts instead of sample counts. To upgrade you will need to change the input count by
    dividing it by the channel count, and then do the same with the return value.
  - API_CHANGE: Deprecated drflac_seek_to_sample() and replaced with drflac_seek_to_pcm_frame(). Same rules as
    the changes to drflac_read_*() apply.
  - API CHANGE: Deprecated drflac_open_and_decode_*() and replaced with drflac_open_*_and_read_*(). Same rules as
    the changes to drflac_read_*() apply.
  - Optimizations.

v0.10.0 - 2018-09-11
  - Remove the DR_FLAC_NO_WIN32_IO option and the Win32 file IO functionality. If you need to use Win32 file IO you
    need to do it yourself via the callback API.
  - Fix the clang build.
  - Fix undefined behavior.

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

  - Fix Clang build.
  - Start using major.minor.revision versioning.

v0.8g - 2018-04-19
  - Fix build on non-x86/x64 architectures.

v0.8f - 2018-02-02
  - Stop pretending to support changing rate/channels mid stream.

v0.8e - 2018-02-01
  - Fix a crash when the block size of a frame is larger than the maximum block size defined by the FLAC stream.
  - Fix a crash the the Rice partition order is invalid.

v0.8d - 2017-09-22
  - Add support for decoding streams with ID3 tags. ID3 tags are just skipped.

v0.8c - 2017-09-07
  - Fix warning on non-x86/x64 architectures.

v0.8b - 2017-08-19
  - Fix build on non-x86/x64 architectures.

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

  - Optimizations. This brings dr_flac back to about the same class of efficiency as the reference implementation.
  - Add support for custom implementations of malloc(), realloc(), etc.
  - Add CRC checking to Ogg encapsulated streams.
  - Fix VC++ 6 build. This is only for the C++ compiler. The C compiler is not currently supported.
  - Bug fixes.

v0.7 - 2017-07-23
  - Add support for opening a stream without a header block. To do this, use drflac_open_relaxed() / drflac_open_with_metadata_relaxed().

v0.6 - 2017-07-22
  - Add support for recovering from invalid frames. With this change, dr_flac will simply skip over invalid frames as if they
    never existed. Frames are checked against their sync code, the CRC-8 of the frame header and the CRC-16 of the whole frame.

v0.5 - 2017-07-16
  - Fix typos.
  - Change drflac_bool* types to unsigned.
  - Add CRC checking. This makes dr_flac slower, but can be disabled with #define DR_FLAC_NO_CRC.

v0.4f - 2017-03-10
  - Fix a couple of bugs with the bitstreaming code.

v0.4e - 2017-02-17

share/public_html/static/music_inc/src/drflac_cache.c  view on Meta::CPAN

    {
        printf("network_drflac: opened successfully\n");    
        ndrflac->pFlac = pFlac;        
        return ndrflac;  
    }
    free(ndrflac);
    return NULL;
}

/* returns of samples */
uint64_t network_drflac_read_pcm_frames_f32_mem(NetworkDrFlac *ndrflac, uint32_t start_pcm_frame, uint32_t desired_pcm_frames, float32_t *outFloat, NetworkDrFlac_Error *error)
{   
    drflac *pFlac = ndrflac->pFlac;
    ndrflac->error = error;    

    // seek to sample 
    printf("seek to %u\n", start_pcm_frame);
    const uint32_t currentPCMFrame32 = pFlac->currentPCMFrame;
    const drflac_bool32 seekres = drflac_seek_to_pcm_frame(pFlac, start_pcm_frame);
    
    if(!NDRFLAC_OK(ndrflac))
    {        
        printf("network_drflac_read_pcm_frames_f32_mem: failed seek_to_pcm_frame NOT OK current: %u desired: %u\n", currentPCMFrame32, start_pcm_frame);
        return 0;        
    }
    else if(!seekres)
    {
        printf("network_drflac_read_pcm_frames_f32_mem: seek failed current: %u desired: %u\n", currentPCMFrame32, start_pcm_frame);     
        error->code = NDRFLAC_GENERIC_ERROR;
        return 0;
    }   

    // decode to pcm
    float32_t *data = malloc(pFlac->channels*sizeof(float32_t)*desired_pcm_frames);
    uint32_t frames_decoded = drflac_read_pcm_frames_f32(pFlac, desired_pcm_frames, data);

    if(frames_decoded != desired_pcm_frames)
    {
        printf("network_drflac_read_pcm_frames_f32_mem: expected %u decoded %u\n", desired_pcm_frames, frames_decoded);
    }
    if(!NDRFLAC_OK(ndrflac))
    {
        printf("network_drflac_read_pcm_frames_f32_mem: failed read_pcm_frames_f32\n");
        free(data);
        return 0;
    }

    #ifdef NETWORK_DR_FLAC_FORCE_REDBOOK
    // resample
    if(pFlac->sampleRate != 44100)
    {
        printf("Converting samplerate from %u to %u\n", pFlac->sampleRate, 44100);
        ma_resampler_config config = ma_resampler_config_init(ma_format_f32, pFlac->channels, pFlac->sampleRate,  44100, ma_resample_algorithm_linear);
        ma_resampler resampler;
        ma_result result = ma_resampler_init(&config, &resampler);
        ma_uint64 frameCountIn  = frames_decoded;
        ma_uint64 frameCountOut = ma_resampler_get_expected_output_frame_count(&resampler, frameCountIn);
        float32_t *pFramesOut = malloc(frameCountOut*pFlac->channels*sizeof(float32_t));
        ma_result result_process = ma_resampler_process_pcm_frames(&resampler, data, &frameCountIn, pFramesOut, &frameCountOut);
        free(data);
        if (result_process != MA_SUCCESS)
        {
            printf("network_drflac_read_pcm_frames_f32_mem: failed read_pcm_frames_f32 resample\n");
            return 0;
        }
        data = pFramesOut;
        frames_decoded = frameCountOut;
    }
    #endif

    // deinterleave
    for(unsigned i = 0; i < frames_decoded; i++)
    {
        for(unsigned j = 0; j < pFlac->channels; j++)
        {            
            unsigned chanIndex = j*frames_decoded;
            float32_t sample = data[(i*pFlac->channels) + j];
            outFloat[chanIndex+i] = sample;
        }
    }
    printf("returning from start_pcm_frame: %u frames_decoded %u data %p\n", start_pcm_frame, frames_decoded, data);
    free(data);

    // return number of samples   
    return frames_decoded;
}

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

initializing the device.

When initializing the device you first need to configure it. The device configuration allows you to specify things like the format of the data delivered via
the callback, the size of the internal buffer and the ID of the device you want to emit or capture audio from.

Once you have the device configuration set up you can initialize the device. When initializing a device you need to allocate memory for the device object
beforehand. This gives the application complete control over how the memory is allocated. In the example below we initialize a playback device on the stack,
but you could allocate it on the heap if that suits your situation better.

    ```c
    void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
    {
        // In playback mode copy data to pOutput. In capture mode read data from pInput. In full-duplex mode, both
        // pOutput and pInput will be valid and you can move data from pInput into pOutput. Never process more than
        // frameCount frames.
    }

    int main()
    {
        ma_device_config config = ma_device_config_init(ma_device_type_playback);
        config.playback.format   = ma_format_f32;   // Set to ma_format_unknown to use the device's native format.
        config.playback.channels = 2;               // Set to 0 to use the device's native channel count.
        config.sampleRate        = 48000;           // Set to 0 to use the device's native sample rate.
        config.dataCallback      = data_callback;   // This function will be called when miniaudio needs more data.
        config.pUserData         = pMyCustomData;   // Can be accessed from the device object (device.pUserData).

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


        // Do something here. Probably your program's main loop.

        ma_device_uninit(&device);    // This will stop the device so no need to do that manually.
        return 0;
    }
    ```

In the example above, `data_callback()` is where audio data is written and read from the device. The idea is in playback mode you cause sound to be emitted
from the speakers by writing audio data to the output buffer (`pOutput` in the example). In capture mode you read data from the input buffer (`pInput`) to
extract sound captured by the microphone. The `frameCount` parameter tells you how many frames can be written to the output buffer and read from the input
buffer. A "frame" is one sample for each channel. For example, in a stereo stream (2 channels), one frame is 2 samples: one for the left, one for the right.
The channel count is defined by the device config. The size in bytes of an individual sample is defined by the sample format which is also specified in the
device config. Multi-channel audio data is always interleaved, which means the samples for each frame are stored next to each other in memory. For example, in
a stereo stream the first pair of samples will be the left and right samples for the first frame, the second pair of samples will be the left and right samples
for the second frame, etc.

The configuration of the device is defined by the `ma_device_config` structure. The config object is always initialized with `ma_device_config_init()`. It's
important to always initialize the config with this function as it initializes it with logical defaults and ensures your program doesn't break when new members
are added to the `ma_device_config` structure. The example above uses a fairly simple and standard device configuration. The call to `ma_device_config_init()`
takes a single parameter, which is whether or not the device is a playback, capture, duplex or loopback device (loopback devices are not supported on all
backends). The `config.playback.format` member sets the sample format which can be one of the following (all formats are native-endian):

    +---------------+----------------------------------------+---------------------------+
    | Symbol        | Description                            | Range                     |
    +---------------+----------------------------------------+---------------------------+

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

===========
miniaudio should work cleanly out of the box without the need to download or install any dependencies. See below for platform-specific details.


2.1. Windows
------------
The Windows build should compile cleanly on all popular compilers without the need to configure any include paths nor link to any libraries.

2.2. macOS and iOS
------------------
The macOS build should compile cleanly without the need to download any dependencies nor link to any libraries or frameworks. The iOS build needs to be
compiled as Objective-C and will need to link the relevant frameworks but should compile cleanly out of the box with Xcode. Compiling through the command line
requires linking to `-lpthread` and `-lm`.

Due to the way miniaudio links to frameworks at runtime, your application may not pass Apple's notarization process. To fix this there are two options. The
first is to use the `MA_NO_RUNTIME_LINKING` option, like so:

    ```c
    #ifdef __APPLE__
        #define MA_NO_RUNTIME_LINKING
    #endif 
    #define MINIAUDIO_IMPLEMENTATION
    #include "miniaudio.h"
    ```

This will require linking with `-framework CoreFoundation -framework CoreAudio -framework AudioUnit`. Alternatively, if you would rather keep using runtime
linking you can add the following to your entitlements.xcent file:

    ```
    <key>com.apple.security.cs.allow-dyld-environment-variables</key>
    <true/>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    ```


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

==============
This section defines common terms used throughout miniaudio. Unfortunately there is often ambiguity in the use of terms throughout the audio space, so this
section is intended to clarify how miniaudio uses each term.

3.1. Sample
-----------
A sample is a single unit of audio data. If the sample format is f32, then one sample is one 32-bit floating point number.

3.2. Frame / PCM Frame
----------------------
A frame is a group of samples equal to the number of channels. For a stereo stream a frame is 2 samples, a mono frame is 1 sample, a 5.1 surround sound frame
is 6 samples, etc. The terms "frame" and "PCM frame" are the same thing in miniaudio. Note that this is different to a compressed frame. If ever miniaudio
needs to refer to a compressed frame, such as a FLAC frame, it will always clarify what it's referring to with something like "FLAC frame".

3.3. Channel
------------
A stream of monaural audio that is emitted from an individual speaker in a speaker system, or received from an individual microphone in a microphone system. A
stereo stream has two channels (a left channel, and a right channel), a 5.1 surround sound system has 6 channels, etc. Some audio systems refer to a channel as
a complex audio stream that's mixed with other channels to produce the final mix - this is completely different to miniaudio's use of the term "channel" and
should not be confused.

3.4. Sample Rate
----------------
The sample rate in miniaudio is always expressed in Hz, such as 44100, 48000, etc. It's the number of PCM frames that are processed per second.

3.5. Formats
------------
Throughout miniaudio you will see references to different sample formats:

    +---------------+----------------------------------------+---------------------------+
    | Symbol        | Description                            | Range                     |
    +---------------+----------------------------------------+---------------------------+
    | ma_format_f32 | 32-bit floating point                  | [-1, 1]                   |
    | ma_format_s16 | 16-bit signed integer                  | [-32768, 32767]           |

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


When initializing a decoder, you can optionally pass in a pointer to a ma_decoder_config object (the NULL argument in the example above) which allows you to
configure the output format, channel count, sample rate and channel map:

    ```c
    ma_decoder_config config = ma_decoder_config_init(ma_format_f32, 2, 48000);
    ```

When passing in NULL for decoder config in `ma_decoder_init*()`, the output format will be the same as that defined by the decoding backend.

Data is read from the decoder as PCM frames. This will return the number of PCM frames actually read. If the return value is less than the requested number of
PCM frames it means you've reached the end:

    ```c
    ma_uint64 framesRead = ma_decoder_read_pcm_frames(pDecoder, pFrames, framesToRead);
    if (framesRead < framesToRead) {
        // Reached the end.
    }
    ```

You can also seek to a specific frame like so:

    ```c
    ma_result result = ma_decoder_seek_to_pcm_frame(pDecoder, targetFrame);
    if (result != MA_SUCCESS) {
        return false;   // An error occurred.
    }
    ```

If you want to loop back to the start, you can simply seek back to the first PCM frame:

    ```c
    ma_decoder_seek_to_pcm_frame(pDecoder, 0);
    ```

When loading a decoder, miniaudio uses a trial and error technique to find the appropriate decoding backend. This can be unnecessarily inefficient if the type
is already known. In this case you can use the `_wav`, `_mp3`, etc. varients of the aforementioned initialization APIs:

    ```c
    ma_decoder_init_wav()
    ma_decoder_init_mp3()
    ma_decoder_init_memory_wav()
    ma_decoder_init_memory_mp3()

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

When initializing an encoder you must specify a config which is initialized with `ma_encoder_config_init()`. Here you must specify the file type, the output
sample format, output channel count and output sample rate. The following file types are supported:

    +------------------------+-------------+
    | Enum                   | Description |
    +------------------------+-------------+
    | ma_resource_format_wav | WAV         |
    +------------------------+-------------+

If the format, channel count or sample rate is not supported by the output file type an error will be returned. The encoder will not perform data conversion so
you will need to convert it before outputting any audio data. To output audio data, use `ma_encoder_write_pcm_frames()`, like in the example below:

    ```c
    framesWritten = ma_encoder_write_pcm_frames(&encoder, pPCMFramesToWrite, framesToWrite);
    ```

Encoders must be uninitialized with `ma_encoder_uninit()`.


6. Data Conversion
==================
A data conversion API is included with miniaudio which supports the majority of data conversion requirements. This supports conversion between sample formats,
channel counts (with channel mapping) and sample rates.


6.1. Sample Format Conversion
-----------------------------
Conversion between sample formats is achieved with the `ma_pcm_*_to_*()`, `ma_pcm_convert()` and `ma_convert_pcm_frames_format()` APIs. Use `ma_pcm_*_to_*()`
to convert between two specific formats. Use `ma_pcm_convert()` to convert based on a `ma_format` variable. Use `ma_convert_pcm_frames_format()` to convert
PCM frames where you want to specify the frame count and channel count as a variable instead of the total sample count.


6.1.1. Dithering
----------------
Dithering can be set using the ditherMode parameter.

The different dithering modes include the following, in order of efficiency:

    +-----------+--------------------------+
    | Type      | Enum Token               |

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

        2,                              // Output channels
        NULL,                           // Output channel map
        ma_channel_mix_mode_default);   // The mixing algorithm to use when combining channels.

    result = ma_channel_converter_init(&config, &converter);
    if (result != MA_SUCCESS) {
        // Error.
    }
    ```

To perform the conversion simply call `ma_channel_converter_process_pcm_frames()` like so:

    ```c
    ma_result result = ma_channel_converter_process_pcm_frames(&converter, pFramesOut, pFramesIn, frameCount);
    if (result != MA_SUCCESS) {
        // Error.
    }
    ```

It is up to the caller to ensure the output buffer is large enough to accomodate the new PCM frames.

Input and output PCM frames are always interleaved. Deinterleaved layouts are not supported.


6.2.1. Channel Mapping
----------------------
In addition to converting from one channel count to another, like the example above, the channel converter can also be used to rearrange channels. When
initializing the channel converter, you can optionally pass in channel maps for both the input and output frames. If the channel counts are the same, and each
channel map contains the same channel positions with the exception that they're in a different order, a simple shuffling of the channels will be performed. If,
however, there is not a 1:1 mapping of channel positions, or the channel counts differ, the input channels will be mixed based on a mixing mode which is
specified when initializing the `ma_channel_converter_config` object.

When converting from mono to multi-channel, the mono channel is simply copied to each output channel. When going the other way around, the audio of each output
channel is simply averaged and copied to the mono channel.

In more complicated cases blending is used. The `ma_channel_mix_mode_simple` mode will drop excess channels and silence extra channels. For example, converting
from 4 to 2 channels, the 3rd and 4th channels will be dropped, whereas converting from 2 to 4 channels will put silence into the 3rd and 4th channels.

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


Do the following to uninitialize the resampler:

    ```c
    ma_resampler_uninit(&resampler);
    ```

The following example shows how data can be processed

    ```c
    ma_uint64 frameCountIn  = 1000;
    ma_uint64 frameCountOut = 2000;
    ma_result result = ma_resampler_process_pcm_frames(&resampler, pFramesIn, &frameCountIn, pFramesOut, &frameCountOut);
    if (result != MA_SUCCESS) {
        // An error occurred...
    }

    // At this point, frameCountIn contains the number of input frames that were consumed and frameCountOut contains the
    // number of output frames written.
    ```

To initialize the resampler you first need to set up a config (`ma_resampler_config`) with `ma_resampler_config_init()`. You need to specify the sample format
you want to use, the number of channels, the input and output sample rate, and the algorithm.

The sample format can be either `ma_format_s16` or `ma_format_f32`. If you need a different format you will need to perform pre- and post-conversions yourself
where necessary. Note that the format is the same for both input and output. The format cannot be changed after initialization.

The resampler supports multiple channels and is always interleaved (both input and output). The channel count cannot be changed after initialization.

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

    | Linear    | ma_resample_algorithm_linear |
    | Speex     | ma_resample_algorithm_speex  |
    +-----------+------------------------------+

Because Speex is not public domain it is strictly opt-in and the code is stored in separate files. if you opt-in to the Speex backend you will need to consider
it's license, the text of which can be found in it's source files in "extras/speex_resampler". Details on how to opt-in to the Speex resampler is explained in
the Speex Resampler section below.

The algorithm cannot be changed after initialization.

Processing always happens on a per PCM frame basis and always assumes interleaved input and output. De-interleaved processing is not supported. To process
frames, use `ma_resampler_process_pcm_frames()`. On input, this function takes the number of output frames you can fit in the output buffer and the number of
input frames contained in the input buffer. On output these variables contain the number of output frames that were written to the output buffer and the
number of input frames that were consumed in the process. You can pass in NULL for the input buffer in which case it will be treated as an infinitely large
buffer of zeros. The output buffer can also be NULL, in which case the processing will be treated as seek.

The sample rate can be changed dynamically on the fly. You can change this with explicit sample rates with `ma_resampler_set_rate()` and also with a decimal
ratio with `ma_resampler_set_rate_ratio()`. The ratio is in/out.

Sometimes it's useful to know exactly how many input frames will be required to output a specific number of frames. You can calculate this with
`ma_resampler_get_required_input_frame_count()`. Likewise, it's sometimes useful to know exactly how many frames would be output given a certain number of
input frames. You can do this with `ma_resampler_get_expected_output_frame_count()`.

Due to the nature of how resampling works, the resampler introduces some latency. This can be retrieved in terms of both the input rate and the output rate
with `ma_resampler_get_input_latency()` and `ma_resampler_get_output_latency()`.


6.3.1. Resampling Algorithms
----------------------------
The choice of resampling algorithm depends on your situation and requirements. The linear resampler is the most efficient and has the least amount of latency,
but at the expense of poorer quality. The Speex resampler is higher quality, but slower with more latency. It also performs several heap allocations internally
for memory management.

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


Do the following to uninitialize the data converter:

    ```c
    ma_data_converter_uninit(&converter);
    ```

The following example shows how data can be processed

    ```c
    ma_uint64 frameCountIn  = 1000;
    ma_uint64 frameCountOut = 2000;
    ma_result result = ma_data_converter_process_pcm_frames(&converter, pFramesIn, &frameCountIn, pFramesOut, &frameCountOut);
    if (result != MA_SUCCESS) {
        // An error occurred...
    }

    // At this point, frameCountIn contains the number of input frames that were consumed and frameCountOut contains the number
    // of output frames written.
    ```

The data converter supports multiple channels and is always interleaved (both input and output). The channel count cannot be changed after initialization.

Sample rates can be anything other than zero, and are always specified in hertz. They should be set to something like 44100, etc. The sample rate is the only
configuration property that can be changed after initialization, but only if the `resampling.allowDynamicSampleRate` member of `ma_data_converter_config` is
set to MA_TRUE. To change the sample rate, use `ma_data_converter_set_rate()` or `ma_data_converter_set_rate_ratio()`. The ratio must be in/out. The resampling
algorithm cannot be changed after initialization.

Processing always happens on a per PCM frame basis and always assumes interleaved input and output. De-interleaved processing is not supported. To process
frames, use `ma_data_converter_process_pcm_frames()`. On input, this function takes the number of output frames you can fit in the output buffer and the number
of input frames contained in the input buffer. On output these variables contain the number of output frames that were written to the output buffer and the
number of input frames that were consumed in the process. You can pass in NULL for the input buffer in which case it will be treated as an infinitely large
buffer of zeros. The output buffer can also be NULL, in which case the processing will be treated as seek.

Sometimes it's useful to know exactly how many input frames will be required to output a specific number of frames. You can calculate this with
`ma_data_converter_get_required_input_frame_count()`. Likewise, it's sometimes useful to know exactly how many frames would be output given a certain number of
input frames. You can do this with `ma_data_converter_get_expected_output_frame_count()`.

Due to the nature of how resampling works, the data converter introduces some latency if resampling is required. This can be retrieved in terms of both the
input rate and the output rate with `ma_data_converter_get_input_latency()` and `ma_data_converter_get_output_latency()`.



7. Filtering
============

7.1. Biquad Filtering

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


    ```c
    ma_biquad_config config = ma_biquad_config_init(ma_format_f32, channels, b0, b1, b2, a0, a1, a2);
    ma_result result = ma_biquad_init(&config, &biquad);
    if (result != MA_SUCCESS) {
        // Error.
    }

    ...

    ma_biquad_process_pcm_frames(&biquad, pFramesOut, pFramesIn, frameCount);
    ```

Biquad filtering is implemented using transposed direct form 2. The numerator coefficients are b0, b1 and b2, and the denominator coefficients are a0, a1 and
a2. The a0 coefficient is required and coefficients must not be pre-normalized.

Supported formats are `ma_format_s16` and `ma_format_f32`. If you need to use a different format you need to convert it yourself beforehand. When using
`ma_format_s16` the biquad filter will use fixed point arithmetic. When using `ma_format_f32`, floating point arithmetic will be used.

Input and output frames are always interleaved.

Filtering can be applied in-place by passing in the same pointer for both the input and output buffers, like so:

    ```c
    ma_biquad_process_pcm_frames(&biquad, pMyData, pMyData, frameCount);
    ```

If you need to change the values of the coefficients, but maintain the values in the registers you can do so with `ma_biquad_reinit()`. This is useful if you
need to change the properties of the filter while keeping the values of registers valid to avoid glitching. Do not use `ma_biquad_init()` for this as it will
do a full initialization which involves clearing the registers to 0. Note that changing the format or channel count after initialization is invalid and will
result in an error.


7.2. Low-Pass Filtering
-----------------------

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


    ```c
    ma_lpf_config config = ma_lpf_config_init(ma_format_f32, channels, sampleRate, cutoffFrequency, order);
    ma_result result = ma_lpf_init(&config, &lpf);
    if (result != MA_SUCCESS) {
        // Error.
    }

    ...

    ma_lpf_process_pcm_frames(&lpf, pFramesOut, pFramesIn, frameCount);
    ```

Supported formats are `ma_format_s16` and` ma_format_f32`. If you need to use a different format you need to convert it yourself beforehand. Input and output
frames are always interleaved.

Filtering can be applied in-place by passing in the same pointer for both the input and output buffers, like so:

    ```c
    ma_lpf_process_pcm_frames(&lpf, pMyData, pMyData, frameCount);
    ```

The maximum filter order is limited to MA_MAX_FILTER_ORDER which is set to 8. If you need more, you can chain first and second order filters together.

    ```c
    for (iFilter = 0; iFilter < filterCount; iFilter += 1) {
        ma_lpf2_process_pcm_frames(&lpf2[iFilter], pMyData, pMyData, frameCount);
    }
    ```

If you need to change the configuration of the filter, but need to maintain the state of internal registers you can do so with `ma_lpf_reinit()`. This may be
useful if you need to change the sample rate and/or cutoff frequency dynamically while maintaing smooth transitions. Note that changing the format or channel
count after initialization is invalid and will result in an error.

The `ma_lpf` object supports a configurable order, but if you only need a first order filter you may want to consider using `ma_lpf1`. Likewise, if you only
need a second order filter you can use `ma_lpf2`. The advantage of this is that they're lighter weight and a bit more efficient.

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

        frequency);

    ma_waveform waveform;
    ma_result result = ma_waveform_init(&config, &waveform);
    if (result != MA_SUCCESS) {
        // Error.
    }

    ...

    ma_waveform_read_pcm_frames(&waveform, pOutput, frameCount);
    ```

The amplitude, frequency and sample rate can be changed dynamically with `ma_waveform_set_amplitude()`, `ma_waveform_set_frequency()` and
`ma_waveform_set_sample_rate()` respectively.

You can invert the waveform by setting the amplitude to a negative value. You can use this to control whether or not a sawtooth has a positive or negative
ramp, for example.

Below are the supported waveform types:

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

        amplitude);

    ma_noise noise;
    ma_result result = ma_noise_init(&config, &noise);
    if (result != MA_SUCCESS) {
        // Error.
    }

    ...

    ma_noise_read_pcm_frames(&noise, pOutput, frameCount);
    ```

The noise API uses simple LCG random number generation. It supports a custom seed which is useful for things like automated testing requiring reproducibility.
Setting the seed to zero will default to MA_DEFAULT_LCG_SEED.

By default, the noise API will use different values for different channels. So, for example, the left side in a stereo stream will be different to the right
side. To instead have each channel use the same random value, set the `duplicateChannels` member of the noise config to true, like so:

    ```c
    config.duplicateChannels = MA_TRUE;

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

    }

    ...
    
    ma_audio_buffer_uninit_and_free(&buffer);
    ```

If you initialize the buffer with `ma_audio_buffer_alloc_and_init()` you should uninitialize it with `ma_audio_buffer_uninit_and_free()`. In the example above,
the memory pointed to by `pExistingData` will be copied into the buffer, which is contrary to the behavior of `ma_audio_buffer_init()`.

An audio buffer has a playback cursor just like a decoder. As you read frames from the buffer, the cursor moves forward. The last parameter (`loop`) can be
used to determine if the buffer should loop. The return value is the number of frames actually read. If this is less than the number of frames requested it
means the end has been reached. This should never happen if the `loop` parameter is set to true. If you want to manually loop back to the start, you can do so
with with `ma_audio_buffer_seek_to_pcm_frame(pAudioBuffer, 0)`. Below is an example for reading data from an audio buffer.

    ```c
    ma_uint64 framesRead = ma_audio_buffer_read_pcm_frames(pAudioBuffer, pFramesOut, desiredFrameCount, isLooping);
    if (framesRead < desiredFrameCount) {
        // If not looping, this means the end has been reached. This should never happen in looping mode with valid input.
    }
    ```

Sometimes you may want to avoid the cost of data movement between the internal buffer and the output buffer. Instead you can use memory mapping to retrieve a
pointer to a segment of data:

    ```c
    void* pMappedFrames;
    ma_uint64 frameCount = frameCountToTryMapping;
    ma_result result = ma_audio_buffer_map(pAudioBuffer, &pMappedFrames, &frameCount);
    if (result == MA_SUCCESS) {
        // Map was successful. The value in frameCount will be how many frames were _actually_ mapped, which may be
        // less due to the end of the buffer being reached.
        ma_copy_pcm_frames(pFramesOut, pMappedFrames, frameCount, pAudioBuffer->format, pAudioBuffer->channels);

        // You must unmap the buffer.
        ma_audio_buffer_unmap(pAudioBuffer, frameCount);
    }
    ```

When you use memory mapping, the read cursor is increment by the frame count passed in to `ma_audio_buffer_unmap()`. If you decide not to process every frame
you can pass in a value smaller than the value returned by `ma_audio_buffer_map()`. The disadvantage to using memory mapping is that it does not handle looping
for you. You can determine if the buffer is at the end for the purpose of looping with `ma_audio_buffer_at_end()` or by inspecting the return value of
`ma_audio_buffer_unmap()` and checking if it equals `MA_AT_END`. You should not treat `MA_AT_END` as an error when returned by `ma_audio_buffer_unmap()`.



10. Ring Buffers
================
miniaudio supports lock free (single producer, single consumer) ring buffers which are exposed via the `ma_rb` and `ma_pcm_rb` APIs. The `ma_rb` API operates
on bytes, whereas the `ma_pcm_rb` operates on PCM frames. They are otherwise identical as `ma_pcm_rb` is just a wrapper around `ma_rb`.

Unlike most other APIs in miniaudio, ring buffers support both interleaved and deinterleaved streams. The caller can also allocate their own backing memory for
the ring buffer to use internally for added flexibility. Otherwise the ring buffer will manage it's internal memory for you.

The examples below use the PCM frame variant of the ring buffer since that's most likely the one you will want to use. To initialize a ring buffer, do
something like the following:

    ```c
    ma_pcm_rb rb;
    ma_result result = ma_pcm_rb_init(FORMAT, CHANNELS, BUFFER_SIZE_IN_FRAMES, NULL, NULL, &rb);
    if (result != MA_SUCCESS) {
        // Error
    }
    ```

The `ma_pcm_rb_init()` function takes the sample format and channel count as parameters because it's the PCM varient of the ring buffer API. For the regular
ring buffer that operates on bytes you would call `ma_rb_init()` which leaves these out and just takes the size of the buffer in bytes instead of frames. The
fourth parameter is an optional pre-allocated buffer and the fifth parameter is a pointer to a `ma_allocation_callbacks` structure for custom memory allocation
routines. Passing in `NULL` for this results in `MA_MALLOC()` and `MA_FREE()` being used.

Use `ma_pcm_rb_init_ex()` if you need a deinterleaved buffer. The data for each sub-buffer is offset from each other based on the stride. To manage your
sub-buffers you can use `ma_pcm_rb_get_subbuffer_stride()`, `ma_pcm_rb_get_subbuffer_offset()` and `ma_pcm_rb_get_subbuffer_ptr()`.

Use 'ma_pcm_rb_acquire_read()` and `ma_pcm_rb_acquire_write()` to retrieve a pointer to a section of the ring buffer. You specify the number of frames you
need, and on output it will set to what was actually acquired. If the read or write pointer is positioned such that the number of frames requested will require
a loop, it will be clamped to the end of the buffer. Therefore, the number of frames you're given may be less than the number you requested.

After calling `ma_pcm_rb_acquire_read()` or `ma_pcm_rb_acquire_write()`, you do your work on the buffer and then "commit" it with `ma_pcm_rb_commit_read()` or
`ma_pcm_rb_commit_write()`. This is where the read/write pointers are updated. When you commit you need to pass in the buffer that was returned by the earlier
call to `ma_pcm_rb_acquire_read()` or `ma_pcm_rb_acquire_write()` and is only used for validation. The number of frames passed to `ma_pcm_rb_commit_read()` and
`ma_pcm_rb_commit_write()` is what's used to increment the pointers.

If you want to correct for drift between the write pointer and the read pointer you can use a combination of `ma_pcm_rb_pointer_distance()`,
`ma_pcm_rb_seek_read()` and `ma_pcm_rb_seek_write()`. Note that you can only move the pointers forward, and you should only move the read pointer forward via
the consumer thread, and the write pointer forward by the producer thread. If there is too much space between the pointers, move the read pointer forward. If
there is too little space between the pointers, move the write pointer forward.

You can use a ring buffer at the byte level instead of the PCM frame level by using the `ma_rb` API. This is exactly the same, only you will use the `ma_rb`
functions instead of `ma_pcm_rb` and instead of frame counts you will pass around byte counts.

The maximum size of the buffer in bytes is `0x7FFFFFFF-(MA_SIMD_ALIGNMENT-1)` due to the most significant bit being used to encode a loop flag and the internally
managed buffers always being aligned to MA_SIMD_ALIGNMENT.

Note that the ring buffer is only thread safe when used by a single consumer thread and single producer thread.



11. Backends
============

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

    ma_biquad_coefficient b1;
    ma_biquad_coefficient b2;
    ma_biquad_coefficient a1;
    ma_biquad_coefficient a2;
    ma_biquad_coefficient r1[MA_MAX_CHANNELS];
    ma_biquad_coefficient r2[MA_MAX_CHANNELS];
} ma_biquad;

MA_API ma_result ma_biquad_init(const ma_biquad_config* pConfig, ma_biquad* pBQ);
MA_API ma_result ma_biquad_reinit(const ma_biquad_config* pConfig, ma_biquad* pBQ);
MA_API ma_result ma_biquad_process_pcm_frames(ma_biquad* pBQ, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_biquad_get_latency(ma_biquad* pBQ);


/**************************************************************************************************************************************************************

Low-Pass Filtering

**************************************************************************************************************************************************************/
typedef struct
{

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

typedef struct
{
    ma_format format;
    ma_uint32 channels;
    ma_biquad_coefficient a;
    ma_biquad_coefficient r1[MA_MAX_CHANNELS];
} ma_lpf1;

MA_API ma_result ma_lpf1_init(const ma_lpf1_config* pConfig, ma_lpf1* pLPF);
MA_API ma_result ma_lpf1_reinit(const ma_lpf1_config* pConfig, ma_lpf1* pLPF);
MA_API ma_result ma_lpf1_process_pcm_frames(ma_lpf1* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_lpf1_get_latency(ma_lpf1* pLPF);

typedef struct
{
    ma_biquad bq;   /* The second order low-pass filter is implemented as a biquad filter. */
} ma_lpf2;

MA_API ma_result ma_lpf2_init(const ma_lpf2_config* pConfig, ma_lpf2* pLPF);
MA_API ma_result ma_lpf2_reinit(const ma_lpf2_config* pConfig, ma_lpf2* pLPF);
MA_API ma_result ma_lpf2_process_pcm_frames(ma_lpf2* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_lpf2_get_latency(ma_lpf2* pLPF);


typedef struct
{
    ma_format format;
    ma_uint32 channels;
    ma_uint32 sampleRate;
    double cutoffFrequency;
    ma_uint32 order;    /* If set to 0, will be treated as a passthrough (no filtering will be applied). */

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

    ma_uint32 channels;
    ma_uint32 sampleRate;
    ma_uint32 lpf1Count;
    ma_uint32 lpf2Count;
    ma_lpf1 lpf1[1];
    ma_lpf2 lpf2[MA_MAX_FILTER_ORDER/2];
} ma_lpf;

MA_API ma_result ma_lpf_init(const ma_lpf_config* pConfig, ma_lpf* pLPF);
MA_API ma_result ma_lpf_reinit(const ma_lpf_config* pConfig, ma_lpf* pLPF);
MA_API ma_result ma_lpf_process_pcm_frames(ma_lpf* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_lpf_get_latency(ma_lpf* pLPF);


/**************************************************************************************************************************************************************

High-Pass Filtering

**************************************************************************************************************************************************************/
typedef struct
{

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

typedef struct
{
    ma_format format;
    ma_uint32 channels;
    ma_biquad_coefficient a;
    ma_biquad_coefficient r1[MA_MAX_CHANNELS];
} ma_hpf1;

MA_API ma_result ma_hpf1_init(const ma_hpf1_config* pConfig, ma_hpf1* pHPF);
MA_API ma_result ma_hpf1_reinit(const ma_hpf1_config* pConfig, ma_hpf1* pHPF);
MA_API ma_result ma_hpf1_process_pcm_frames(ma_hpf1* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_hpf1_get_latency(ma_hpf1* pHPF);

typedef struct
{
    ma_biquad bq;   /* The second order high-pass filter is implemented as a biquad filter. */
} ma_hpf2;

MA_API ma_result ma_hpf2_init(const ma_hpf2_config* pConfig, ma_hpf2* pHPF);
MA_API ma_result ma_hpf2_reinit(const ma_hpf2_config* pConfig, ma_hpf2* pHPF);
MA_API ma_result ma_hpf2_process_pcm_frames(ma_hpf2* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_hpf2_get_latency(ma_hpf2* pHPF);


typedef struct
{
    ma_format format;
    ma_uint32 channels;
    ma_uint32 sampleRate;
    double cutoffFrequency;
    ma_uint32 order;    /* If set to 0, will be treated as a passthrough (no filtering will be applied). */

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

    ma_uint32 channels;
    ma_uint32 sampleRate;
    ma_uint32 hpf1Count;
    ma_uint32 hpf2Count;
    ma_hpf1 hpf1[1];
    ma_hpf2 hpf2[MA_MAX_FILTER_ORDER/2];
} ma_hpf;

MA_API ma_result ma_hpf_init(const ma_hpf_config* pConfig, ma_hpf* pHPF);
MA_API ma_result ma_hpf_reinit(const ma_hpf_config* pConfig, ma_hpf* pHPF);
MA_API ma_result ma_hpf_process_pcm_frames(ma_hpf* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_hpf_get_latency(ma_hpf* pHPF);


/**************************************************************************************************************************************************************

Band-Pass Filtering

**************************************************************************************************************************************************************/
typedef struct
{

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


MA_API ma_bpf2_config ma_bpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, double q);

typedef struct
{
    ma_biquad bq;   /* The second order band-pass filter is implemented as a biquad filter. */
} ma_bpf2;

MA_API ma_result ma_bpf2_init(const ma_bpf2_config* pConfig, ma_bpf2* pBPF);
MA_API ma_result ma_bpf2_reinit(const ma_bpf2_config* pConfig, ma_bpf2* pBPF);
MA_API ma_result ma_bpf2_process_pcm_frames(ma_bpf2* pBPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_bpf2_get_latency(ma_bpf2* pBPF);


typedef struct
{
    ma_format format;
    ma_uint32 channels;
    ma_uint32 sampleRate;
    double cutoffFrequency;
    ma_uint32 order;    /* If set to 0, will be treated as a passthrough (no filtering will be applied). */

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

typedef struct
{
    ma_format format;
    ma_uint32 channels;
    ma_uint32 bpf2Count;
    ma_bpf2 bpf2[MA_MAX_FILTER_ORDER/2];
} ma_bpf;

MA_API ma_result ma_bpf_init(const ma_bpf_config* pConfig, ma_bpf* pBPF);
MA_API ma_result ma_bpf_reinit(const ma_bpf_config* pConfig, ma_bpf* pBPF);
MA_API ma_result ma_bpf_process_pcm_frames(ma_bpf* pBPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_bpf_get_latency(ma_bpf* pBPF);


/**************************************************************************************************************************************************************

Notching Filter

**************************************************************************************************************************************************************/
typedef struct
{

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


MA_API ma_notch2_config ma_notch2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double q, double frequency);

typedef struct
{
    ma_biquad bq;
} ma_notch2;

MA_API ma_result ma_notch2_init(const ma_notch2_config* pConfig, ma_notch2* pFilter);
MA_API ma_result ma_notch2_reinit(const ma_notch2_config* pConfig, ma_notch2* pFilter);
MA_API ma_result ma_notch2_process_pcm_frames(ma_notch2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_notch2_get_latency(ma_notch2* pFilter);


/**************************************************************************************************************************************************************

Peaking EQ Filter

**************************************************************************************************************************************************************/
typedef struct
{

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


MA_API ma_peak2_config ma_peak2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double q, double frequency);

typedef struct
{
    ma_biquad bq;
} ma_peak2;

MA_API ma_result ma_peak2_init(const ma_peak2_config* pConfig, ma_peak2* pFilter);
MA_API ma_result ma_peak2_reinit(const ma_peak2_config* pConfig, ma_peak2* pFilter);
MA_API ma_result ma_peak2_process_pcm_frames(ma_peak2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_peak2_get_latency(ma_peak2* pFilter);


/**************************************************************************************************************************************************************

Low Shelf Filter

**************************************************************************************************************************************************************/
typedef struct
{

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


MA_API ma_loshelf2_config ma_loshelf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double shelfSlope, double frequency);

typedef struct
{
    ma_biquad bq;
} ma_loshelf2;

MA_API ma_result ma_loshelf2_init(const ma_loshelf2_config* pConfig, ma_loshelf2* pFilter);
MA_API ma_result ma_loshelf2_reinit(const ma_loshelf2_config* pConfig, ma_loshelf2* pFilter);
MA_API ma_result ma_loshelf2_process_pcm_frames(ma_loshelf2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_loshelf2_get_latency(ma_loshelf2* pFilter);


/**************************************************************************************************************************************************************

High Shelf Filter

**************************************************************************************************************************************************************/
typedef struct
{

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


MA_API ma_hishelf2_config ma_hishelf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double shelfSlope, double frequency);

typedef struct
{
    ma_biquad bq;
} ma_hishelf2;

MA_API ma_result ma_hishelf2_init(const ma_hishelf2_config* pConfig, ma_hishelf2* pFilter);
MA_API ma_result ma_hishelf2_reinit(const ma_hishelf2_config* pConfig, ma_hishelf2* pFilter);
MA_API ma_result ma_hishelf2_process_pcm_frames(ma_hishelf2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_hishelf2_get_latency(ma_hishelf2* pFilter);



/************************************************************************************************************************************************************
*************************************************************************************************************************************************************

DATA CONVERSION
===============

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

{
    ma_linear_resampler_config config;
    ma_uint32 inAdvanceInt;
    ma_uint32 inAdvanceFrac;
    ma_uint32 inTimeInt;
    ma_uint32 inTimeFrac;
    union
    {
        float    f32[MA_MAX_CHANNELS];
        ma_int16 s16[MA_MAX_CHANNELS];
    } x0; /* The previous input frame. */
    union
    {
        float    f32[MA_MAX_CHANNELS];
        ma_int16 s16[MA_MAX_CHANNELS];
    } x1; /* The next input frame. */
    ma_lpf lpf;
} ma_linear_resampler;

MA_API ma_result ma_linear_resampler_init(const ma_linear_resampler_config* pConfig, ma_linear_resampler* pResampler);
MA_API void ma_linear_resampler_uninit(ma_linear_resampler* pResampler);
MA_API ma_result ma_linear_resampler_process_pcm_frames(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut);
MA_API ma_result ma_linear_resampler_set_rate(ma_linear_resampler* pResampler, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);
MA_API ma_result ma_linear_resampler_set_rate_ratio(ma_linear_resampler* pResampler, float ratioInOut);
MA_API ma_uint64 ma_linear_resampler_get_required_input_frame_count(ma_linear_resampler* pResampler, ma_uint64 outputFrameCount);
MA_API ma_uint64 ma_linear_resampler_get_expected_output_frame_count(ma_linear_resampler* pResampler, ma_uint64 inputFrameCount);
MA_API ma_uint64 ma_linear_resampler_get_input_latency(ma_linear_resampler* pResampler);
MA_API ma_uint64 ma_linear_resampler_get_output_latency(ma_linear_resampler* pResampler);

typedef enum
{
    ma_resample_algorithm_linear = 0,   /* Fastest, lowest quality. Optional low-pass filtering. Default. */
    ma_resample_algorithm_speex
} ma_resample_algorithm;

typedef struct

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

MA_API ma_result ma_resampler_init(const ma_resampler_config* pConfig, ma_resampler* pResampler);

/*
Uninitializes a resampler.
*/
MA_API void ma_resampler_uninit(ma_resampler* pResampler);

/*
Converts the given input data.

Both the input and output frames must be in the format specified in the config when the resampler was initilized.

On input, [pFrameCountOut] contains the number of output frames to process. On output it contains the number of output frames that
were actually processed, which may be less than the requested amount which will happen if there's not enough input data. You can use
ma_resampler_get_expected_output_frame_count() to know how many output frames will be processed for a given number of input frames.

On input, [pFrameCountIn] contains the number of input frames contained in [pFramesIn]. On output it contains the number of whole
input frames that were actually processed. You can use ma_resampler_get_required_input_frame_count() to know how many input frames
you should provide for a given number of output frames. [pFramesIn] can be NULL, in which case zeroes will be used instead.

If [pFramesOut] is NULL, a seek is performed. In this case, if [pFrameCountOut] is not NULL it will seek by the specified number of
output frames. Otherwise, if [pFramesCountOut] is NULL and [pFrameCountIn] is not NULL, it will seek by the specified number of input
frames. When seeking, [pFramesIn] is allowed to NULL, in which case the internal timing state will be updated, but no input will be
processed. In this case, any internal filter state will be updated as if zeroes were passed in.

It is an error for [pFramesOut] to be non-NULL and [pFrameCountOut] to be NULL.

It is an error for both [pFrameCountOut] and [pFrameCountIn] to be NULL.
*/
MA_API ma_result ma_resampler_process_pcm_frames(ma_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut);


/*
Sets the input and output sample sample rate.
*/
MA_API ma_result ma_resampler_set_rate(ma_resampler* pResampler, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);

/*
Sets the input and output sample rate as a ratio.

The ration is in/out.
*/
MA_API ma_result ma_resampler_set_rate_ratio(ma_resampler* pResampler, float ratio);


/*
Calculates the number of whole input frames that would need to be read from the client in order to output the specified
number of output frames.

The returned value does not include cached input frames. It only returns the number of extra frames that would need to be
read from the input buffer in order to output the specified number of output frames.
*/
MA_API ma_uint64 ma_resampler_get_required_input_frame_count(ma_resampler* pResampler, ma_uint64 outputFrameCount);

/*
Calculates the number of whole output frames that would be output after fully reading and consuming the specified number of
input frames.
*/
MA_API ma_uint64 ma_resampler_get_expected_output_frame_count(ma_resampler* pResampler, ma_uint64 inputFrameCount);


/*
Retrieves the latency introduced by the resampler in input frames.
*/
MA_API ma_uint64 ma_resampler_get_input_latency(ma_resampler* pResampler);

/*
Retrieves the latency introduced by the resampler in output frames.
*/
MA_API ma_uint64 ma_resampler_get_output_latency(ma_resampler* pResampler);



/**************************************************************************************************************************************************************

Channel Conversion

**************************************************************************************************************************************************************/

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

    } weights;
    ma_bool32 isPassthrough         : 1;
    ma_bool32 isSimpleShuffle       : 1;
    ma_bool32 isSimpleMonoExpansion : 1;
    ma_bool32 isStereoToMono        : 1;
    ma_uint8  shuffleTable[MA_MAX_CHANNELS];
} ma_channel_converter;

MA_API ma_result ma_channel_converter_init(const ma_channel_converter_config* pConfig, ma_channel_converter* pConverter);
MA_API void ma_channel_converter_uninit(ma_channel_converter* pConverter);
MA_API ma_result ma_channel_converter_process_pcm_frames(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);


/**************************************************************************************************************************************************************

Data Conversion

**************************************************************************************************************************************************************/
typedef struct
{
    ma_format formatIn;

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

    ma_resampler resampler;
    ma_bool32 hasPreFormatConversion  : 1;
    ma_bool32 hasPostFormatConversion : 1;
    ma_bool32 hasChannelConverter     : 1;
    ma_bool32 hasResampler            : 1;
    ma_bool32 isPassthrough           : 1;
} ma_data_converter;

MA_API ma_result ma_data_converter_init(const ma_data_converter_config* pConfig, ma_data_converter* pConverter);
MA_API void ma_data_converter_uninit(ma_data_converter* pConverter);
MA_API ma_result ma_data_converter_process_pcm_frames(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut);
MA_API ma_result ma_data_converter_set_rate(ma_data_converter* pConverter, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);
MA_API ma_result ma_data_converter_set_rate_ratio(ma_data_converter* pConverter, float ratioInOut);
MA_API ma_uint64 ma_data_converter_get_required_input_frame_count(ma_data_converter* pConverter, ma_uint64 outputFrameCount);
MA_API ma_uint64 ma_data_converter_get_expected_output_frame_count(ma_data_converter* pConverter, ma_uint64 inputFrameCount);
MA_API ma_uint64 ma_data_converter_get_input_latency(ma_data_converter* pConverter);
MA_API ma_uint64 ma_data_converter_get_output_latency(ma_data_converter* pConverter);


/************************************************************************************************************************************************************

Format Conversion

************************************************************************************************************************************************************/
MA_API void ma_pcm_u8_to_s16(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);

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

MA_API void ma_pcm_s24_to_f32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_s32_to_u8(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_s32_to_s16(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_s32_to_s24(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_s32_to_f32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_f32_to_u8(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_f32_to_s16(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_f32_to_s24(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_f32_to_s32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_convert(void* pOut, ma_format formatOut, const void* pIn, ma_format formatIn, ma_uint64 sampleCount, ma_dither_mode ditherMode);
MA_API void ma_convert_pcm_frames_format(void* pOut, ma_format formatOut, const void* pIn, ma_format formatIn, ma_uint64 frameCount, ma_uint32 channels, ma_dither_mode ditherMode);

/*
Deinterleaves an interleaved buffer.
*/
MA_API void ma_deinterleave_pcm_frames(ma_format format, ma_uint32 channels, ma_uint64 frameCount, const void* pInterleavedPCMFrames, void** ppDeinterleavedPCMFrames);

/*
Interleaves a group of deinterleaved buffers.
*/
MA_API void ma_interleave_pcm_frames(ma_format format, ma_uint32 channels, ma_uint64 frameCount, const void** ppDeinterleavedPCMFrames, void* pInterleavedPCMFrames);

/************************************************************************************************************************************************************

Channel Maps

************************************************************************************************************************************************************/

/*
Helper for retrieving a standard channel map.

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

MA_API ma_bool32 ma_channel_map_contains_channel_position(ma_uint32 channels, const ma_channel* pChannelMap, ma_channel channelPosition);


/************************************************************************************************************************************************************

Conversion Helpers

************************************************************************************************************************************************************/

/*
High-level helper for doing a full format conversion in one go. Returns the number of output frames. Call this with pOut set to NULL to
determine the required size of the output buffer. frameCountOut should be set to the capacity of pOut. If pOut is NULL, frameCountOut is
ignored.

A return value of 0 indicates an error.

This function is useful for one-off bulk conversions, but if you're streaming data you should use the ma_data_converter APIs instead.
*/
MA_API ma_uint64 ma_convert_frames(void* pOut, ma_uint64 frameCountOut, ma_format formatOut, ma_uint32 channelsOut, ma_uint32 sampleRateOut, const void* pIn, ma_uint64 frameCountIn, ma_format formatIn, ma_uint32 channelsIn, ma_uint32 sampleRateIn);
MA_API ma_uint64 ma_convert_frames_ex(void* pOut, ma_uint64 frameCountOut, const void* pIn, ma_uint64 frameCountIn, const ma_data_converter_config* pConfig);


/************************************************************************************************************************************************************

Ring Buffer

************************************************************************************************************************************************************/
typedef struct
{
    void* pBuffer;

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

MA_API ma_result ma_pcm_rb_init_ex(ma_format format, ma_uint32 channels, ma_uint32 subbufferSizeInFrames, ma_uint32 subbufferCount, ma_uint32 subbufferStrideInFrames, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallba...
MA_API ma_result ma_pcm_rb_init(ma_format format, ma_uint32 channels, ma_uint32 bufferSizeInFrames, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_pcm_rb* pRB);
MA_API void ma_pcm_rb_uninit(ma_pcm_rb* pRB);
MA_API void ma_pcm_rb_reset(ma_pcm_rb* pRB);
MA_API ma_result ma_pcm_rb_acquire_read(ma_pcm_rb* pRB, ma_uint32* pSizeInFrames, void** ppBufferOut);
MA_API ma_result ma_pcm_rb_commit_read(ma_pcm_rb* pRB, ma_uint32 sizeInFrames, void* pBufferOut);
MA_API ma_result ma_pcm_rb_acquire_write(ma_pcm_rb* pRB, ma_uint32* pSizeInFrames, void** ppBufferOut);
MA_API ma_result ma_pcm_rb_commit_write(ma_pcm_rb* pRB, ma_uint32 sizeInFrames, void* pBufferOut);
MA_API ma_result ma_pcm_rb_seek_read(ma_pcm_rb* pRB, ma_uint32 offsetInFrames);
MA_API ma_result ma_pcm_rb_seek_write(ma_pcm_rb* pRB, ma_uint32 offsetInFrames);
MA_API ma_int32 ma_pcm_rb_pointer_distance(ma_pcm_rb* pRB); /* Return value is in frames. */
MA_API ma_uint32 ma_pcm_rb_available_read(ma_pcm_rb* pRB);
MA_API ma_uint32 ma_pcm_rb_available_write(ma_pcm_rb* pRB);
MA_API ma_uint32 ma_pcm_rb_get_subbuffer_size(ma_pcm_rb* pRB);
MA_API ma_uint32 ma_pcm_rb_get_subbuffer_stride(ma_pcm_rb* pRB);
MA_API ma_uint32 ma_pcm_rb_get_subbuffer_offset(ma_pcm_rb* pRB, ma_uint32 subbufferIndex);
MA_API void* ma_pcm_rb_get_subbuffer_ptr(ma_pcm_rb* pRB, ma_uint32 subbufferIndex, void* pBuffer);


/************************************************************************************************************************************************************

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

Free's an aligned malloc'd buffer.
*/
MA_API void ma_aligned_free(void* p, const ma_allocation_callbacks* pAllocationCallbacks);

/*
Retrieves a friendly name for a format.
*/
MA_API const char* ma_get_format_name(ma_format format);

/*
Blends two frames in floating point format.
*/
MA_API void ma_blend_f32(float* pOut, float* pInA, float* pInB, float factor, ma_uint32 channels);

/*
Retrieves the size of a sample in bytes for the given format.

This API is efficient and is implemented using a lookup table.

Thread Safety: SAFE
  This API is pure.
*/
MA_API ma_uint32 ma_get_bytes_per_sample(ma_format format);
static MA_INLINE ma_uint32 ma_get_bytes_per_frame(ma_format format, ma_uint32 channels) { return ma_get_bytes_per_sample(format) * channels; }

/*
Converts a log level to a string.
*/
MA_API const char* ma_log_level_to_string(ma_uint32 logLevel);



/************************************************************************************************************************************************************
*************************************************************************************************************************************************************

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

    ma_backend_null    /* <-- Must always be the last item. Lowest priority, and used as the terminator for backend enumeration. */
} ma_backend;

#define MA_BACKEND_COUNT (ma_backend_null+1)


/*
The callback for processing audio data from the device.

The data callback is fired by miniaudio whenever the device needs to have more data delivered to a playback device, or when a capture device has some data
available. This is called as soon as the backend asks for more data which means it may be called with inconsistent frame counts. You cannot assume the
callback will be fired with a consistent frame count.


Parameters
----------
pDevice (in)
    A pointer to the relevant device.

pOutput (out)
    A pointer to the output buffer that will receive audio data that will later be played back through the speakers. This will be non-null for a playback or
    full-duplex device and null for a capture and loopback device.

pInput (in)
    A pointer to the buffer containing input data from a recording device. This will be non-null for a capture, full-duplex or loopback device and null for a
    playback device.

frameCount (in)
    The number of PCM frames to process. Note that this will not necessarily be equal to what you requested when you initialized the device. The
    `periodSizeInFrames` and `periodSizeInMilliseconds` members of the device config are just hints, and are not necessarily exactly what you'll get. You must
    not assume this will always be the same value each time the callback is fired.


Remarks
-------
You cannot stop and start the device from inside the callback or else you'll get a deadlock. You must also not uninitialize the device from inside the
callback. The following APIs cannot be called from inside the callback:

    ma_device_init()
    ma_device_init_ex()
    ma_device_uninit()
    ma_device_start()
    ma_device_stop()

The proper way to stop the device is to call `ma_device_stop()` from a different thread, normally the main application thread.
*/
typedef void (* ma_device_callback_proc)(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);

/*
The callback for when the device has been stopped.

This will be called when the device is stopped explicitly with `ma_device_stop()` and also called implicitly when the device is stopped through external forces
such as being unplugged or an internal error occuring.


Parameters
----------

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

#ifdef MA_SUPPORT_WINMM
        struct
        {
            /*HWAVEOUT*/ ma_handle hDevicePlayback;
            /*HWAVEIN*/ ma_handle hDeviceCapture;
            /*HANDLE*/ ma_handle hEventPlayback;
            /*HANDLE*/ ma_handle hEventCapture;
            ma_uint32 fragmentSizeInFrames;
            ma_uint32 iNextHeaderPlayback;             /* [0,periods). Used as an index into pWAVEHDRPlayback. */
            ma_uint32 iNextHeaderCapture;              /* [0,periods). Used as an index into pWAVEHDRCapture. */
            ma_uint32 headerFramesConsumedPlayback;    /* The number of PCM frames consumed in the buffer in pWAVEHEADER[iNextHeader]. */
            ma_uint32 headerFramesConsumedCapture;     /* ^^^ */
            /*WAVEHDR**/ ma_uint8* pWAVEHDRPlayback;   /* One instantiation for each period. */
            /*WAVEHDR**/ ma_uint8* pWAVEHDRCapture;    /* One instantiation for each period. */
            ma_uint8* pIntermediaryBufferPlayback;
            ma_uint8* pIntermediaryBufferCapture;
            ma_uint8* _pHeapData;                      /* Used internally and is used for the heap allocated data for the intermediary buffer and the WAVEHDR structures. */
        } winmm;
#endif
#ifdef MA_SUPPORT_ALSA
        struct

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



/*
Initializes a device.

A device represents a physical audio device. The idea is you send or receive audio data from the device to either play it back through a speaker, or capture it
from a microphone. Whether or not you should send or receive data from the device (or both) depends on the type of device you are initializing which can be
playback, capture, full-duplex or loopback. (Note that loopback mode is only supported on select backends.) Sending and receiving audio data to and from the
device is done via a callback which is fired by miniaudio at periodic time intervals.

The frequency at which data is delivered to and from a device depends on the size of it's period. The size of the period can be defined in terms of PCM frames
or milliseconds, whichever is more convenient. Generally speaking, the smaller the period, the lower the latency at the expense of higher CPU usage and
increased risk of glitching due to the more frequent and granular data deliver intervals. The size of a period will depend on your requirements, but
miniaudio's defaults should work fine for most scenarios. If you're building a game you should leave this fairly small, whereas if you're building a simple
media player you can make it larger. Note that the period size you request is actually just a hint - miniaudio will tell the backend what you want, but the
backend is ultimately responsible for what it gives you. You cannot assume you will get exactly what you ask for.

When delivering data to and from a device you need to make sure it's in the correct format which you can set through the device configuration. You just set the
format that you want to use and miniaudio will perform all of the necessary conversion for you internally. When delivering data to and from the callback you
can assume the format is the same as what you requested when you initialized the device. See Remarks for more details on miniaudio's data conversion pipeline.

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

The device can be configured via the `pConfig` argument. The config object is initialized with `ma_device_config_init()`. Individual configuration settings can
then be set directly on the structure. Below are the members of the `ma_device_config` object.

    deviceType
        Must be `ma_device_type_playback`, `ma_device_type_capture`, `ma_device_type_duplex` of `ma_device_type_loopback`.

    sampleRate
        The sample rate, in hertz. The most common sample rates are 48000 and 44100. Setting this to 0 will use the device's native sample rate.

    periodSizeInFrames
        The desired size of a period in PCM frames. If this is 0, `periodSizeInMilliseconds` will be used instead. If both are 0 the default buffer size will
        be used depending on the selected performance profile. This value affects latency. See below for details.

    periodSizeInMilliseconds
        The desired size of a period in milliseconds. If this is 0, `periodSizeInFrames` will be used instead. If both are 0 the default buffer size will be
        used depending on the selected performance profile. The value affects latency. See below for details.

    periods
        The number of periods making up the device's entire buffer. The total buffer size is `periodSizeInFrames` or `periodSizeInMilliseconds` multiplied by
        this value. This is just a hint as backends will be the ones who ultimately decide how your periods will be configured.

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

************************************************************************************************************************************************************/

/*
Adjust buffer size based on a scaling factor.

This just multiplies the base size by the scaling factor, making sure it's a size of at least 1.
*/
MA_API ma_uint32 ma_scale_buffer_size(ma_uint32 baseBufferSize, float scale);

/*
Calculates a buffer size in milliseconds from the specified number of frames and sample rate.
*/
MA_API ma_uint32 ma_calculate_buffer_size_in_milliseconds_from_frames(ma_uint32 bufferSizeInFrames, ma_uint32 sampleRate);

/*
Calculates a buffer size in frames from the specified number of milliseconds and sample rate.
*/
MA_API ma_uint32 ma_calculate_buffer_size_in_frames_from_milliseconds(ma_uint32 bufferSizeInMilliseconds, ma_uint32 sampleRate);

/*
Copies PCM frames from one buffer to another.
*/
MA_API void ma_copy_pcm_frames(void* dst, const void* src, ma_uint64 frameCount, ma_format format, ma_uint32 channels);

/*
Copies silent frames into the given buffer.

Remarks
-------
For all formats except `ma_format_u8`, the output buffer will be filled with 0. For `ma_format_u8` it will be filled with 128. The reason for this is that it
makes more sense for the purpose of mixing to initialize it to the center point.
*/
MA_API void ma_silence_pcm_frames(void* p, ma_uint64 frameCount, ma_format format, ma_uint32 channels);
static MA_INLINE void ma_zero_pcm_frames(void* p, ma_uint64 frameCount, ma_format format, ma_uint32 channels) { ma_silence_pcm_frames(p, frameCount, format, channels); }


/*
Offsets a pointer by the specified number of PCM frames.
*/
MA_API void* ma_offset_pcm_frames_ptr(void* p, ma_uint64 offsetInFrames, ma_format format, ma_uint32 channels);
MA_API const void* ma_offset_pcm_frames_const_ptr(const void* p, ma_uint64 offsetInFrames, ma_format format, ma_uint32 channels);


/*
Clips f32 samples.
*/
MA_API void ma_clip_samples_f32(float* p, ma_uint64 sampleCount);
static MA_INLINE void ma_clip_pcm_frames_f32(float* p, ma_uint64 frameCount, ma_uint32 channels) { ma_clip_samples_f32(p, frameCount*channels); }

/*
Helper for applying a volume factor to samples.

Note that the source and destination buffers can be the same, in which case it'll perform the operation in-place.
*/
MA_API void ma_copy_and_apply_volume_factor_u8(ma_uint8* pSamplesOut, const ma_uint8* pSamplesIn, ma_uint64 sampleCount, float factor);
MA_API void ma_copy_and_apply_volume_factor_s16(ma_int16* pSamplesOut, const ma_int16* pSamplesIn, ma_uint64 sampleCount, float factor);
MA_API void ma_copy_and_apply_volume_factor_s24(void* pSamplesOut, const void* pSamplesIn, ma_uint64 sampleCount, float factor);
MA_API void ma_copy_and_apply_volume_factor_s32(ma_int32* pSamplesOut, const ma_int32* pSamplesIn, ma_uint64 sampleCount, float factor);
MA_API void ma_copy_and_apply_volume_factor_f32(float* pSamplesOut, const float* pSamplesIn, ma_uint64 sampleCount, float factor);

MA_API void ma_apply_volume_factor_u8(ma_uint8* pSamples, ma_uint64 sampleCount, float factor);
MA_API void ma_apply_volume_factor_s16(ma_int16* pSamples, ma_uint64 sampleCount, float factor);
MA_API void ma_apply_volume_factor_s24(void* pSamples, ma_uint64 sampleCount, float factor);
MA_API void ma_apply_volume_factor_s32(ma_int32* pSamples, ma_uint64 sampleCount, float factor);
MA_API void ma_apply_volume_factor_f32(float* pSamples, ma_uint64 sampleCount, float factor);

MA_API void ma_copy_and_apply_volume_factor_pcm_frames_u8(ma_uint8* pPCMFramesOut, const ma_uint8* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s16(ma_int16* pPCMFramesOut, const ma_int16* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s24(void* pPCMFramesOut, const void* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s32(ma_int32* pPCMFramesOut, const ma_int32* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_copy_and_apply_volume_factor_pcm_frames_f32(float* pPCMFramesOut, const float* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_copy_and_apply_volume_factor_pcm_frames(void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float factor);

MA_API void ma_apply_volume_factor_pcm_frames_u8(ma_uint8* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_apply_volume_factor_pcm_frames_s16(ma_int16* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_apply_volume_factor_pcm_frames_s24(void* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_apply_volume_factor_pcm_frames_s32(ma_int32* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_apply_volume_factor_pcm_frames_f32(float* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_apply_volume_factor_pcm_frames(void* pFrames, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float factor);


/*
Helper for converting a linear factor to gain in decibels.
*/
MA_API float ma_factor_to_gain_db(float factor);

/*
Helper for converting gain in decibels to a linear factor.
*/
MA_API float ma_gain_db_to_factor(float gain);


typedef void ma_data_source;

typedef struct
{
    ma_result (* onRead)(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
    ma_result (* onSeek)(ma_data_source* pDataSource, ma_uint64 frameIndex);
    ma_result (* onMap)(ma_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount);   /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
    ma_result (* onUnmap)(ma_data_source* pDataSource, ma_uint64 frameCount);
    ma_result (* onGetDataFormat)(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
    ma_result (* onGetCursor)(ma_data_source* pDataSource, ma_uint64* pCursor);
    ma_result (* onGetLength)(ma_data_source* pDataSource, ma_uint64* pLength);
} ma_data_source_callbacks;

MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead, ma_bool32 loop);   /* Must support pFramesOut = NULL in which case a forward seek should be performed. */
MA_API ma_result ma_data_source_seek_pcm_frames(ma_data_source* pDataSource, ma_uint64 frameCount, ma_uint64* pFramesSeeked, ma_bool32 loop); /* Can only seek forward. Equivalent to ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount); */
MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, ma_uint64 frameIndex);
MA_API ma_result ma_data_source_map(ma_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount);
MA_API ma_result ma_data_source_unmap(ma_data_source* pDataSource, ma_uint64 frameCount);       /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor);
MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLength);    /* Returns MA_NOT_IMPLEMENTED if the length is unknown or cannot be determined. Decoders can return this. */


typedef struct
{
    ma_format format;
    ma_uint32 channels;
    ma_uint64 sizeInFrames;
    const void* pData;  /* If set to NULL, will allocate a block of memory for you. */
    ma_allocation_callbacks allocationCallbacks;
} ma_audio_buffer_config;

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

    ma_allocation_callbacks allocationCallbacks;
    ma_bool32 ownsData;             /* Used to control whether or not miniaudio owns the data buffer. If set to true, pData will be freed in ma_audio_buffer_uninit(). */
    ma_uint8 _pExtraData[1];        /* For allocating a buffer with the memory located directly after the other memory of the structure. */
} ma_audio_buffer;

MA_API ma_result ma_audio_buffer_init(const ma_audio_buffer_config* pConfig, ma_audio_buffer* pAudioBuffer);
MA_API ma_result ma_audio_buffer_init_copy(const ma_audio_buffer_config* pConfig, ma_audio_buffer* pAudioBuffer);
MA_API ma_result ma_audio_buffer_alloc_and_init(const ma_audio_buffer_config* pConfig, ma_audio_buffer** ppAudioBuffer);  /* Always copies the data. Doesn't make sense to use this otherwise. Use ma_audio_buffer_uninit_and_free() to uninit. */
MA_API void ma_audio_buffer_uninit(ma_audio_buffer* pAudioBuffer);
MA_API void ma_audio_buffer_uninit_and_free(ma_audio_buffer* pAudioBuffer);
MA_API ma_uint64 ma_audio_buffer_read_pcm_frames(ma_audio_buffer* pAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop);
MA_API ma_result ma_audio_buffer_seek_to_pcm_frame(ma_audio_buffer* pAudioBuffer, ma_uint64 frameIndex);
MA_API ma_result ma_audio_buffer_map(ma_audio_buffer* pAudioBuffer, void** ppFramesOut, ma_uint64* pFrameCount);
MA_API ma_result ma_audio_buffer_unmap(ma_audio_buffer* pAudioBuffer, ma_uint64 frameCount);    /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
MA_API ma_result ma_audio_buffer_at_end(ma_audio_buffer* pAudioBuffer);
MA_API ma_result ma_audio_buffer_get_available_frames(ma_audio_buffer* pAudioBuffer, ma_uint64* pAvailableFrames);



/************************************************************************************************************************************************************

VFS
===

The VFS object (virtual file system) is what's used to customize file access. This is useful in cases where stdio FILE* based APIs may not be entirely
appropriate for a given situation.

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


Decoders are independent of the main device API. Decoding APIs can be called freely inside the device's data callback, but they are not thread safe unless
you do your own synchronization.

************************************************************************************************************************************************************/
#ifndef MA_NO_DECODING
typedef struct ma_decoder ma_decoder;

typedef size_t    (* ma_decoder_read_proc)                    (ma_decoder* pDecoder, void* pBufferOut, size_t bytesToRead);     /* Returns the number of bytes read. */
typedef ma_bool32 (* ma_decoder_seek_proc)                    (ma_decoder* pDecoder, int byteOffset, ma_seek_origin origin);    /* Origin will never be ma_seek_origin_end. */
typedef ma_uint64 (* ma_decoder_read_pcm_frames_proc)         (ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount);   /* Returns the number of frames read. Output data is in internal format. */
typedef ma_result (* ma_decoder_seek_to_pcm_frame_proc)       (ma_decoder* pDecoder, ma_uint64 frameIndex);
typedef ma_result (* ma_decoder_uninit_proc)                  (ma_decoder* pDecoder);
typedef ma_uint64 (* ma_decoder_get_length_in_pcm_frames_proc)(ma_decoder* pDecoder);

typedef struct
{
    ma_format format;      /* Set to 0 or ma_format_unknown to use the stream's internal format. */
    ma_uint32 channels;    /* Set to 0 to use the stream's internal channels. */
    ma_uint32 sampleRate;  /* Set to 0 to use the stream's internal sample rate. */
    ma_channel channelMap[MA_MAX_CHANNELS];
    ma_channel_mix_mode channelMixMode;
    ma_dither_mode ditherMode;
    struct

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

    ma_allocation_callbacks allocationCallbacks;
} ma_decoder_config;

struct ma_decoder
{
    ma_data_source_callbacks ds;
    ma_decoder_read_proc onRead;
    ma_decoder_seek_proc onSeek;
    void* pUserData;
    ma_uint64  readPointerInBytes;          /* In internal encoded data. */
    ma_uint64  readPointerInPCMFrames;      /* In output sample rate. Used for keeping track of how many frames are available for decoding. */
    ma_format  internalFormat;
    ma_uint32  internalChannels;
    ma_uint32  internalSampleRate;
    ma_channel internalChannelMap[MA_MAX_CHANNELS];
    ma_format  outputFormat;
    ma_uint32  outputChannels;
    ma_uint32  outputSampleRate;
    ma_channel outputChannelMap[MA_MAX_CHANNELS];
    ma_data_converter converter;   /* <-- Data conversion is achieved by running frames through this. */
    ma_allocation_callbacks allocationCallbacks;
    ma_decoder_read_pcm_frames_proc onReadPCMFrames;
    ma_decoder_seek_to_pcm_frame_proc onSeekToPCMFrame;
    ma_decoder_uninit_proc onUninit;
    ma_decoder_get_length_in_pcm_frames_proc onGetLengthInPCMFrames;
    void* pInternalDecoder; /* <-- The drwav/drflac/stb_vorbis/etc. objects. */
    union
    {
        struct
        {
            ma_vfs* pVFS;
            ma_vfs_file file;
        } vfs;
        struct
        {

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


MA_API ma_result ma_decoder_init_file_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
MA_API ma_result ma_decoder_init_file_wav_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
MA_API ma_result ma_decoder_init_file_flac_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
MA_API ma_result ma_decoder_init_file_mp3_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
MA_API ma_result ma_decoder_init_file_vorbis_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);

MA_API ma_result ma_decoder_uninit(ma_decoder* pDecoder);

/*
Retrieves the current position of the read cursor in PCM frames.
*/
MA_API ma_result ma_decoder_get_cursor_in_pcm_frames(ma_decoder* pDecoder, ma_uint64* pCursor);

/*
Retrieves the length of the decoder in PCM frames.

Do not call this on streams of an undefined length, such as internet radio.

If the length is unknown or an error occurs, 0 will be returned.

This will always return 0 for Vorbis decoders. This is due to a limitation with stb_vorbis in push mode which is what miniaudio
uses internally.

For MP3's, this will decode the entire file. Do not call this in time critical scenarios.

This function is not thread safe without your own synchronization.
*/
MA_API ma_uint64 ma_decoder_get_length_in_pcm_frames(ma_decoder* pDecoder);

/*
Reads PCM frames from the given decoder.

This is not thread safe without your own synchronization.
*/
MA_API ma_uint64 ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount);

/*
Seeks to a PCM frame based on it's absolute index.

This is not thread safe without your own synchronization.
*/
MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 frameIndex);

/*
Retrieves the number of frames that can be read before reaching the end.

This calls `ma_decoder_get_length_in_pcm_frames()` so you need to be aware of the rules for that function, in
particular ensuring you do not call it on streams of an undefined length, such as internet radio.

If the total length of the decoder cannot be retrieved, such as with Vorbis decoders, `MA_NOT_IMPLEMENTED` will be
returned.
*/
MA_API ma_result ma_decoder_get_available_frames(ma_decoder* pDecoder, ma_uint64* pAvailableFrames);

/*
Helper for opening and decoding a file into a heap allocated block of memory. Free the returned pointer with ma_free(). On input,
pConfig should be set to what you want. On output it will be set to what you got.
*/
MA_API ma_result ma_decode_from_vfs(ma_vfs* pVFS, const char* pFilePath, ma_decoder_config* pConfig, ma_uint64* pFrameCountOut, void** ppPCMFramesOut);
MA_API ma_result ma_decode_file(const char* pFilePath, ma_decoder_config* pConfig, ma_uint64* pFrameCountOut, void** ppPCMFramesOut);
MA_API ma_result ma_decode_memory(const void* pData, size_t dataSize, ma_decoder_config* pConfig, ma_uint64* pFrameCountOut, void** ppPCMFramesOut);

#endif  /* MA_NO_DECODING */

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

Encoders do not perform any format conversion for you. If your target format does not support the format, and error will be returned.

************************************************************************************************************************************************************/
#ifndef MA_NO_ENCODING
typedef struct ma_encoder ma_encoder;

typedef size_t    (* ma_encoder_write_proc)           (ma_encoder* pEncoder, const void* pBufferIn, size_t bytesToWrite);     /* Returns the number of bytes written. */
typedef ma_bool32 (* ma_encoder_seek_proc)            (ma_encoder* pEncoder, int byteOffset, ma_seek_origin origin);
typedef ma_result (* ma_encoder_init_proc)            (ma_encoder* pEncoder);
typedef void      (* ma_encoder_uninit_proc)          (ma_encoder* pEncoder);
typedef ma_uint64 (* ma_encoder_write_pcm_frames_proc)(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount);

typedef struct
{
    ma_resource_format resourceFormat;
    ma_format format;
    ma_uint32 channels;
    ma_uint32 sampleRate;
    ma_allocation_callbacks allocationCallbacks;
} ma_encoder_config;

MA_API ma_encoder_config ma_encoder_config_init(ma_resource_format resourceFormat, ma_format format, ma_uint32 channels, ma_uint32 sampleRate);

struct ma_encoder
{
    ma_encoder_config config;
    ma_encoder_write_proc onWrite;
    ma_encoder_seek_proc onSeek;
    ma_encoder_init_proc onInit;
    ma_encoder_uninit_proc onUninit;
    ma_encoder_write_pcm_frames_proc onWritePCMFrames;
    void* pUserData;
    void* pInternalEncoder; /* <-- The drwav/drflac/stb_vorbis/etc. objects. */
    void* pFile;    /* FILE*. Only used when initialized with ma_encoder_init_file(). */
};

MA_API ma_result ma_encoder_init(ma_encoder_write_proc onWrite, ma_encoder_seek_proc onSeek, void* pUserData, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
MA_API ma_result ma_encoder_init_file(const char* pFilePath, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
MA_API ma_result ma_encoder_init_file_w(const wchar_t* pFilePath, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
MA_API void ma_encoder_uninit(ma_encoder* pEncoder);
MA_API ma_uint64 ma_encoder_write_pcm_frames(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount);

#endif /* MA_NO_ENCODING */


/************************************************************************************************************************************************************

Generation

************************************************************************************************************************************************************/
#ifndef MA_NO_GENERATION

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


typedef struct
{
    ma_data_source_callbacks ds;
    ma_waveform_config config;
    double advance;
    double time;
} ma_waveform;

MA_API ma_result ma_waveform_init(const ma_waveform_config* pConfig, ma_waveform* pWaveform);
MA_API ma_uint64 ma_waveform_read_pcm_frames(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount);
MA_API ma_result ma_waveform_seek_to_pcm_frame(ma_waveform* pWaveform, ma_uint64 frameIndex);
MA_API ma_result ma_waveform_set_amplitude(ma_waveform* pWaveform, double amplitude);
MA_API ma_result ma_waveform_set_frequency(ma_waveform* pWaveform, double frequency);
MA_API ma_result ma_waveform_set_sample_rate(ma_waveform* pWaveform, ma_uint32 sampleRate);



typedef enum
{
    ma_noise_type_white,
    ma_noise_type_pink,

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

            ma_uint32 counter[MA_MAX_CHANNELS];
        } pink;
        struct
        {
            double accumulation[MA_MAX_CHANNELS];
        } brownian;
    } state;
} ma_noise;

MA_API ma_result ma_noise_init(const ma_noise_config* pConfig, ma_noise* pNoise);
MA_API ma_uint64 ma_noise_read_pcm_frames(ma_noise* pNoise, void* pFramesOut, ma_uint64 frameCount);

#endif  /* MA_NO_GENERATION */

#ifdef __cplusplus
}
#endif
#endif  /* miniaudio_h */



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


#define MA_ZERO_OBJECT(p) MA_ZERO_MEMORY((p), sizeof(*(p)))

#define ma_countof(x)               (sizeof(x) / sizeof(x[0]))
#define ma_max(x, y)                (((x) > (y)) ? (x) : (y))
#define ma_min(x, y)                (((x) < (y)) ? (x) : (y))
#define ma_abs(x)                   (((x) > 0) ? (x) : -(x))
#define ma_clamp(x, lo, hi)         (ma_max(lo, ma_min(x, hi)))
#define ma_offset_ptr(p, offset)    (((ma_uint8*)(p)) + (offset))

#define ma_buffer_frame_capacity(buffer, channels, format) (sizeof(buffer) / ma_get_bytes_per_sample(format) / (channels))

static MA_INLINE double ma_sin(double x)
{
    /* TODO: Implement custom sin(x). */
    return sin(x);
}

static MA_INLINE double ma_exp(double x)
{
    /* TODO: Implement custom exp(x). */

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

            } else {
                *pDst = *pSrc;
            }
        }
    }

    return MA_SUCCESS;
}


MA_API ma_uint64 ma_calculate_frame_count_after_resampling(ma_uint32 sampleRateOut, ma_uint32 sampleRateIn, ma_uint64 frameCountIn)
{
    /* For robustness we're going to use a resampler object to calculate this since that already has a way of calculating this. */
    ma_result result;
    ma_uint64 frameCountOut;
    ma_resampler_config config;
    ma_resampler resampler;

    if (sampleRateOut == sampleRateIn) {
        return frameCountIn;
    }

    config = ma_resampler_config_init(ma_format_s16, 1, sampleRateIn, sampleRateOut, ma_resample_algorithm_linear);
    result = ma_resampler_init(&config, &resampler);
    if (result != MA_SUCCESS) {
        return 0;
    }

    frameCountOut = ma_resampler_get_expected_output_frame_count(&resampler, frameCountIn);

    ma_resampler_uninit(&resampler);
    return frameCountOut;
}

#ifndef MA_DATA_CONVERTER_STACK_BUFFER_SIZE
#define MA_DATA_CONVERTER_STACK_BUFFER_SIZE     4096
#endif



#if defined(MA_WIN32)
static ma_result ma_result_from_GetLastError(DWORD error)

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

            closestDiff = diff;
            closestRate = standardRate;
        }
    }

    return closestRate;
}
#endif


static void ma_device__on_data(ma_device* pDevice, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount)
{
    float masterVolumeFactor;
    
    masterVolumeFactor = pDevice->masterVolumeFactor;

    if (pDevice->onData) {
        if (!pDevice->noPreZeroedOutputBuffer && pFramesOut != NULL) {
            ma_silence_pcm_frames(pFramesOut, frameCount, pDevice->playback.format, pDevice->playback.channels);
        }

        /* Volume control of input makes things a bit awkward because the input buffer is read-only. We'll need to use a temp buffer and loop in this case. */
        if (pFramesIn != NULL && masterVolumeFactor < 1) {
            ma_uint8 tempFramesIn[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
            ma_uint32 bpfCapture  = ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
            ma_uint32 bpfPlayback = ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
            ma_uint32 totalFramesProcessed = 0;
            while (totalFramesProcessed < frameCount) {
                ma_uint32 framesToProcessThisIteration = frameCount - totalFramesProcessed;
                if (framesToProcessThisIteration > sizeof(tempFramesIn)/bpfCapture) {
                    framesToProcessThisIteration = sizeof(tempFramesIn)/bpfCapture;
                }

                ma_copy_and_apply_volume_factor_pcm_frames(tempFramesIn, ma_offset_ptr(pFramesIn, totalFramesProcessed*bpfCapture), framesToProcessThisIteration, pDevice->capture.format, pDevice->capture.channels, masterVolumeFactor);

                pDevice->onData(pDevice, ma_offset_ptr(pFramesOut, totalFramesProcessed*bpfPlayback), tempFramesIn, framesToProcessThisIteration);

                totalFramesProcessed += framesToProcessThisIteration;
            }
        } else {
            pDevice->onData(pDevice, pFramesOut, pFramesIn, frameCount);
        }

        /* Volume control and clipping for playback devices. */
        if (pFramesOut != NULL) {
            if (masterVolumeFactor < 1) {
                if (pFramesIn == NULL) {    /* <-- In full-duplex situations, the volume will have been applied to the input samples before the data callback. Applying it again post-callback will incorrectly compound it. */
                    ma_apply_volume_factor_pcm_frames(pFramesOut, frameCount, pDevice->playback.format, pDevice->playback.channels, masterVolumeFactor);
                }
            }

            if (!pDevice->noClip && pDevice->playback.format == ma_format_f32) {
                ma_clip_pcm_frames_f32((float*)pFramesOut, frameCount, pDevice->playback.channels);
            }
        }
    }
}



/* A helper function for reading sample data from the client. */
static void ma_device__read_frames_from_client(ma_device* pDevice, ma_uint32 frameCount, void* pFramesOut)
{
    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(frameCount > 0);
    MA_ASSERT(pFramesOut != NULL);

    if (pDevice->playback.converter.isPassthrough) {
        ma_device__on_data(pDevice, pFramesOut, NULL, frameCount);
    } else {
        ma_result result;
        ma_uint64 totalFramesReadOut;
        ma_uint64 totalFramesReadIn;
        void* pRunningFramesOut;

        totalFramesReadOut = 0;
        totalFramesReadIn  = 0;
        pRunningFramesOut  = pFramesOut;

        while (totalFramesReadOut < frameCount) {
            ma_uint8 pIntermediaryBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];  /* In client format. */
            ma_uint64 intermediaryBufferCap = sizeof(pIntermediaryBuffer) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
            ma_uint64 framesToReadThisIterationIn;
            ma_uint64 framesReadThisIterationIn;
            ma_uint64 framesToReadThisIterationOut;
            ma_uint64 framesReadThisIterationOut;
            ma_uint64 requiredInputFrameCount;

            framesToReadThisIterationOut = (frameCount - totalFramesReadOut);
            framesToReadThisIterationIn = framesToReadThisIterationOut;
            if (framesToReadThisIterationIn > intermediaryBufferCap) {
                framesToReadThisIterationIn = intermediaryBufferCap;
            }

            requiredInputFrameCount = ma_data_converter_get_required_input_frame_count(&pDevice->playback.converter, framesToReadThisIterationOut);
            if (framesToReadThisIterationIn > requiredInputFrameCount) {
                framesToReadThisIterationIn = requiredInputFrameCount;
            }

            if (framesToReadThisIterationIn > 0) {
                ma_device__on_data(pDevice, pIntermediaryBuffer, NULL, (ma_uint32)framesToReadThisIterationIn);
                totalFramesReadIn += framesToReadThisIterationIn;
            }

            /*
            At this point we have our decoded data in input format and now we need to convert to output format. Note that even if we didn't read any
            input frames, we still want to try processing frames because there may some output frames generated from cached input data.
            */
            framesReadThisIterationIn  = framesToReadThisIterationIn;
            framesReadThisIterationOut = framesToReadThisIterationOut;
            result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, pIntermediaryBuffer, &framesReadThisIterationIn, pRunningFramesOut, &framesReadThisIterationOut);
            if (result != MA_SUCCESS) {
                break;
            }

            totalFramesReadOut += framesReadThisIterationOut;
            pRunningFramesOut   = ma_offset_ptr(pRunningFramesOut, framesReadThisIterationOut * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));

            if (framesReadThisIterationIn == 0 && framesReadThisIterationOut == 0) {
                break;  /* We're done. */
            }
        }
    }
}

/* A helper for sending sample data to the client. */
static void ma_device__send_frames_to_client(ma_device* pDevice, ma_uint32 frameCountInDeviceFormat, const void* pFramesInDeviceFormat)
{
    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(frameCountInDeviceFormat > 0);
    MA_ASSERT(pFramesInDeviceFormat != NULL);

    if (pDevice->capture.converter.isPassthrough) {
        ma_device__on_data(pDevice, NULL, pFramesInDeviceFormat, frameCountInDeviceFormat);
    } else {
        ma_result result;
        ma_uint8 pFramesInClientFormat[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
        ma_uint64 framesInClientFormatCap = sizeof(pFramesInClientFormat) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
        ma_uint64 totalDeviceFramesProcessed = 0;
        ma_uint64 totalClientFramesProcessed = 0;
        const void* pRunningFramesInDeviceFormat = pFramesInDeviceFormat;

        /* We just keep going until we've exhaused all of our input frames and cannot generate any more output frames. */
        for (;;) {
            ma_uint64 deviceFramesProcessedThisIteration;
            ma_uint64 clientFramesProcessedThisIteration;

            deviceFramesProcessedThisIteration = (frameCountInDeviceFormat - totalDeviceFramesProcessed);
            clientFramesProcessedThisIteration = framesInClientFormatCap;

            result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningFramesInDeviceFormat, &deviceFramesProcessedThisIteration, pFramesInClientFormat, &clientFramesProcessedThisIteration);
            if (result != MA_SUCCESS) {
                break;
            }

            if (clientFramesProcessedThisIteration > 0) {
                ma_device__on_data(pDevice, NULL, pFramesInClientFormat, (ma_uint32)clientFramesProcessedThisIteration);    /* Safe cast. */
            }

            pRunningFramesInDeviceFormat = ma_offset_ptr(pRunningFramesInDeviceFormat, deviceFramesProcessedThisIteration * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));
            totalDeviceFramesProcessed  += deviceFramesProcessedThisIteration;
            totalClientFramesProcessed  += clientFramesProcessedThisIteration;

            if (deviceFramesProcessedThisIteration == 0 && clientFramesProcessedThisIteration == 0) {
                break;  /* We're done. */
            }
        }
    }
}


/* We only want to expose ma_device__handle_duplex_callback_capture() and ma_device__handle_duplex_callback_playback() if we have an asynchronous backend enabled. */
#if defined(MA_HAS_JACK)      || \
    defined(MA_HAS_COREAUDIO) || \
    defined(MA_HAS_AAUDIO)    || \
    defined(MA_HAS_OPENSL)    || \
    defined(MA_HAS_WEBAUDIO)
static ma_result ma_device__handle_duplex_callback_capture(ma_device* pDevice, ma_uint32 frameCountInDeviceFormat, const void* pFramesInDeviceFormat, ma_pcm_rb* pRB)
{
    ma_result result;
    ma_uint32 totalDeviceFramesProcessed = 0;
    const void* pRunningFramesInDeviceFormat = pFramesInDeviceFormat;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(frameCountInDeviceFormat > 0);
    MA_ASSERT(pFramesInDeviceFormat != NULL);
    MA_ASSERT(pRB != NULL);
    
    /* Write to the ring buffer. The ring buffer is in the client format which means we need to convert. */
    for (;;) {
        ma_uint32 framesToProcessInDeviceFormat = (frameCountInDeviceFormat - totalDeviceFramesProcessed);
        ma_uint32 framesToProcessInClientFormat = MA_DATA_CONVERTER_STACK_BUFFER_SIZE / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
        ma_uint64 framesProcessedInDeviceFormat;
        ma_uint64 framesProcessedInClientFormat;
        void* pFramesInClientFormat;

        result = ma_pcm_rb_acquire_write(pRB, &framesToProcessInClientFormat, &pFramesInClientFormat);
        if (result != MA_SUCCESS) {
            ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "Failed to acquire capture PCM frames from ring buffer.", result);
            break;
        }

        if (framesToProcessInClientFormat == 0) {
            if (ma_pcm_rb_pointer_distance(pRB) == (ma_int32)ma_pcm_rb_get_subbuffer_size(pRB)) {
                break;  /* Overrun. Not enough room in the ring buffer for input frame. Excess frames are dropped. */
            }
        }

        /* Convert. */
        framesProcessedInDeviceFormat = framesToProcessInDeviceFormat;
        framesProcessedInClientFormat = framesToProcessInClientFormat;
        result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningFramesInDeviceFormat, &framesProcessedInDeviceFormat, pFramesInClientFormat, &framesProcessedInClientFormat);
        if (result != MA_SUCCESS) {
            break;
        }

        result = ma_pcm_rb_commit_write(pRB, (ma_uint32)framesProcessedInClientFormat, pFramesInClientFormat);  /* Safe cast. */
        if (result != MA_SUCCESS) {
            ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "Failed to commit capture PCM frames to ring buffer.", result);
            break;
        }

        pRunningFramesInDeviceFormat = ma_offset_ptr(pRunningFramesInDeviceFormat, framesProcessedInDeviceFormat * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));
        totalDeviceFramesProcessed += (ma_uint32)framesProcessedInDeviceFormat; /* Safe cast. */

        /* We're done when we're unable to process any client nor device frames. */
        if (framesProcessedInClientFormat == 0 && framesProcessedInDeviceFormat == 0) {
            break;  /* Done. */
        }
    }

    return MA_SUCCESS;
}

static ma_result ma_device__handle_duplex_callback_playback(ma_device* pDevice, ma_uint32 frameCount, void* pFramesInInternalFormat, ma_pcm_rb* pRB)
{
    ma_result result;
    ma_uint8 playbackFramesInExternalFormat[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
    ma_uint8 silentInputFrames[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
    ma_uint32 totalFramesToReadFromClient;
    ma_uint32 totalFramesReadFromClient;
    ma_uint32 totalFramesReadOut = 0;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(frameCount > 0);
    MA_ASSERT(pFramesInInternalFormat != NULL);
    MA_ASSERT(pRB != NULL);
    
    /*
    Sitting in the ring buffer should be captured data from the capture callback in external format. If there's not enough data in there for
    the whole frameCount frames we just use silence instead for the input data.
    */
    MA_ZERO_MEMORY(silentInputFrames, sizeof(silentInputFrames));

    /* We need to calculate how many output frames are required to be read from the client to completely fill frameCount internal frames. */
    totalFramesToReadFromClient = (ma_uint32)ma_data_converter_get_required_input_frame_count(&pDevice->playback.converter, frameCount);
    totalFramesReadFromClient = 0;
    while (totalFramesReadFromClient < totalFramesToReadFromClient && ma_device_is_started(pDevice)) {
        ma_uint32 framesRemainingFromClient;
        ma_uint32 framesToProcessFromClient;
        ma_uint32 inputFrameCount;
        void* pInputFrames;

        framesRemainingFromClient = (totalFramesToReadFromClient - totalFramesReadFromClient);
        framesToProcessFromClient = sizeof(playbackFramesInExternalFormat) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
        if (framesToProcessFromClient > framesRemainingFromClient) {
            framesToProcessFromClient = framesRemainingFromClient;
        }

        /* We need to grab captured samples before firing the callback. If there's not enough input samples we just pass silence. */
        inputFrameCount = framesToProcessFromClient;
        result = ma_pcm_rb_acquire_read(pRB, &inputFrameCount, &pInputFrames);
        if (result == MA_SUCCESS) {
            if (inputFrameCount > 0) {
                /* Use actual input frames. */
                ma_device__on_data(pDevice, playbackFramesInExternalFormat, pInputFrames, inputFrameCount);
            } else {
                if (ma_pcm_rb_pointer_distance(pRB) == 0) {
                    break;  /* Underrun. */
                }
            }
            
            /* We're done with the captured samples. */
            result = ma_pcm_rb_commit_read(pRB, inputFrameCount, pInputFrames);
            if (result != MA_SUCCESS) {
                break; /* Don't know what to do here... Just abandon ship. */
            }
        } else {
            /* Use silent input frames. */
            inputFrameCount = ma_min(
                sizeof(playbackFramesInExternalFormat) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels),
                sizeof(silentInputFrames)              / ma_get_bytes_per_frame(pDevice->capture.format,  pDevice->capture.channels)
            );

            ma_device__on_data(pDevice, playbackFramesInExternalFormat, silentInputFrames, inputFrameCount);
        }

        /* We have samples in external format so now we need to convert to internal format and output to the device. */
        {
            ma_uint64 framesConvertedIn  = inputFrameCount;
            ma_uint64 framesConvertedOut = (frameCount - totalFramesReadOut);
            ma_data_converter_process_pcm_frames(&pDevice->playback.converter, playbackFramesInExternalFormat, &framesConvertedIn, pFramesInInternalFormat, &framesConvertedOut);

            totalFramesReadFromClient += (ma_uint32)framesConvertedIn;  /* Safe cast. */
            totalFramesReadOut        += (ma_uint32)framesConvertedOut; /* Safe cast. */
            pFramesInInternalFormat    = ma_offset_ptr(pFramesInInternalFormat, framesConvertedOut * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
        }
    }

    return MA_SUCCESS;
}
#endif  /* Asynchronous backends. */

/* A helper for changing the state of the device. */
static MA_INLINE void ma_device__set_state(ma_device* pDevice, ma_uint32 newState)
{

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

        return MA_ERROR;
    }

    if (ma_event_wait(&pDevice->null_device.operationCompletionEvent) != MA_SUCCESS) {
        return MA_ERROR;
    }

    return pDevice->null_device.operationResult;
}

static ma_uint64 ma_device_get_total_run_time_in_frames__null(ma_device* pDevice)
{
    ma_uint32 internalSampleRate;
    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        internalSampleRate = pDevice->capture.internalSampleRate;
    } else {
        internalSampleRate = pDevice->playback.internalSampleRate;
    }


    return (ma_uint64)((pDevice->null_device.priorRunTime + ma_timer_get_time_in_seconds(&pDevice->null_device.timer)) * internalSampleRate);

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

    MA_ASSERT(pDevice != NULL);

    MA_ZERO_OBJECT(&pDevice->null_device);

    if (pConfig->deviceType == ma_device_type_loopback) {
        return MA_DEVICE_TYPE_NOT_SUPPORTED;
    }

    periodSizeInFrames = pConfig->periodSizeInFrames;
    if (periodSizeInFrames == 0) {
        periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(pConfig->periodSizeInMilliseconds, pConfig->sampleRate);
    }

    if (pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) {
        ma_strncpy_s(pDevice->capture.name,  sizeof(pDevice->capture.name),  "NULL Capture Device",  (size_t)-1);
        pDevice->capture.internalFormat             = pConfig->capture.format;
        pDevice->capture.internalChannels           = pConfig->capture.channels;
        ma_channel_map_copy(pDevice->capture.internalChannelMap, pConfig->capture.channelMap, ma_min(pConfig->capture.channels, MA_MAX_CHANNELS));
        pDevice->capture.internalPeriodSizeInFrames = periodSizeInFrames;
        pDevice->capture.internalPeriods            = pConfig->periods;
    }

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

static ma_result ma_device_stop__null(ma_device* pDevice)
{
    MA_ASSERT(pDevice != NULL);

    ma_device_do_operation__null(pDevice, MA_DEVICE_OP_SUSPEND__NULL);

    c89atomic_exchange_32(&pDevice->null_device.isStarted, MA_FALSE);
    return MA_SUCCESS;
}

static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    ma_result result = MA_SUCCESS;
    ma_uint32 totalPCMFramesProcessed;
    ma_bool32 wasStartedOnEntry;

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

    wasStartedOnEntry = pDevice->null_device.isStarted;

    /* Keep going until everything has been read. */
    totalPCMFramesProcessed = 0;
    while (totalPCMFramesProcessed < frameCount) {
        ma_uint64 targetFrame;

        /* If there are any frames remaining in the current period, consume those first. */
        if (pDevice->null_device.currentPeriodFramesRemainingPlayback > 0) {
            ma_uint32 framesRemaining = (frameCount - totalPCMFramesProcessed);
            ma_uint32 framesToProcess = pDevice->null_device.currentPeriodFramesRemainingPlayback;
            if (framesToProcess > framesRemaining) {
                framesToProcess = framesRemaining;
            }

            /* We don't actually do anything with pPCMFrames, so just mark it as unused to prevent a warning. */
            (void)pPCMFrames;

            pDevice->null_device.currentPeriodFramesRemainingPlayback -= framesToProcess;
            totalPCMFramesProcessed += framesToProcess;
        }

        /* If we've consumed the current period we'll need to mark it as such an ensure the device is started if it's not already. */
        if (pDevice->null_device.currentPeriodFramesRemainingPlayback == 0) {
            pDevice->null_device.currentPeriodFramesRemainingPlayback = 0;

            if (!pDevice->null_device.isStarted && !wasStartedOnEntry) {
                result = ma_device_start__null(pDevice);
                if (result != MA_SUCCESS) {
                    break;
                }
            }
        }

        /* If we've consumed the whole buffer we can return now. */
        MA_ASSERT(totalPCMFramesProcessed <= frameCount);
        if (totalPCMFramesProcessed == frameCount) {
            break;
        }

        /* Getting here means we've still got more frames to consume, we but need to wait for it to become available. */
        targetFrame = pDevice->null_device.lastProcessedFramePlayback;
        for (;;) {
            ma_uint64 currentFrame;

            /* Stop waiting if the device has been stopped. */
            if (!pDevice->null_device.isStarted) {
                break;
            }

            currentFrame = ma_device_get_total_run_time_in_frames__null(pDevice);
            if (currentFrame >= targetFrame) {
                break;
            }

            /* Getting here means we haven't yet reached the target sample, so continue waiting. */
            ma_sleep(10);
        }

        pDevice->null_device.lastProcessedFramePlayback          += pDevice->playback.internalPeriodSizeInFrames;
        pDevice->null_device.currentPeriodFramesRemainingPlayback = pDevice->playback.internalPeriodSizeInFrames;
    }

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

    return result;
}

static ma_result ma_device_read__null(ma_device* pDevice, void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    ma_result result = MA_SUCCESS;
    ma_uint32 totalPCMFramesProcessed;

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

    /* Keep going until everything has been read. */
    totalPCMFramesProcessed = 0;
    while (totalPCMFramesProcessed < frameCount) {
        ma_uint64 targetFrame;

        /* If there are any frames remaining in the current period, consume those first. */
        if (pDevice->null_device.currentPeriodFramesRemainingCapture > 0) {
            ma_uint32 bpf = ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
            ma_uint32 framesRemaining = (frameCount - totalPCMFramesProcessed);
            ma_uint32 framesToProcess = pDevice->null_device.currentPeriodFramesRemainingCapture;
            if (framesToProcess > framesRemaining) {
                framesToProcess = framesRemaining;
            }

            /* We need to ensure the output buffer is zeroed. */
            MA_ZERO_MEMORY(ma_offset_ptr(pPCMFrames, totalPCMFramesProcessed*bpf), framesToProcess*bpf);

            pDevice->null_device.currentPeriodFramesRemainingCapture -= framesToProcess;
            totalPCMFramesProcessed += framesToProcess;
        }

        /* If we've consumed the current period we'll need to mark it as such an ensure the device is started if it's not already. */
        if (pDevice->null_device.currentPeriodFramesRemainingCapture == 0) {
            pDevice->null_device.currentPeriodFramesRemainingCapture = 0;
        }

        /* If we've consumed the whole buffer we can return now. */
        MA_ASSERT(totalPCMFramesProcessed <= frameCount);
        if (totalPCMFramesProcessed == frameCount) {
            break;
        }

        /* Getting here means we've still got more frames to consume, we but need to wait for it to become available. */
        targetFrame = pDevice->null_device.lastProcessedFrameCapture + pDevice->capture.internalPeriodSizeInFrames;
        for (;;) {
            ma_uint64 currentFrame;

            /* Stop waiting if the device has been stopped. */
            if (!pDevice->null_device.isStarted) {
                break;
            }

            currentFrame = ma_device_get_total_run_time_in_frames__null(pDevice);
            if (currentFrame >= targetFrame) {
                break;
            }

            /* Getting here means we haven't yet reached the target sample, so continue waiting. */
            ma_sleep(10);
        }

        pDevice->null_device.lastProcessedFrameCapture          += pDevice->capture.internalPeriodSizeInFrames;
        pDevice->null_device.currentPeriodFramesRemainingCapture = pDevice->capture.internalPeriodSizeInFrames;

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


    return result;
}

static ma_result ma_device_main_loop__null(ma_device* pDevice)
{
    ma_result result = MA_SUCCESS;
    ma_bool32 exitLoop = MA_FALSE;
    ma_uint8  capturedDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
    ma_uint8  playbackDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
    ma_uint32 capturedDeviceDataCapInFrames = sizeof(capturedDeviceData) / ma_get_bytes_per_frame(pDevice->capture.internalFormat,  pDevice->capture.internalChannels);
    ma_uint32 playbackDeviceDataCapInFrames = sizeof(playbackDeviceData) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    
    MA_ASSERT(pDevice != NULL);

    /* The capture device needs to be started immediately. */
    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        result = ma_device_start__null(pDevice);
        if (result != MA_SUCCESS) {
            return result;
        }
    }

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

                        break;
                    }

                    capturedDeviceFramesRemaining = capturedDeviceFramesToProcess;
                    capturedDeviceFramesProcessed = 0;

                    /* At this point we have our captured data in device format and we now need to convert it to client format. */
                    for (;;) {
                        ma_uint8  capturedClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint8  playbackClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint32 capturedClientDataCapInFrames = sizeof(capturedClientData) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
                        ma_uint32 playbackClientDataCapInFrames = sizeof(playbackClientData) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
                        ma_uint64 capturedClientFramesToProcessThisIteration = ma_min(capturedClientDataCapInFrames, playbackClientDataCapInFrames);
                        ma_uint64 capturedDeviceFramesToProcessThisIteration = capturedDeviceFramesRemaining;
                        ma_uint8* pRunningCapturedDeviceFrames = ma_offset_ptr(capturedDeviceData, capturedDeviceFramesProcessed * ma_get_bytes_per_frame(pDevice->capture.internalFormat,  pDevice->capture.internalChannels));
                        
                        /* Convert capture data from device format to client format. */
                        result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningCapturedDeviceFrames, &capturedDeviceFramesToProcessThisIteration, capturedClientData, &capturedClientFramesToProcessThisIteration);
                        if (result != MA_SUCCESS) {
                            break;
                        }

                        /*
                        If we weren't able to generate any output frames it must mean we've exhaused all of our input. The only time this would not be the case is if capturedClientData was too small
                        which should never be the case when it's of the size MA_DATA_CONVERTER_STACK_BUFFER_SIZE.
                        */
                        if (capturedClientFramesToProcessThisIteration == 0) {
                            break;
                        }

                        ma_device__on_data(pDevice, playbackClientData, capturedClientData, (ma_uint32)capturedClientFramesToProcessThisIteration);    /* Safe cast .*/

                        capturedDeviceFramesProcessed += (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */
                        capturedDeviceFramesRemaining -= (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */

                        /* At this point the playbackClientData buffer should be holding data that needs to be written to the device. */
                        for (;;) {
                            ma_uint64 convertedClientFrameCount = capturedClientFramesToProcessThisIteration;
                            ma_uint64 convertedDeviceFrameCount = playbackDeviceDataCapInFrames;
                            result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, playbackClientData, &convertedClientFrameCount, playbackDeviceData, &convertedDeviceFrameCount);
                            if (result != MA_SUCCESS) {
                                break;
                            }

                            result = ma_device_write__null(pDevice, playbackDeviceData, (ma_uint32)convertedDeviceFrameCount, NULL);   /* Safe cast. */
                            if (result != MA_SUCCESS) {
                                exitLoop = MA_TRUE;
                                break;
                            }

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

                        }
                    }

                    totalCapturedDeviceFramesProcessed += capturedDeviceFramesProcessed;
                }
            } break;

            case ma_device_type_capture:
            {
                ma_uint32 periodSizeInFrames = pDevice->capture.internalPeriodSizeInFrames;
                ma_uint32 framesReadThisPeriod = 0;
                while (framesReadThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesReadThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToReadThisIteration = framesRemainingInPeriod;
                    if (framesToReadThisIteration > capturedDeviceDataCapInFrames) {
                        framesToReadThisIteration = capturedDeviceDataCapInFrames;
                    }

                    result = ma_device_read__null(pDevice, capturedDeviceData, framesToReadThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    ma_device__send_frames_to_client(pDevice, framesProcessed, capturedDeviceData);

                    framesReadThisPeriod += framesProcessed;
                }
            } break;

            case ma_device_type_playback:
            {
                /* We write in chunks of the period size, but use a stack allocated buffer for the intermediary. */
                ma_uint32 periodSizeInFrames = pDevice->playback.internalPeriodSizeInFrames;
                ma_uint32 framesWrittenThisPeriod = 0;
                while (framesWrittenThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesWrittenThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToWriteThisIteration = framesRemainingInPeriod;
                    if (framesToWriteThisIteration > playbackDeviceDataCapInFrames) {
                        framesToWriteThisIteration = playbackDeviceDataCapInFrames;
                    }

                    ma_device__read_frames_from_client(pDevice, framesToWriteThisIteration, playbackDeviceData);

                    result = ma_device_write__null(pDevice, playbackDeviceData, framesToWriteThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    framesWrittenThisPeriod += framesProcessed;
                }
            } break;

            /* To silence a warning. Will never hit this. */
            case ma_device_type_loopback:
            default: break;
        }
    }


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

    pData->channelsOut = wf.Format.nChannels;
    pData->sampleRateOut = wf.Format.nSamplesPerSec;

    /* Get the internal channel map based on the channel mask. */
    ma_channel_mask_to_channel_map__win32(wf.dwChannelMask, pData->channelsOut, pData->channelMapOut);

    /* Period size. */
    pData->periodsOut = pData->periodsIn;
    pData->periodSizeInFramesOut = pData->periodSizeInFramesIn;
    if (pData->periodSizeInFramesOut == 0) {
        pData->periodSizeInFramesOut = ma_calculate_buffer_size_in_frames_from_milliseconds(pData->periodSizeInMillisecondsIn, wf.Format.nSamplesPerSec);
    }

    periodDurationInMicroseconds = ((ma_uint64)pData->periodSizeInFramesOut * 1000 * 1000) / wf.Format.nSamplesPerSec;


    /* Slightly different initialization for shared and exclusive modes. We try exclusive mode first, and if it fails, fall back to shared mode. */
    if (shareMode == MA_AUDCLNT_SHAREMODE_EXCLUSIVE) {
        MA_REFERENCE_TIME bufferDuration = periodDurationInMicroseconds * 10;

        /*

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

        ma_IMMDeviceEnumerator_Release(pDeviceEnumerator);
    }
#endif

    c89atomic_exchange_32(&pDevice->wasapi.isStartedCapture,  MA_FALSE);
    c89atomic_exchange_32(&pDevice->wasapi.isStartedPlayback, MA_FALSE);

    return MA_SUCCESS;
}

static ma_result ma_device__get_available_frames__wasapi(ma_device* pDevice, ma_IAudioClient* pAudioClient, ma_uint32* pFrameCount)
{
    ma_uint32 paddingFramesCount;
    HRESULT hr;
    ma_share_mode shareMode;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pFrameCount != NULL);
    
    *pFrameCount = 0;

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


    return MA_SUCCESS;
}


static ma_result ma_device_main_loop__wasapi(ma_device* pDevice)
{
    ma_result result;
    HRESULT hr;
    ma_bool32 exitLoop = MA_FALSE;
    ma_uint32 framesWrittenToPlaybackDevice = 0;
    ma_uint32 mappedDeviceBufferSizeInFramesCapture = 0;
    ma_uint32 mappedDeviceBufferSizeInFramesPlayback = 0;
    ma_uint32 mappedDeviceBufferFramesRemainingCapture = 0;
    ma_uint32 mappedDeviceBufferFramesRemainingPlayback = 0;
    BYTE* pMappedDeviceBufferCapture = NULL;
    BYTE* pMappedDeviceBufferPlayback = NULL;
    ma_uint32 bpfCaptureDevice = ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
    ma_uint32 bpfPlaybackDevice = ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    ma_uint32 bpfCaptureClient = ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
    ma_uint32 bpfPlaybackClient = ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
    ma_uint8  inputDataInClientFormat[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
    ma_uint32 inputDataInClientFormatCap = sizeof(inputDataInClientFormat) / bpfCaptureClient;
    ma_uint8  outputDataInClientFormat[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
    ma_uint32 outputDataInClientFormatCap = sizeof(outputDataInClientFormat) / bpfPlaybackClient;
    ma_uint32 outputDataInClientFormatCount = 0;
    ma_uint32 outputDataInClientFormatConsumed = 0;
    ma_uint32 periodSizeInFramesCapture = 0;

    MA_ASSERT(pDevice != NULL);

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

            if (result != MA_SUCCESS) {
                exitLoop = MA_TRUE;
                break;
            }
        }

        switch (pDevice->type)
        {
            case ma_device_type_duplex:
            {
                ma_uint32 framesAvailableCapture;
                ma_uint32 framesAvailablePlayback;
                DWORD flagsCapture;    /* Passed to IAudioCaptureClient_GetBuffer(). */

                /* The process is to map the playback buffer and fill it as quickly as possible from input data. */
                if (pMappedDeviceBufferPlayback == NULL) {
                    /* WASAPI is weird with exclusive mode. You need to wait on the event _before_ querying the available frames. */
                    if (pDevice->playback.shareMode == ma_share_mode_exclusive) {
                        if (WaitForSingleObject(pDevice->wasapi.hEventPlayback, INFINITE) != WAIT_OBJECT_0) {
                            return MA_ERROR;   /* Wait failed. */
                        }
                    }

                    result = ma_device__get_available_frames__wasapi(pDevice, (ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback, &framesAvailablePlayback);
                    if (result != MA_SUCCESS) {
                        return result;
                    }

                    /*printf("TRACE 1: framesAvailablePlayback=%d\n", framesAvailablePlayback);*/


                    /* In exclusive mode, the frame count needs to exactly match the value returned by GetCurrentPadding(). */
                    if (pDevice->playback.shareMode != ma_share_mode_exclusive) {
                        if (framesAvailablePlayback > pDevice->wasapi.periodSizeInFramesPlayback) {
                            framesAvailablePlayback = pDevice->wasapi.periodSizeInFramesPlayback;
                        }
                    }

                    /* If there's no frames available in the playback device we need to wait for more. */
                    if (framesAvailablePlayback == 0) {
                        /* In exclusive mode we waited at the top. */
                        if (pDevice->playback.shareMode != ma_share_mode_exclusive) {
                            if (WaitForSingleObject(pDevice->wasapi.hEventPlayback, INFINITE) != WAIT_OBJECT_0) {
                                return MA_ERROR;   /* Wait failed. */
                            }
                        }

                        continue;
                    }

                    /* We're ready to map the playback device's buffer. We don't release this until it's been entirely filled. */
                    hr = ma_IAudioRenderClient_GetBuffer((ma_IAudioRenderClient*)pDevice->wasapi.pRenderClient, framesAvailablePlayback, &pMappedDeviceBufferPlayback);
                    if (FAILED(hr)) {
                        ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to retrieve internal buffer from playback device in preparation for writing to the device.", ma_result_from_HRESULT(hr));
                        exitLoop = MA_TRUE;
                        break;
                    }

                    mappedDeviceBufferSizeInFramesPlayback    = framesAvailablePlayback;
                    mappedDeviceBufferFramesRemainingPlayback = framesAvailablePlayback;
                }

                /* At this point we should have a buffer available for output. We need to keep writing input samples to it. */
                for (;;) {
                    /* Try grabbing some captured data if we haven't already got a mapped buffer. */
                    if (pMappedDeviceBufferCapture == NULL) {
                        if (pDevice->capture.shareMode == ma_share_mode_shared) {
                            if (WaitForSingleObject(pDevice->wasapi.hEventCapture, INFINITE) != WAIT_OBJECT_0) {
                                return MA_ERROR;   /* Wait failed. */
                            }
                        }

                        result = ma_device__get_available_frames__wasapi(pDevice, (ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture, &framesAvailableCapture);
                        if (result != MA_SUCCESS) {
                            exitLoop = MA_TRUE;
                            break;
                        }

                        /*printf("TRACE 2: framesAvailableCapture=%d\n", framesAvailableCapture);*/

                        /* Wait for more if nothing is available. */
                        if (framesAvailableCapture == 0) {
                            /* In exclusive mode we waited at the top. */
                            if (pDevice->capture.shareMode != ma_share_mode_shared) {
                                if (WaitForSingleObject(pDevice->wasapi.hEventCapture, INFINITE) != WAIT_OBJECT_0) {
                                    return MA_ERROR;   /* Wait failed. */
                                }
                            }

                            continue;
                        }

                        /* Getting here means there's data available for writing to the output device. */
                        mappedDeviceBufferSizeInFramesCapture = ma_min(framesAvailableCapture, periodSizeInFramesCapture);
                        hr = ma_IAudioCaptureClient_GetBuffer((ma_IAudioCaptureClient*)pDevice->wasapi.pCaptureClient, (BYTE**)&pMappedDeviceBufferCapture, &mappedDeviceBufferSizeInFramesCapture, &flagsCapture, NULL, NULL);
                        if (FAILED(hr)) {
                            ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to retrieve internal buffer from capture device in preparation for writing to the device.", ma_result_from_HRESULT(hr));
                            exitLoop = MA_TRUE;
                            break;
                        }


                        /* Overrun detection. */
                        if ((flagsCapture & MA_AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY) != 0) {
                            /* Glitched. Probably due to an overrun. */
                        #ifdef MA_DEBUG_OUTPUT
                            printf("[WASAPI] Data discontinuity (possible overrun). framesAvailableCapture=%d, mappedBufferSizeInFramesCapture=%d\n", framesAvailableCapture, mappedDeviceBufferSizeInFramesCapture);
                        #endif

                            /*
                            Exeriment: If we get an overrun it probably means we're straddling the end of the buffer. In order to prevent a never-ending sequence of glitches let's experiment
                            by dropping every frame until we're left with only a single period. To do this we just keep retrieving and immediately releasing buffers until we're down to the
                            last period.
                            */
                            if (framesAvailableCapture >= pDevice->wasapi.actualPeriodSizeInFramesCapture) {
                            #ifdef MA_DEBUG_OUTPUT
                                printf("[WASAPI] Synchronizing capture stream. ");
                            #endif
                                do
                                {
                                    hr = ma_IAudioCaptureClient_ReleaseBuffer((ma_IAudioCaptureClient*)pDevice->wasapi.pCaptureClient, mappedDeviceBufferSizeInFramesCapture);
                                    if (FAILED(hr)) {
                                        break;
                                    }

                                    framesAvailableCapture -= mappedDeviceBufferSizeInFramesCapture;
                                    
                                    if (framesAvailableCapture > 0) {
                                        mappedDeviceBufferSizeInFramesCapture = ma_min(framesAvailableCapture, periodSizeInFramesCapture);
                                        hr = ma_IAudioCaptureClient_GetBuffer((ma_IAudioCaptureClient*)pDevice->wasapi.pCaptureClient, (BYTE**)&pMappedDeviceBufferCapture, &mappedDeviceBufferSizeInFramesCapture, &flagsCapture, NULL, NULL);
                                        if (FAILED(hr)) {
                                            ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to retrieve internal buffer from capture device in preparation for writing to the device.", ma_result_from_HRESULT(hr));
                                            exitLoop = MA_TRUE;
                                            break;
                                        }
                                    } else {
                                        pMappedDeviceBufferCapture = NULL;
                                        mappedDeviceBufferSizeInFramesCapture = 0;
                                    }
                                } while (framesAvailableCapture > periodSizeInFramesCapture);
                            #ifdef MA_DEBUG_OUTPUT
                                printf("framesAvailableCapture=%d, mappedBufferSizeInFramesCapture=%d\n", framesAvailableCapture, mappedDeviceBufferSizeInFramesCapture);
                            #endif
                            }
                        } else {
                        #ifdef MA_DEBUG_OUTPUT
                            if (flagsCapture != 0) {
                                printf("[WASAPI] Capture Flags: %ld\n", flagsCapture);
                            }
                        #endif
                        }

                        mappedDeviceBufferFramesRemainingCapture = mappedDeviceBufferSizeInFramesCapture;
                    }


                    /* At this point we should have both input and output data available. We now need to convert the data and post it to the client. */
                    for (;;) {
                        BYTE* pRunningDeviceBufferCapture;
                        BYTE* pRunningDeviceBufferPlayback;
                        ma_uint32 framesToProcess;
                        ma_uint32 framesProcessed;

                        pRunningDeviceBufferCapture  = pMappedDeviceBufferCapture  + ((mappedDeviceBufferSizeInFramesCapture  - mappedDeviceBufferFramesRemainingCapture ) * bpfCaptureDevice);
                        pRunningDeviceBufferPlayback = pMappedDeviceBufferPlayback + ((mappedDeviceBufferSizeInFramesPlayback - mappedDeviceBufferFramesRemainingPlayback) * bpfPlaybackDevice);
                        
                        /* There may be some data sitting in the converter that needs to be processed first. Once this is exhaused, run the data callback again. */
                        if (!pDevice->playback.converter.isPassthrough && outputDataInClientFormatConsumed < outputDataInClientFormatCount) {
                            ma_uint64 convertedFrameCountClient = (outputDataInClientFormatCount - outputDataInClientFormatConsumed);
                            ma_uint64 convertedFrameCountDevice = mappedDeviceBufferFramesRemainingPlayback;
                            void* pConvertedFramesClient = outputDataInClientFormat + (outputDataInClientFormatConsumed * bpfPlaybackClient);
                            void* pConvertedFramesDevice = pRunningDeviceBufferPlayback;
                            result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, pConvertedFramesClient, &convertedFrameCountClient, pConvertedFramesDevice, &convertedFrameCountDevice);
                            if (result != MA_SUCCESS) {
                                break;
                            }

                            outputDataInClientFormatConsumed          += (ma_uint32)convertedFrameCountClient;  /* Safe cast. */
                            mappedDeviceBufferFramesRemainingPlayback -= (ma_uint32)convertedFrameCountDevice;  /* Safe cast. */

                            if (mappedDeviceBufferFramesRemainingPlayback == 0) {
                                break;
                            }
                        }

                        /*
                        Getting here means we need to fire the callback. If format conversion is unnecessary, we can optimize this by passing the pointers to the internal
                        buffers directly to the callback.
                        */
                        if (pDevice->capture.converter.isPassthrough && pDevice->playback.converter.isPassthrough) {
                            /* Optimal path. We can pass mapped pointers directly to the callback. */
                            framesToProcess = ma_min(mappedDeviceBufferFramesRemainingCapture, mappedDeviceBufferFramesRemainingPlayback);
                            framesProcessed = framesToProcess;

                            ma_device__on_data(pDevice, pRunningDeviceBufferPlayback, pRunningDeviceBufferCapture, framesToProcess);

                            mappedDeviceBufferFramesRemainingCapture  -= framesProcessed;
                            mappedDeviceBufferFramesRemainingPlayback -= framesProcessed;

                            if (mappedDeviceBufferFramesRemainingCapture == 0) {
                                break;  /* Exhausted input data. */
                            }
                            if (mappedDeviceBufferFramesRemainingPlayback == 0) {
                                break;  /* Exhausted output data. */
                            }
                        } else if (pDevice->capture.converter.isPassthrough) {
                            /* The input buffer is a passthrough, but the playback buffer requires a conversion. */
                            framesToProcess = ma_min(mappedDeviceBufferFramesRemainingCapture, outputDataInClientFormatCap);
                            framesProcessed = framesToProcess;

                            ma_device__on_data(pDevice, outputDataInClientFormat, pRunningDeviceBufferCapture, framesToProcess);
                            outputDataInClientFormatCount    = framesProcessed;
                            outputDataInClientFormatConsumed = 0;

                            mappedDeviceBufferFramesRemainingCapture -= framesProcessed;
                            if (mappedDeviceBufferFramesRemainingCapture == 0) {
                                break;  /* Exhausted input data. */
                            }
                        } else if (pDevice->playback.converter.isPassthrough) {
                            /* The input buffer requires conversion, the playback buffer is passthrough. */
                            ma_uint64 capturedDeviceFramesToProcess = mappedDeviceBufferFramesRemainingCapture;
                            ma_uint64 capturedClientFramesToProcess = ma_min(inputDataInClientFormatCap, mappedDeviceBufferFramesRemainingPlayback);

                            result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningDeviceBufferCapture, &capturedDeviceFramesToProcess, inputDataInClientFormat, &capturedClientFramesToProcess);
                            if (result != MA_SUCCESS) {
                                break;
                            }

                            if (capturedClientFramesToProcess == 0) {
                                break;
                            }

                            ma_device__on_data(pDevice, pRunningDeviceBufferPlayback, inputDataInClientFormat, (ma_uint32)capturedClientFramesToProcess);   /* Safe cast. */

                            mappedDeviceBufferFramesRemainingCapture  -= (ma_uint32)capturedDeviceFramesToProcess;
                            mappedDeviceBufferFramesRemainingPlayback -= (ma_uint32)capturedClientFramesToProcess;
                        } else {
                            ma_uint64 capturedDeviceFramesToProcess = mappedDeviceBufferFramesRemainingCapture;
                            ma_uint64 capturedClientFramesToProcess = ma_min(inputDataInClientFormatCap, outputDataInClientFormatCap);

                            result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningDeviceBufferCapture, &capturedDeviceFramesToProcess, inputDataInClientFormat, &capturedClientFramesToProcess);
                            if (result != MA_SUCCESS) {
                                break;
                            }

                            if (capturedClientFramesToProcess == 0) {
                                break;
                            }

                            ma_device__on_data(pDevice, outputDataInClientFormat, inputDataInClientFormat, (ma_uint32)capturedClientFramesToProcess);
                            

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

                /* If at this point we've run out of data we need to release the buffer. */
                if (mappedDeviceBufferFramesRemainingPlayback == 0 && pMappedDeviceBufferPlayback != NULL) {
                    hr = ma_IAudioRenderClient_ReleaseBuffer((ma_IAudioRenderClient*)pDevice->wasapi.pRenderClient, mappedDeviceBufferSizeInFramesPlayback, 0);
                    if (FAILED(hr)) {
                        ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to release internal buffer from playback device after writing to the device.", ma_result_from_HRESULT(hr));
                        exitLoop = MA_TRUE;
                        break;
                    }

                    /*printf("TRACE: Released playback buffer\n");*/
                    framesWrittenToPlaybackDevice += mappedDeviceBufferSizeInFramesPlayback;

                    pMappedDeviceBufferPlayback = NULL;
                    mappedDeviceBufferFramesRemainingPlayback = 0;
                    mappedDeviceBufferSizeInFramesPlayback    = 0;
                }

                if (!pDevice->wasapi.isStartedPlayback) {
                    ma_uint32 startThreshold = pDevice->playback.internalPeriodSizeInFrames * 1;

                    /* Prevent a deadlock. If we don't clamp against the actual buffer size we'll never end up starting the playback device which will result in a deadlock. */
                    if (startThreshold > pDevice->wasapi.actualPeriodSizeInFramesPlayback) {
                        startThreshold = pDevice->wasapi.actualPeriodSizeInFramesPlayback;
                    }

                    if (pDevice->playback.shareMode == ma_share_mode_exclusive || framesWrittenToPlaybackDevice >= startThreshold) {
                        hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback);
                        if (FAILED(hr)) {
                            ma_IAudioClient_Stop((ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture);
                            ma_IAudioClient_Reset((ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture);
                            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal playback device.", ma_result_from_HRESULT(hr));
                        }
                        c89atomic_exchange_32(&pDevice->wasapi.isStartedPlayback, MA_TRUE);
                    }
                }
            } break;



            case ma_device_type_capture:
            case ma_device_type_loopback:
            {
                ma_uint32 framesAvailableCapture;
                DWORD flagsCapture;    /* Passed to IAudioCaptureClient_GetBuffer(). */

                /* Wait for data to become available first. */
                if (WaitForSingleObject(pDevice->wasapi.hEventCapture, INFINITE) != WAIT_OBJECT_0) {
                    exitLoop = MA_TRUE;
                    break;   /* Wait failed. */
                }

                /* See how many frames are available. Since we waited at the top, I don't think this should ever return 0. I'm checking for this anyway. */
                result = ma_device__get_available_frames__wasapi(pDevice, (ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture, &framesAvailableCapture);
                if (result != MA_SUCCESS) {
                    exitLoop = MA_TRUE;
                    break;
                }

                if (framesAvailableCapture < pDevice->wasapi.periodSizeInFramesCapture) {
                    continue;   /* Nothing available. Keep waiting. */
                }

                /* Map the data buffer in preparation for sending to the client. */
                mappedDeviceBufferSizeInFramesCapture = framesAvailableCapture;
                hr = ma_IAudioCaptureClient_GetBuffer((ma_IAudioCaptureClient*)pDevice->wasapi.pCaptureClient, (BYTE**)&pMappedDeviceBufferCapture, &mappedDeviceBufferSizeInFramesCapture, &flagsCapture, NULL, NULL);
                if (FAILED(hr)) {
                    ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to retrieve internal buffer from capture device in preparation for writing to the device.", ma_result_from_HRESULT(hr));
                    exitLoop = MA_TRUE;
                    break;
                }

                /* Overrun detection. */
                if ((flagsCapture & MA_AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY) != 0) {
                    /* Glitched. Probably due to an overrun. */
                #ifdef MA_DEBUG_OUTPUT
                    printf("[WASAPI] Data discontinuity (possible overrun). framesAvailableCapture=%d, mappedBufferSizeInFramesCapture=%d\n", framesAvailableCapture, mappedDeviceBufferSizeInFramesCapture);
                #endif

                    /*
                    Exeriment: If we get an overrun it probably means we're straddling the end of the buffer. In order to prevent a never-ending sequence of glitches let's experiment
                    by dropping every frame until we're left with only a single period. To do this we just keep retrieving and immediately releasing buffers until we're down to the
                    last period.
                    */
                    if (framesAvailableCapture >= pDevice->wasapi.actualPeriodSizeInFramesCapture) {
                    #ifdef MA_DEBUG_OUTPUT
                        printf("[WASAPI] Synchronizing capture stream. ");
                    #endif
                        do
                        {
                            hr = ma_IAudioCaptureClient_ReleaseBuffer((ma_IAudioCaptureClient*)pDevice->wasapi.pCaptureClient, mappedDeviceBufferSizeInFramesCapture);
                            if (FAILED(hr)) {
                                break;
                            }

                            framesAvailableCapture -= mappedDeviceBufferSizeInFramesCapture;
                                    
                            if (framesAvailableCapture > 0) {
                                mappedDeviceBufferSizeInFramesCapture = ma_min(framesAvailableCapture, periodSizeInFramesCapture);
                                hr = ma_IAudioCaptureClient_GetBuffer((ma_IAudioCaptureClient*)pDevice->wasapi.pCaptureClient, (BYTE**)&pMappedDeviceBufferCapture, &mappedDeviceBufferSizeInFramesCapture, &flagsCapture, NULL, NULL);
                                if (FAILED(hr)) {
                                    ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to retrieve internal buffer from capture device in preparation for writing to the device.", ma_result_from_HRESULT(hr));
                                    exitLoop = MA_TRUE;
                                    break;
                                }
                            } else {
                                pMappedDeviceBufferCapture = NULL;
                                mappedDeviceBufferSizeInFramesCapture = 0;
                            }
                        } while (framesAvailableCapture > periodSizeInFramesCapture);
                    #ifdef MA_DEBUG_OUTPUT
                        printf("framesAvailableCapture=%d, mappedBufferSizeInFramesCapture=%d\n", framesAvailableCapture, mappedDeviceBufferSizeInFramesCapture);
                    #endif
                    }
                } else {
                #ifdef MA_DEBUG_OUTPUT
                    if (flagsCapture != 0) {
                        printf("[WASAPI] Capture Flags: %ld\n", flagsCapture);
                    }
                #endif
                }

                /* We should have a buffer at this point, but let's just do a sanity check anyway. */
                if (mappedDeviceBufferSizeInFramesCapture > 0 && pMappedDeviceBufferCapture != NULL) {
                    ma_device__send_frames_to_client(pDevice, mappedDeviceBufferSizeInFramesCapture, pMappedDeviceBufferCapture);

                    /* At this point we're done with the buffer. */
                    hr = ma_IAudioCaptureClient_ReleaseBuffer((ma_IAudioCaptureClient*)pDevice->wasapi.pCaptureClient, mappedDeviceBufferSizeInFramesCapture);
                    pMappedDeviceBufferCapture = NULL;    /* <-- Important. Not doing this can result in an error once we leave this loop because it will use this to know whether or not a final ReleaseBuffer() needs to be called. */
                    mappedDeviceBufferSizeInFramesCapture = 0;
                    if (FAILED(hr)) {
                        ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to release internal buffer from capture device after reading from the device.", ma_result_from_HRESULT(hr));
                        exitLoop = MA_TRUE;
                        break;
                    }
                }
            } break;



            case ma_device_type_playback:
            {
                ma_uint32 framesAvailablePlayback;

                /* Wait for space to become available first. */
                if (WaitForSingleObject(pDevice->wasapi.hEventPlayback, INFINITE) != WAIT_OBJECT_0) {
                    exitLoop = MA_TRUE;
                    break;   /* Wait failed. */
                }

                /* Check how much space is available. If this returns 0 we just keep waiting. */
                result = ma_device__get_available_frames__wasapi(pDevice, (ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback, &framesAvailablePlayback);
                if (result != MA_SUCCESS) {
                    exitLoop = MA_TRUE;
                    break;
                }

                if (framesAvailablePlayback < pDevice->wasapi.periodSizeInFramesPlayback) {
                    continue;   /* No space available. */
                }

                /* Map a the data buffer in preparation for the callback. */
                hr = ma_IAudioRenderClient_GetBuffer((ma_IAudioRenderClient*)pDevice->wasapi.pRenderClient, framesAvailablePlayback, &pMappedDeviceBufferPlayback);
                if (FAILED(hr)) {
                    ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to retrieve internal buffer from playback device in preparation for writing to the device.", ma_result_from_HRESULT(hr));
                    exitLoop = MA_TRUE;
                    break;
                }

                /* We should have a buffer at this point. */
                ma_device__read_frames_from_client(pDevice, framesAvailablePlayback, pMappedDeviceBufferPlayback);

                /* At this point we're done writing to the device and we just need to release the buffer. */
                hr = ma_IAudioRenderClient_ReleaseBuffer((ma_IAudioRenderClient*)pDevice->wasapi.pRenderClient, framesAvailablePlayback, 0);
                pMappedDeviceBufferPlayback = NULL;    /* <-- Important. Not doing this can result in an error once we leave this loop because it will use this to know whether or not a final ReleaseBuffer() needs to be called. */
                mappedDeviceBufferSizeInFramesPlayback = 0;

                if (FAILED(hr)) {
                    ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to release internal buffer from playback device after writing to the device.", ma_result_from_HRESULT(hr));
                    exitLoop = MA_TRUE;
                    break;
                }

                framesWrittenToPlaybackDevice += framesAvailablePlayback;
                if (!pDevice->wasapi.isStartedPlayback) {
                    if (pDevice->playback.shareMode == ma_share_mode_exclusive || framesWrittenToPlaybackDevice >= pDevice->playback.internalPeriodSizeInFrames*1) {
                        hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback);
                        if (FAILED(hr)) {
                            ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal playback device.", ma_result_from_HRESULT(hr));
                            exitLoop = MA_TRUE;
                            break;
                        }
                        c89atomic_exchange_32(&pDevice->wasapi.isStartedPlayback, MA_TRUE);
                    }
                }
            } break;

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

        c89atomic_exchange_32(&pDevice->wasapi.isStartedCapture, MA_FALSE);
    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        /* Any mapped buffers need to be released. */
        if (pMappedDeviceBufferPlayback != NULL) {
            hr = ma_IAudioRenderClient_ReleaseBuffer((ma_IAudioRenderClient*)pDevice->wasapi.pRenderClient, mappedDeviceBufferSizeInFramesPlayback, 0);
        }

        /*
        The buffer needs to be drained before stopping the device. Not doing this will result in the last few frames not getting output to
        the speakers. This is a problem for very short sounds because it'll result in a significant portion of it not getting played.
        */
        if (pDevice->wasapi.isStartedPlayback) {
            /* We need to make sure we put a timeout here or else we'll risk getting stuck in a deadlock in some cases. */
            DWORD waitTime = pDevice->wasapi.actualPeriodSizeInFramesPlayback / pDevice->playback.internalSampleRate;

            if (pDevice->playback.shareMode == ma_share_mode_exclusive) {
                WaitForSingleObject(pDevice->wasapi.hEventPlayback, waitTime);
            } else {
                ma_uint32 prevFramesAvaialablePlayback = (ma_uint32)-1;
                ma_uint32 framesAvailablePlayback;
                for (;;) {
                    result = ma_device__get_available_frames__wasapi(pDevice, (ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback, &framesAvailablePlayback);
                    if (result != MA_SUCCESS) {
                        break;
                    }

                    if (framesAvailablePlayback >= pDevice->wasapi.actualPeriodSizeInFramesPlayback) {
                        break;
                    }

                    /*
                    Just a safety check to avoid an infinite loop. If this iteration results in a situation where the number of available frames
                    has not changed, get out of the loop. I don't think this should ever happen, but I think it's nice to have just in case.
                    */
                    if (framesAvailablePlayback == prevFramesAvaialablePlayback) {
                        break;
                    }
                    prevFramesAvaialablePlayback = framesAvailablePlayback;

                    WaitForSingleObject(pDevice->wasapi.hEventPlayback, waitTime);
                    ResetEvent(pDevice->wasapi.hEventPlayback); /* Manual reset. */
                }
            }
        }

        hr = ma_IAudioClient_Stop((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback);
        if (FAILED(hr)) {
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to stop internal playback device.", ma_result_from_HRESULT(hr));

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


    MA_ASSERT(pDevice != NULL);
    MA_ZERO_OBJECT(&pDevice->dsound);

    if (pConfig->deviceType == ma_device_type_loopback) {
        return MA_DEVICE_TYPE_NOT_SUPPORTED;
    }

    periodSizeInMilliseconds = pConfig->periodSizeInMilliseconds;
    if (periodSizeInMilliseconds == 0) {
        periodSizeInMilliseconds = ma_calculate_buffer_size_in_milliseconds_from_frames(pConfig->periodSizeInFrames, pConfig->sampleRate);
    }
    
    /* DirectSound should use a latency of about 20ms per period for low latency mode. */
    if (pDevice->usingDefaultBufferSize) {
        if (pConfig->performanceProfile == ma_performance_profile_low_latency) {
            periodSizeInMilliseconds =  20;
        } else {
            periodSizeInMilliseconds = 200;
        }
    }

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

            ma_device_uninit__dsound(pDevice);
            return result;
        }

        wf.Format.nBlockAlign          = (WORD)(wf.Format.nChannels * wf.Format.wBitsPerSample / 8);
        wf.Format.nAvgBytesPerSec      = wf.Format.nBlockAlign * wf.Format.nSamplesPerSec;
        wf.Samples.wValidBitsPerSample = wf.Format.wBitsPerSample;
        wf.SubFormat                   = MA_GUID_KSDATAFORMAT_SUBTYPE_PCM;

        /* The size of the buffer must be a clean multiple of the period count. */
        periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(periodSizeInMilliseconds, wf.Format.nSamplesPerSec);

        MA_ZERO_OBJECT(&descDS);
        descDS.dwSize = sizeof(descDS);
        descDS.dwFlags = 0;
        descDS.dwBufferBytes = periodSizeInFrames * pConfig->periods * ma_get_bytes_per_frame(pDevice->capture.internalFormat, wf.Format.nChannels);
        descDS.lpwfxFormat = (WAVEFORMATEX*)&wf;
        hr = ma_IDirectSoundCapture_CreateCaptureBuffer((ma_IDirectSoundCapture*)pDevice->dsound.pCapture, &descDS, (ma_IDirectSoundCaptureBuffer**)&pDevice->dsound.pCaptureBuffer, NULL);
        if (FAILED(hr)) {
            ma_device_uninit__dsound(pDevice);
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundCapture_CreateCaptureBuffer() failed for capture device.", ma_result_from_HRESULT(hr));
        }

        /* Get the _actual_ properties of the buffer. */
        pActualFormat = (WAVEFORMATEXTENSIBLE*)rawdata;
        hr = ma_IDirectSoundCaptureBuffer_GetFormat((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, (WAVEFORMATEX*)pActualFormat, sizeof(rawdata), NULL);

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

        pDevice->capture.internalSampleRate = pActualFormat->Format.nSamplesPerSec;

        /* Get the internal channel map based on the channel mask. */
        if (pActualFormat->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
            ma_channel_mask_to_channel_map__win32(pActualFormat->dwChannelMask, pDevice->capture.internalChannels, pDevice->capture.internalChannelMap);
        } else {
            ma_channel_mask_to_channel_map__win32(wf.dwChannelMask, pDevice->capture.internalChannels, pDevice->capture.internalChannelMap);
        }

        /*
        After getting the actual format the size of the buffer in frames may have actually changed. However, we want this to be as close to what the
        user has asked for as possible, so let's go ahead and release the old capture buffer and create a new one in this case.
        */
        if (periodSizeInFrames != (descDS.dwBufferBytes / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels) / pConfig->periods)) {
            descDS.dwBufferBytes = periodSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.internalFormat, wf.Format.nChannels) * pConfig->periods;
            ma_IDirectSoundCaptureBuffer_Release((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer);

            hr = ma_IDirectSoundCapture_CreateCaptureBuffer((ma_IDirectSoundCapture*)pDevice->dsound.pCapture, &descDS, (ma_IDirectSoundCaptureBuffer**)&pDevice->dsound.pCaptureBuffer, NULL);
            if (FAILED(hr)) {
                ma_device_uninit__dsound(pDevice);
                return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[DirectSound] Second attempt at IDirectSoundCapture_CreateCaptureBuffer() failed for capture device.", ma_result_from_HRESULT(hr));
            }
        }

        /* DirectSound should give us a buffer exactly the size we asked for. */

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

        pDevice->playback.internalSampleRate = pActualFormat->Format.nSamplesPerSec;

        /* Get the internal channel map based on the channel mask. */
        if (pActualFormat->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
            ma_channel_mask_to_channel_map__win32(pActualFormat->dwChannelMask, pDevice->playback.internalChannels, pDevice->playback.internalChannelMap);
        } else {
            ma_channel_mask_to_channel_map__win32(wf.dwChannelMask, pDevice->playback.internalChannels, pDevice->playback.internalChannelMap);
        }

        /* The size of the buffer must be a clean multiple of the period count. */
        periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(periodSizeInMilliseconds, pDevice->playback.internalSampleRate);

        /*
        Meaning of dwFlags (from MSDN):
        
        DSBCAPS_CTRLPOSITIONNOTIFY
          The buffer has position notification capability.
        
        DSBCAPS_GLOBALFOCUS
          With this flag set, an application using DirectSound can continue to play its buffers if the user switches focus to
          another application, even if the new application uses DirectSound.
        
        DSBCAPS_GETCURRENTPOSITION2
          In the first version of DirectSound, the play cursor was significantly ahead of the actual playing sound on emulated
          sound cards; it was directly behind the write cursor. Now, if the DSBCAPS_GETCURRENTPOSITION2 flag is specified, the
          application can get a more accurate play cursor.
        */
        MA_ZERO_OBJECT(&descDS);
        descDS.dwSize = sizeof(descDS);
        descDS.dwFlags = MA_DSBCAPS_CTRLPOSITIONNOTIFY | MA_DSBCAPS_GLOBALFOCUS | MA_DSBCAPS_GETCURRENTPOSITION2;
        descDS.dwBufferBytes = periodSizeInFrames * pConfig->periods * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
        descDS.lpwfxFormat = (WAVEFORMATEX*)&wf;
        hr = ma_IDirectSound_CreateSoundBuffer((ma_IDirectSound*)pDevice->dsound.pPlayback, &descDS, (ma_IDirectSoundBuffer**)&pDevice->dsound.pPlaybackBuffer, NULL);
        if (FAILED(hr)) {
            ma_device_uninit__dsound(pDevice);
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[DirectSound] IDirectSound_CreateSoundBuffer() failed for playback device's secondary buffer.", ma_result_from_HRESULT(hr));
        }

        /* DirectSound should give us a buffer exactly the size we asked for. */
        pDevice->playback.internalPeriodSizeInFrames = periodSizeInFrames;
        pDevice->playback.internalPeriods            = pConfig->periods;
    }

    (void)pContext;
    return MA_SUCCESS;
}


static ma_result ma_device_main_loop__dsound(ma_device* pDevice)
{
    ma_result result = MA_SUCCESS;
    ma_uint32 bpfDeviceCapture  = ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
    ma_uint32 bpfDevicePlayback = ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    HRESULT hr;
    DWORD lockOffsetInBytesCapture;
    DWORD lockSizeInBytesCapture;
    DWORD mappedSizeInBytesCapture;
    DWORD mappedDeviceFramesProcessedCapture;
    void* pMappedDeviceBufferCapture;
    DWORD lockOffsetInBytesPlayback;
    DWORD lockSizeInBytesPlayback;
    DWORD mappedSizeInBytesPlayback;
    void* pMappedDeviceBufferPlayback;
    DWORD prevReadCursorInBytesCapture = 0;
    DWORD prevPlayCursorInBytesPlayback = 0;
    ma_bool32 physicalPlayCursorLoopFlagPlayback = 0;
    DWORD virtualWriteCursorInBytesPlayback = 0;
    ma_bool32 virtualWriteCursorLoopFlagPlayback = 0;
    ma_bool32 isPlaybackDeviceStarted = MA_FALSE;
    ma_uint32 framesWrittenToPlaybackDevice = 0;   /* For knowing whether or not the playback device needs to be started. */
    ma_uint32 waitTimeInMilliseconds = 1;

    MA_ASSERT(pDevice != NULL);

    /* The first thing to do is start the capture device. The playback device is only started after the first period is written. */
    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        if (FAILED(ma_IDirectSoundCaptureBuffer_Start((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, MA_DSCBSTART_LOOPING))) {
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundCaptureBuffer_Start() failed.", MA_FAILED_TO_START_BACKEND_DEVICE);
        }
    }

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

                }

                /* If nothing is available we just sleep for a bit and return from this iteration. */
                if (physicalReadCursorInBytes == prevReadCursorInBytesCapture) {
                    ma_sleep(waitTimeInMilliseconds);
                    continue; /* Nothing is available in the capture buffer. */
                }

                /*
                The current position has moved. We need to map all of the captured samples and write them to the playback device, making sure
                we don't return until every frame has been copied over.
                */
                if (prevReadCursorInBytesCapture < physicalReadCursorInBytes) {
                    /* The capture position has not looped. This is the simple case. */
                    lockOffsetInBytesCapture = prevReadCursorInBytesCapture;
                    lockSizeInBytesCapture   = (physicalReadCursorInBytes - prevReadCursorInBytesCapture);
                } else {
                    /*
                    The capture position has looped. This is the more complex case. Map to the end of the buffer. If this does not return anything,
                    do it again from the start.
                    */

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

                    ma_sleep(waitTimeInMilliseconds);
                    continue; /* Nothing is available in the capture buffer. */
                }

                hr = ma_IDirectSoundCaptureBuffer_Lock((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, lockOffsetInBytesCapture, lockSizeInBytesCapture, &pMappedDeviceBufferCapture, &mappedSizeInBytesCapture, NULL, NULL, 0);
                if (FAILED(hr)) {
                    return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to map buffer from capture device in preparation for writing to the device.", ma_result_from_HRESULT(hr));
                }


                /* At this point we have some input data that we need to output. We do not return until every mapped frame of the input data is written to the playback device. */
                mappedDeviceFramesProcessedCapture = 0;

                for (;;) {  /* Keep writing to the playback device. */
                    ma_uint8  inputFramesInClientFormat[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint32 inputFramesInClientFormatCap = sizeof(inputFramesInClientFormat) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
                    ma_uint8  outputFramesInClientFormat[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint32 outputFramesInClientFormatCap = sizeof(outputFramesInClientFormat) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
                    ma_uint32 outputFramesInClientFormatCount;
                    ma_uint32 outputFramesInClientFormatConsumed = 0;
                    ma_uint64 clientCapturedFramesToProcess = ma_min(inputFramesInClientFormatCap, outputFramesInClientFormatCap);
                    ma_uint64 deviceCapturedFramesToProcess = (mappedSizeInBytesCapture / bpfDeviceCapture) - mappedDeviceFramesProcessedCapture;
                    void* pRunningMappedDeviceBufferCapture = ma_offset_ptr(pMappedDeviceBufferCapture, mappedDeviceFramesProcessedCapture * bpfDeviceCapture);

                    result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningMappedDeviceBufferCapture, &deviceCapturedFramesToProcess, inputFramesInClientFormat, &clientCapturedFramesToProcess);
                    if (result != MA_SUCCESS) {
                        break;
                    }

                    outputFramesInClientFormatCount     = (ma_uint32)clientCapturedFramesToProcess;
                    mappedDeviceFramesProcessedCapture += (ma_uint32)deviceCapturedFramesToProcess;

                    ma_device__on_data(pDevice, outputFramesInClientFormat, inputFramesInClientFormat, (ma_uint32)clientCapturedFramesToProcess);

                    /* At this point we have input and output data in client format. All we need to do now is convert it to the output device format. This may take a few passes. */
                    for (;;) {
                        ma_uint32 framesWrittenThisIteration;
                        DWORD physicalPlayCursorInBytes;
                        DWORD physicalWriteCursorInBytes;
                        DWORD availableBytesPlayback;
                        DWORD silentPaddingInBytes = 0; /* <-- Must be initialized to 0. */

                        /* We need the physical play and write cursors. */
                        if (FAILED(ma_IDirectSoundBuffer_GetCurrentPosition((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, &physicalPlayCursorInBytes, &physicalWriteCursorInBytes))) {
                            break;
                        }

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


                        #ifdef MA_DEBUG_OUTPUT
                                printf("[DirectSound] (Duplex/Playback) Playback buffer starved. availableBytesPlayback=%ld, silentPaddingInBytes=%ld\n", availableBytesPlayback, silentPaddingInBytes);
                        #endif
                            }
                        }

                        /* At this point we have a buffer for output. */
                        if (silentPaddingInBytes > 0) {
                            MA_ZERO_MEMORY(pMappedDeviceBufferPlayback, silentPaddingInBytes);
                            framesWrittenThisIteration = silentPaddingInBytes/bpfDevicePlayback;
                        } else {
                            ma_uint64 convertedFrameCountIn  = (outputFramesInClientFormatCount - outputFramesInClientFormatConsumed);
                            ma_uint64 convertedFrameCountOut = mappedSizeInBytesPlayback/bpfDevicePlayback;
                            void* pConvertedFramesIn  = ma_offset_ptr(outputFramesInClientFormat, outputFramesInClientFormatConsumed * bpfDevicePlayback);
                            void* pConvertedFramesOut = pMappedDeviceBufferPlayback;

                            result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, pConvertedFramesIn, &convertedFrameCountIn, pConvertedFramesOut, &convertedFrameCountOut);
                            if (result != MA_SUCCESS) {
                                break;
                            }

                            outputFramesInClientFormatConsumed += (ma_uint32)convertedFrameCountOut;
                            framesWrittenThisIteration          = (ma_uint32)convertedFrameCountOut;
                        }
                        

                        hr = ma_IDirectSoundBuffer_Unlock((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, pMappedDeviceBufferPlayback, framesWrittenThisIteration*bpfDevicePlayback, NULL, 0);
                        if (FAILED(hr)) {
                            result = ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to unlock internal buffer from playback device after writing to the device.", ma_result_from_HRESULT(hr));
                            break;
                        }

                        virtualWriteCursorInBytesPlayback += framesWrittenThisIteration*bpfDevicePlayback;
                        if ((virtualWriteCursorInBytesPlayback/bpfDevicePlayback) == pDevice->playback.internalPeriodSizeInFrames*pDevice->playback.internalPeriods) {
                            virtualWriteCursorInBytesPlayback  = 0;
                            virtualWriteCursorLoopFlagPlayback = !virtualWriteCursorLoopFlagPlayback;
                        }
                        
                        /*
                        We may need to start the device. We want two full periods to be written before starting the playback device. Having an extra period adds
                        a bit of a buffer to prevent the playback buffer from getting starved.
                        */
                        framesWrittenToPlaybackDevice += framesWrittenThisIteration;
                        if (!isPlaybackDeviceStarted && framesWrittenToPlaybackDevice >= (pDevice->playback.internalPeriodSizeInFrames*2)) {
                            hr = ma_IDirectSoundBuffer_Play((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, 0, 0, MA_DSBPLAY_LOOPING);
                            if (FAILED(hr)) {
                                ma_IDirectSoundCaptureBuffer_Stop((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer);
                                return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundBuffer_Play() failed.", ma_result_from_HRESULT(hr));
                            }
                            isPlaybackDeviceStarted = MA_TRUE;
                        }

                        if (framesWrittenThisIteration < mappedSizeInBytesPlayback/bpfDevicePlayback) {
                            break;  /* We're finished with the output data.*/
                        }
                    }

                    if (clientCapturedFramesToProcess == 0) {
                        break;  /* We just consumed every input sample. */
                    }
                }


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

                if (FAILED(hr)) {
                    return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to map buffer from capture device in preparation for writing to the device.", ma_result_from_HRESULT(hr));
                }

            #ifdef MA_DEBUG_OUTPUT
                if (lockSizeInBytesCapture != mappedSizeInBytesCapture) {
                    printf("[DirectSound] (Capture) lockSizeInBytesCapture=%ld != mappedSizeInBytesCapture=%ld\n", lockSizeInBytesCapture, mappedSizeInBytesCapture);
                }
            #endif

                ma_device__send_frames_to_client(pDevice, mappedSizeInBytesCapture/bpfDeviceCapture, pMappedDeviceBufferCapture);

                hr = ma_IDirectSoundCaptureBuffer_Unlock((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, pMappedDeviceBufferCapture, mappedSizeInBytesCapture, NULL, 0);
                if (FAILED(hr)) {
                    return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to unlock internal buffer from capture device after reading from the device.", ma_result_from_HRESULT(hr));
                }
                prevReadCursorInBytesCapture = lockOffsetInBytesCapture + mappedSizeInBytesCapture;

                if (prevReadCursorInBytesCapture == (pDevice->capture.internalPeriodSizeInFrames*pDevice->capture.internalPeriods*bpfDeviceCapture)) {
                    prevReadCursorInBytesCapture = 0;
                }

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

                    lockSizeInBytesPlayback = physicalPlayCursorInBytes - virtualWriteCursorInBytesPlayback;
                }

                hr = ma_IDirectSoundBuffer_Lock((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, lockOffsetInBytesPlayback, lockSizeInBytesPlayback, &pMappedDeviceBufferPlayback, &mappedSizeInBytesPlayback, NULL, NULL, 0);
                if (FAILED(hr)) {
                    result = ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to map buffer from playback device in preparation for writing to the device.", ma_result_from_HRESULT(hr));
                    break;
                }

                /* At this point we have a buffer for output. */
                ma_device__read_frames_from_client(pDevice, (mappedSizeInBytesPlayback/bpfDevicePlayback), pMappedDeviceBufferPlayback);

                hr = ma_IDirectSoundBuffer_Unlock((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, pMappedDeviceBufferPlayback, mappedSizeInBytesPlayback, NULL, 0);
                if (FAILED(hr)) {
                    result = ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to unlock internal buffer from playback device after writing to the device.", ma_result_from_HRESULT(hr));
                    break;
                }

                virtualWriteCursorInBytesPlayback += mappedSizeInBytesPlayback;
                if (virtualWriteCursorInBytesPlayback == pDevice->playback.internalPeriodSizeInFrames*pDevice->playback.internalPeriods*bpfDevicePlayback) {
                    virtualWriteCursorInBytesPlayback  = 0;
                    virtualWriteCursorLoopFlagPlayback = !virtualWriteCursorLoopFlagPlayback;
                }
                        
                /*
                We may need to start the device. We want two full periods to be written before starting the playback device. Having an extra period adds
                a bit of a buffer to prevent the playback buffer from getting starved.
                */
                framesWrittenToPlaybackDevice += mappedSizeInBytesPlayback/bpfDevicePlayback;
                if (!isPlaybackDeviceStarted && framesWrittenToPlaybackDevice >= pDevice->playback.internalPeriodSizeInFrames) {
                    hr = ma_IDirectSoundBuffer_Play((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, 0, 0, MA_DSBPLAY_LOOPING);
                    if (FAILED(hr)) {
                        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundBuffer_Play() failed.", ma_result_from_HRESULT(hr));
                    }
                    isPlaybackDeviceStarted = MA_TRUE;
                }
            } break;


            default: return MA_INVALID_ARGS;   /* Invalid device type. */

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

        }

        str += 1;
    }

    return last;
}

static ma_uint32 ma_get_period_size_in_bytes(ma_uint32 periodSizeInFrames, ma_format format, ma_uint32 channels)
{
    return periodSizeInFrames * ma_get_bytes_per_frame(format, channels);
}


/*
Our own "WAVECAPS" structure that contains generic information shared between WAVEOUTCAPS2 and WAVEINCAPS2 so
we can do things generically and typesafely. Names are being kept the same for consistency.
*/
typedef struct
{
    CHAR szPname[MAXPNAMELEN];

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

    }

    /* No exlusive mode with WinMM. */
    if (((pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) && pConfig->playback.shareMode == ma_share_mode_exclusive) ||
        ((pConfig->deviceType == ma_device_type_capture  || pConfig->deviceType == ma_device_type_duplex) && pConfig->capture.shareMode  == ma_share_mode_exclusive)) {
        return MA_SHARE_MODE_NOT_SUPPORTED;
    }

    periodSizeInMilliseconds = pConfig->periodSizeInMilliseconds;
    if (periodSizeInMilliseconds == 0) {
        periodSizeInMilliseconds = ma_calculate_buffer_size_in_milliseconds_from_frames(pConfig->periodSizeInFrames, pConfig->sampleRate);
    }
    
    /* WinMM has horrible latency. */
    if (pDevice->usingDefaultBufferSize) {
        if (pConfig->performanceProfile == ma_performance_profile_low_latency) {
            periodSizeInMilliseconds =  40;
        } else {
            periodSizeInMilliseconds = 400;
        }
    }

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

        if (resultMM != MMSYSERR_NOERROR) {
            errorMsg = "[WinMM] Failed to open capture device.", errorCode = MA_FAILED_TO_OPEN_BACKEND_DEVICE;
            goto on_error;
        }

        pDevice->capture.internalFormat             = ma_format_from_WAVEFORMATEX(&wf);
        pDevice->capture.internalChannels           = wf.nChannels;
        pDevice->capture.internalSampleRate         = wf.nSamplesPerSec;
        ma_get_standard_channel_map(ma_standard_channel_map_microsoft, pDevice->capture.internalChannels, pDevice->capture.internalChannelMap);
        pDevice->capture.internalPeriods            = pConfig->periods;
        pDevice->capture.internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(periodSizeInMilliseconds, pDevice->capture.internalSampleRate);
    }

    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        WAVEOUTCAPSA caps;
        WAVEFORMATEX wf;
        MMRESULT resultMM;

        /* We use an event to know when a new fragment needs to be enqueued. */
        pDevice->winmm.hEventPlayback = (ma_handle)CreateEvent(NULL, TRUE, TRUE, NULL);
        if (pDevice->winmm.hEventPlayback == NULL) {

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

        if (resultMM != MMSYSERR_NOERROR) {
            errorMsg = "[WinMM] Failed to open playback device.", errorCode = MA_FAILED_TO_OPEN_BACKEND_DEVICE;
            goto on_error;
        }

        pDevice->playback.internalFormat             = ma_format_from_WAVEFORMATEX(&wf);
        pDevice->playback.internalChannels           = wf.nChannels;
        pDevice->playback.internalSampleRate         = wf.nSamplesPerSec;
        ma_get_standard_channel_map(ma_standard_channel_map_microsoft, pDevice->playback.internalChannels, pDevice->playback.internalChannelMap);
        pDevice->playback.internalPeriods            = pConfig->periods;
        pDevice->playback.internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(periodSizeInMilliseconds, pDevice->playback.internalSampleRate);
    }

    /*
    The heap allocated data is allocated like so:
    
    [Capture WAVEHDRs][Playback WAVEHDRs][Capture Intermediary Buffer][Playback Intermediary Buffer]
    */
    heapSize = 0;
    if (pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) {
        heapSize += sizeof(WAVEHDR)*pDevice->capture.internalPeriods + (pDevice->capture.internalPeriodSizeInFrames*pDevice->capture.internalPeriods*ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));
    }
    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        heapSize += sizeof(WAVEHDR)*pDevice->playback.internalPeriods + (pDevice->playback.internalPeriodSizeInFrames*pDevice->playback.internalPeriods*ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
    }

    pDevice->winmm._pHeapData = (ma_uint8*)ma__calloc_from_callbacks(heapSize, &pContext->allocationCallbacks);
    if (pDevice->winmm._pHeapData == NULL) {
        errorMsg = "[WinMM] Failed to allocate memory for the intermediary buffer.", errorCode = MA_OUT_OF_MEMORY;
        goto on_error;
    }

    MA_ZERO_MEMORY(pDevice->winmm._pHeapData, heapSize);

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

        }
    }
    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);
        } else {
            pDevice->winmm.pWAVEHDRPlayback            = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDevice->capture.internalPeriods));
            pDevice->winmm.pIntermediaryBufferPlayback = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDevice->capture.internalPeriods + pDevice->playback.internalPeriods)) + (pDevice->capture.internalPeriodSizeInFrames*pDevice->capture.internalPeri...
        }

        /* Prepare headers. */
        for (iPeriod = 0; iPeriod < pDevice->playback.internalPeriods; ++iPeriod) {
            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;

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


        resultMM = ((MA_PFN_waveOutReset)pDevice->pContext->winmm.waveOutReset)((HWAVEOUT)pDevice->winmm.hDevicePlayback);
        if (resultMM != MMSYSERR_NOERROR) {
            ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WinMM] WARNING: Failed to reset playback device.", ma_result_from_MMRESULT(resultMM));
        }
    }

    return MA_SUCCESS;
}

static ma_result ma_device_write__winmm(ma_device* pDevice, const void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    ma_result result = MA_SUCCESS;
    MMRESULT resultMM;
    ma_uint32 totalFramesWritten;
    WAVEHDR* pWAVEHDR;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pPCMFrames != NULL);

    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. */

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

                    ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WinMM] waveOutWrite() failed.", result);
                    break;
                }

                /* Make sure we move to the next header. */
                pDevice->winmm.iNextHeaderPlayback = (pDevice->winmm.iNextHeaderPlayback + 1) % pDevice->playback.internalPeriods;
                pDevice->winmm.headerFramesConsumedPlayback = 0;
            }

            /* If at this point we have consumed the entire input buffer we can return. */
            MA_ASSERT(totalFramesWritten <= frameCount);
            if (totalFramesWritten == frameCount) {
                break;
            }

            /* Getting here means there's more to process. */
            continue;
        }

        /* 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;

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

        }
    }

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

    return result;
}

static ma_result ma_device_read__winmm(ma_device* pDevice, void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    ma_result result = MA_SUCCESS;
    MMRESULT resultMM;
    ma_uint32 totalFramesRead;
    WAVEHDR* pWAVEHDR;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pPCMFrames != NULL);

    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. */

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

                    ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WinMM] waveInAddBuffer() failed.", result);
                    break;
                }

                /* Make sure we move to the next header. */
                pDevice->winmm.iNextHeaderCapture = (pDevice->winmm.iNextHeaderCapture + 1) % pDevice->capture.internalPeriods;
                pDevice->winmm.headerFramesConsumedCapture = 0;
            }

            /* If at this point we have filled the entire input buffer we can return. */
            MA_ASSERT(totalFramesRead <= frameCount);
            if (totalFramesRead == frameCount) {
                break;
            }

            /* Getting here means there's more to process. */
            continue;
        }

        /* 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;

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


    return result;
}

static ma_result ma_device_main_loop__winmm(ma_device* pDevice)
{
    ma_result result = MA_SUCCESS;
    ma_bool32 exitLoop = MA_FALSE;
    ma_uint8  capturedDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
    ma_uint8  playbackDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
    ma_uint32 capturedDeviceDataCapInFrames = sizeof(capturedDeviceData) / ma_get_bytes_per_frame(pDevice->capture.internalFormat,  pDevice->capture.internalChannels);
    ma_uint32 playbackDeviceDataCapInFrames = sizeof(playbackDeviceData) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    
    MA_ASSERT(pDevice != NULL);

    /* The capture device needs to be started immediately. */
    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        MMRESULT resultMM;
        WAVEHDR* pWAVEHDR;
        ma_uint32 iPeriod;

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

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

                        exitLoop = MA_TRUE;
                        break;
                    }

                    capturedDeviceFramesRemaining = capturedDeviceFramesToProcess;
                    capturedDeviceFramesProcessed = 0;

                    for (;;) {
                        ma_uint8  capturedClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint8  playbackClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint32 capturedClientDataCapInFrames = sizeof(capturedClientData) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
                        ma_uint32 playbackClientDataCapInFrames = sizeof(playbackClientData) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
                        ma_uint64 capturedClientFramesToProcessThisIteration = ma_min(capturedClientDataCapInFrames, playbackClientDataCapInFrames);
                        ma_uint64 capturedDeviceFramesToProcessThisIteration = capturedDeviceFramesRemaining;
                        ma_uint8* pRunningCapturedDeviceFrames = ma_offset_ptr(capturedDeviceData, capturedDeviceFramesProcessed * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));

                        /* Convert capture data from device format to client format. */
                        result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningCapturedDeviceFrames, &capturedDeviceFramesToProcessThisIteration, capturedClientData, &capturedClientFramesToProcessThisIteration);
                        if (result != MA_SUCCESS) {
                            break;
                        }

                        /*
                        If we weren't able to generate any output frames it must mean we've exhaused all of our input. The only time this would not be the case is if capturedClientData was too small
                        which should never be the case when it's of the size MA_DATA_CONVERTER_STACK_BUFFER_SIZE.
                        */
                        if (capturedClientFramesToProcessThisIteration == 0) {
                            break;
                        }

                        ma_device__on_data(pDevice, playbackClientData, capturedClientData, (ma_uint32)capturedClientFramesToProcessThisIteration);    /* Safe cast .*/

                        capturedDeviceFramesProcessed += (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */
                        capturedDeviceFramesRemaining -= (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */

                        /* At this point the playbackClientData buffer should be holding data that needs to be written to the device. */
                        for (;;) {
                            ma_uint64 convertedClientFrameCount = capturedClientFramesToProcessThisIteration;
                            ma_uint64 convertedDeviceFrameCount = playbackDeviceDataCapInFrames;
                            result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, playbackClientData, &convertedClientFrameCount, playbackDeviceData, &convertedDeviceFrameCount);
                            if (result != MA_SUCCESS) {
                                break;
                            }

                            result = ma_device_write__winmm(pDevice, playbackDeviceData, (ma_uint32)convertedDeviceFrameCount, NULL);  /* Safe cast. */
                            if (result != MA_SUCCESS) {
                                exitLoop = MA_TRUE;
                                break;
                            }

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

                    }

                    totalCapturedDeviceFramesProcessed += capturedDeviceFramesProcessed;
                }
            } break;

            case ma_device_type_capture:
            {
                /* We read in chunks of the period size, but use a stack allocated buffer for the intermediary. */
                ma_uint32 periodSizeInFrames = pDevice->capture.internalPeriodSizeInFrames;
                ma_uint32 framesReadThisPeriod = 0;
                while (framesReadThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesReadThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToReadThisIteration = framesRemainingInPeriod;
                    if (framesToReadThisIteration > capturedDeviceDataCapInFrames) {
                        framesToReadThisIteration = capturedDeviceDataCapInFrames;
                    }

                    result = ma_device_read__winmm(pDevice, capturedDeviceData, framesToReadThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    ma_device__send_frames_to_client(pDevice, framesProcessed, capturedDeviceData);

                    framesReadThisPeriod += framesProcessed;
                }
            } break;

            case ma_device_type_playback:
            {
                /* We write in chunks of the period size, but use a stack allocated buffer for the intermediary. */
                ma_uint32 periodSizeInFrames = pDevice->playback.internalPeriodSizeInFrames;
                ma_uint32 framesWrittenThisPeriod = 0;
                while (framesWrittenThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesWrittenThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToWriteThisIteration = framesRemainingInPeriod;
                    if (framesToWriteThisIteration > playbackDeviceDataCapInFrames) {
                        framesToWriteThisIteration = playbackDeviceDataCapInFrames;
                    }

                    ma_device__read_frames_from_client(pDevice, framesToWriteThisIteration, playbackDeviceData);

                    result = ma_device_write__winmm(pDevice, playbackDeviceData, framesToWriteThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    framesWrittenThisPeriod += framesProcessed;
                }
            } break;

            /* To silence a warning. Will never hit this. */
            case ma_device_type_loopback:
            default: break;
        }
    }


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

            #define MA_INLINE_DEFINED
        #endif
    #endif
#endif
#include <alsa/asoundlib.h>
#if defined(MA_INLINE_DEFINED)
    #undef inline
    #undef MA_INLINE_DEFINED
#endif

typedef snd_pcm_uframes_t                       ma_snd_pcm_uframes_t;
typedef snd_pcm_sframes_t                       ma_snd_pcm_sframes_t;
typedef snd_pcm_stream_t                        ma_snd_pcm_stream_t;
typedef snd_pcm_format_t                        ma_snd_pcm_format_t;
typedef snd_pcm_access_t                        ma_snd_pcm_access_t;
typedef snd_pcm_t                               ma_snd_pcm_t;
typedef snd_pcm_hw_params_t                     ma_snd_pcm_hw_params_t;
typedef snd_pcm_sw_params_t                     ma_snd_pcm_sw_params_t;
typedef snd_pcm_format_mask_t                   ma_snd_pcm_format_mask_t;
typedef snd_pcm_info_t                          ma_snd_pcm_info_t;
typedef snd_pcm_channel_area_t                  ma_snd_pcm_channel_area_t;
typedef snd_pcm_chmap_t                         ma_snd_pcm_chmap_t;

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

#define MA_SND_CHMAP_BC                         SND_CHMAP_BC
#define MA_SND_CHMAP_BLC                        SND_CHMAP_BLC
#define MA_SND_CHMAP_BRC                        SND_CHMAP_BRC

/* Open mode flags. */
#define MA_SND_PCM_NO_AUTO_RESAMPLE             SND_PCM_NO_AUTO_RESAMPLE
#define MA_SND_PCM_NO_AUTO_CHANNELS             SND_PCM_NO_AUTO_CHANNELS
#define MA_SND_PCM_NO_AUTO_FORMAT               SND_PCM_NO_AUTO_FORMAT
#else
#include <errno.h>  /* For EPIPE, etc. */
typedef unsigned long                           ma_snd_pcm_uframes_t;
typedef long                                    ma_snd_pcm_sframes_t;
typedef int                                     ma_snd_pcm_stream_t;
typedef int                                     ma_snd_pcm_format_t;
typedef int                                     ma_snd_pcm_access_t;
typedef int                                     ma_snd_pcm_state_t;
typedef struct ma_snd_pcm_t                     ma_snd_pcm_t;
typedef struct ma_snd_pcm_hw_params_t           ma_snd_pcm_hw_params_t;
typedef struct ma_snd_pcm_sw_params_t           ma_snd_pcm_sw_params_t;
typedef struct ma_snd_pcm_format_mask_t         ma_snd_pcm_format_mask_t;
typedef struct ma_snd_pcm_info_t                ma_snd_pcm_info_t;
typedef struct

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

typedef int                  (* ma_snd_pcm_open_proc)                          (ma_snd_pcm_t **pcm, const char *name, ma_snd_pcm_stream_t stream, int mode);
typedef int                  (* ma_snd_pcm_close_proc)                         (ma_snd_pcm_t *pcm);
typedef size_t               (* ma_snd_pcm_hw_params_sizeof_proc)              (void);
typedef int                  (* ma_snd_pcm_hw_params_any_proc)                 (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params);
typedef int                  (* ma_snd_pcm_hw_params_set_format_proc)          (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, ma_snd_pcm_format_t val);
typedef int                  (* ma_snd_pcm_hw_params_set_format_first_proc)    (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, ma_snd_pcm_format_t *format);
typedef void                 (* ma_snd_pcm_hw_params_get_format_mask_proc)     (ma_snd_pcm_hw_params_t *params, ma_snd_pcm_format_mask_t *mask);
typedef int                  (* ma_snd_pcm_hw_params_set_channels_near_proc)   (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int *val);
typedef int                  (* ma_snd_pcm_hw_params_set_rate_resample_proc)   (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int val);
typedef int                  (* ma_snd_pcm_hw_params_set_rate_near_proc)       (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
typedef int                  (* ma_snd_pcm_hw_params_set_buffer_size_near_proc)(ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, ma_snd_pcm_uframes_t *val);
typedef int                  (* ma_snd_pcm_hw_params_set_periods_near_proc)    (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
typedef int                  (* ma_snd_pcm_hw_params_set_access_proc)          (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, ma_snd_pcm_access_t _access);
typedef int                  (* ma_snd_pcm_hw_params_get_format_proc)          (const ma_snd_pcm_hw_params_t *params, ma_snd_pcm_format_t *format);
typedef int                  (* ma_snd_pcm_hw_params_get_channels_proc)        (const ma_snd_pcm_hw_params_t *params, unsigned int *val);
typedef int                  (* ma_snd_pcm_hw_params_get_channels_min_proc)    (const ma_snd_pcm_hw_params_t *params, unsigned int *val);
typedef int                  (* ma_snd_pcm_hw_params_get_channels_max_proc)    (const ma_snd_pcm_hw_params_t *params, unsigned int *val);
typedef int                  (* ma_snd_pcm_hw_params_get_rate_proc)            (const ma_snd_pcm_hw_params_t *params, unsigned int *rate, int *dir);
typedef int                  (* ma_snd_pcm_hw_params_get_rate_min_proc)        (const ma_snd_pcm_hw_params_t *params, unsigned int *rate, int *dir);
typedef int                  (* ma_snd_pcm_hw_params_get_rate_max_proc)        (const ma_snd_pcm_hw_params_t *params, unsigned int *rate, int *dir);
typedef int                  (* ma_snd_pcm_hw_params_get_buffer_size_proc)     (const ma_snd_pcm_hw_params_t *params, ma_snd_pcm_uframes_t *val);
typedef int                  (* ma_snd_pcm_hw_params_get_periods_proc)         (const ma_snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
typedef int                  (* ma_snd_pcm_hw_params_get_access_proc)          (const ma_snd_pcm_hw_params_t *params, ma_snd_pcm_access_t *_access);
typedef int                  (* ma_snd_pcm_hw_params_proc)                     (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params);
typedef size_t               (* ma_snd_pcm_sw_params_sizeof_proc)              (void);
typedef int                  (* ma_snd_pcm_sw_params_current_proc)             (ma_snd_pcm_t *pcm, ma_snd_pcm_sw_params_t *params);
typedef int                  (* ma_snd_pcm_sw_params_get_boundary_proc)        (const ma_snd_pcm_sw_params_t *params, ma_snd_pcm_uframes_t* val);
typedef int                  (* ma_snd_pcm_sw_params_set_avail_min_proc)       (ma_snd_pcm_t *pcm, ma_snd_pcm_sw_params_t *params, ma_snd_pcm_uframes_t val);
typedef int                  (* ma_snd_pcm_sw_params_set_start_threshold_proc) (ma_snd_pcm_t *pcm, ma_snd_pcm_sw_params_t *params, ma_snd_pcm_uframes_t val);
typedef int                  (* ma_snd_pcm_sw_params_set_stop_threshold_proc)  (ma_snd_pcm_t *pcm, ma_snd_pcm_sw_params_t *params, ma_snd_pcm_uframes_t val);
typedef int                  (* ma_snd_pcm_sw_params_proc)                     (ma_snd_pcm_t *pcm, ma_snd_pcm_sw_params_t *params);
typedef size_t               (* ma_snd_pcm_format_mask_sizeof_proc)            (void);
typedef int                  (* ma_snd_pcm_format_mask_test_proc)              (const ma_snd_pcm_format_mask_t *mask, ma_snd_pcm_format_t val);
typedef ma_snd_pcm_chmap_t * (* ma_snd_pcm_get_chmap_proc)                     (ma_snd_pcm_t *pcm);
typedef ma_snd_pcm_state_t   (* ma_snd_pcm_state_proc)                         (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_pcm_prepare_proc)                       (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_pcm_start_proc)                         (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_pcm_drop_proc)                          (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_pcm_drain_proc)                         (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_device_name_hint_proc)                  (int card, const char *iface, void ***hints);
typedef char *               (* ma_snd_device_name_get_hint_proc)              (const void *hint, const char *id);
typedef int                  (* ma_snd_card_get_index_proc)                    (const char *name);
typedef int                  (* ma_snd_device_name_free_hint_proc)             (void **hints);
typedef int                  (* ma_snd_pcm_mmap_begin_proc)                    (ma_snd_pcm_t *pcm, const ma_snd_pcm_channel_area_t **areas, ma_snd_pcm_uframes_t *offset, ma_snd_pcm_uframes_t *frames);
typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_mmap_commit_proc)                   (ma_snd_pcm_t *pcm, ma_snd_pcm_uframes_t offset, ma_snd_pcm_uframes_t frames);
typedef int                  (* ma_snd_pcm_recover_proc)                       (ma_snd_pcm_t *pcm, int err, int silent);
typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_readi_proc)                         (ma_snd_pcm_t *pcm, void *buffer, ma_snd_pcm_uframes_t size);
typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_writei_proc)                        (ma_snd_pcm_t *pcm, const void *buffer, ma_snd_pcm_uframes_t size);
typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_avail_proc)                         (ma_snd_pcm_t *pcm);
typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_avail_update_proc)                  (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_pcm_wait_proc)                          (ma_snd_pcm_t *pcm, int timeout);
typedef int                  (* ma_snd_pcm_info_proc)                          (ma_snd_pcm_t *pcm, ma_snd_pcm_info_t* info);
typedef size_t               (* ma_snd_pcm_info_sizeof_proc)                   (void);
typedef const char*          (* ma_snd_pcm_info_get_name_proc)                 (const ma_snd_pcm_info_t* info);
typedef int                  (* ma_snd_config_update_free_global_proc)         (void);

/* This array specifies each of the common devices that can be used for both playback and capture. */
static const char* g_maCommonDeviceNamesALSA[] = {
    "default",
    "null",

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

    ma__free_from_callbacks(pFormatMask, &pContext->allocationCallbacks);
    ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);

    ((ma_snd_pcm_close_proc)pContext->alsa.snd_pcm_close)(pPCM);
    return MA_SUCCESS;
}


#if 0
/*
Waits for a number of frames to become available for either capture or playback. The return
value is the number of frames available.

This will return early if the main loop is broken with ma_device__break_main_loop().
*/
static ma_uint32 ma_device__wait_for_frames__alsa(ma_device* pDevice, ma_bool32* pRequiresRestart)
{
    MA_ASSERT(pDevice != NULL);

    if (pRequiresRestart) *pRequiresRestart = MA_FALSE;

    /* I want it so that this function returns the period size in frames. We just wait until that number of frames are available and then return. */
    ma_uint32 periodSizeInFrames = pDevice->bufferSizeInFrames / pDevice->periods;
    while (!pDevice->alsa.breakFromMainLoop) {
        ma_snd_pcm_sframes_t framesAvailable = ((ma_snd_pcm_avail_update_proc)pDevice->pContext->alsa.snd_pcm_avail_update)((ma_snd_pcm_t*)pDevice->alsa.pPCM);
        if (framesAvailable < 0) {
            if (framesAvailable == -EPIPE) {
                if (((ma_snd_pcm_recover_proc)pDevice->pContext->alsa.snd_pcm_recover)((ma_snd_pcm_t*)pDevice->alsa.pPCM, framesAvailable, MA_TRUE) < 0) {
                    return 0;
                }

                /* A device recovery means a restart for mmap mode. */
                if (pRequiresRestart) {
                    *pRequiresRestart = MA_TRUE;
                }

                /* Try again, but if it fails this time just return an error. */
                framesAvailable = ((ma_snd_pcm_avail_update_proc)pDevice->pContext->alsa.snd_pcm_avail_update)((ma_snd_pcm_t*)pDevice->alsa.pPCM);
                if (framesAvailable < 0) {
                    return 0;
                }
            }
        }

        if (framesAvailable >= periodSizeInFrames) {
            return periodSizeInFrames;
        }

        if (framesAvailable < periodSizeInFrames) {
            /* Less than a whole period is available so keep waiting. */
            int waitResult = ((ma_snd_pcm_wait_proc)pDevice->pContext->alsa.snd_pcm_wait)((ma_snd_pcm_t*)pDevice->alsa.pPCM, -1);
            if (waitResult < 0) {
                if (waitResult == -EPIPE) {
                    if (((ma_snd_pcm_recover_proc)pDevice->pContext->alsa.snd_pcm_recover)((ma_snd_pcm_t*)pDevice->alsa.pPCM, waitResult, MA_TRUE) < 0) {
                        return 0;
                    }

                    /* A device recovery means a restart for mmap mode. */
                    if (pRequiresRestart) {
                        *pRequiresRestart = MA_TRUE;
                    }
                }
            }
        }
    }

    /* We'll get here if the loop was terminated. Just return whatever's available. */
    ma_snd_pcm_sframes_t framesAvailable = ((ma_snd_pcm_avail_update_proc)pDevice->pContext->alsa.snd_pcm_avail_update)((ma_snd_pcm_t*)pDevice->alsa.pPCM);
    if (framesAvailable < 0) {
        return 0;
    }

    return framesAvailable;
}

static ma_bool32 ma_device_read_from_client_and_write__alsa(ma_device* pDevice)
{
    MA_ASSERT(pDevice != NULL);
    if (!ma_device_is_started(pDevice) && ma_device__get_state(pDevice) != MA_STATE_STARTING) {
        return MA_FALSE;
    }
    if (pDevice->alsa.breakFromMainLoop) {
        return MA_FALSE;
    }

    if (pDevice->alsa.isUsingMMap) {
        /* mmap. */
        ma_bool32 requiresRestart;
        ma_uint32 framesAvailable = ma_device__wait_for_frames__alsa(pDevice, &requiresRestart);
        if (framesAvailable == 0) {
            return MA_FALSE;
        }

        /* Don't bother asking the client for more audio data if we're just stopping the device anyway. */
        if (pDevice->alsa.breakFromMainLoop) {
            return MA_FALSE;
        }

        const ma_snd_pcm_channel_area_t* pAreas;
        ma_snd_pcm_uframes_t mappedOffset;
        ma_snd_pcm_uframes_t mappedFrames = framesAvailable;
        while (framesAvailable > 0) {
            int result = ((ma_snd_pcm_mmap_begin_proc)pDevice->pContext->alsa.snd_pcm_mmap_begin)((ma_snd_pcm_t*)pDevice->alsa.pPCM, &pAreas, &mappedOffset, &mappedFrames);
            if (result < 0) {
                return MA_FALSE;
            }

            if (mappedFrames > 0) {
                void* pBuffer = (ma_uint8*)pAreas[0].addr + ((pAreas[0].first + (mappedOffset * pAreas[0].step)) / 8);
                ma_device__read_frames_from_client(pDevice, mappedFrames, pBuffer);
            }

            result = ((ma_snd_pcm_mmap_commit_proc)pDevice->pContext->alsa.snd_pcm_mmap_commit)((ma_snd_pcm_t*)pDevice->alsa.pPCM, mappedOffset, mappedFrames);
            if (result < 0 || (ma_snd_pcm_uframes_t)result != mappedFrames) {
                ((ma_snd_pcm_recover_proc)pDevice->pContext->alsa.snd_pcm_recover)((ma_snd_pcm_t*)pDevice->alsa.pPCM, result, MA_TRUE);
                return MA_FALSE;
            }

            if (requiresRestart) {
                if (((ma_snd_pcm_start_proc)pDevice->pContext->alsa.snd_pcm_start)((ma_snd_pcm_t*)pDevice->alsa.pPCM) < 0) {
                    return MA_FALSE;
                }
            }

            if (framesAvailable >= mappedFrames) {
                framesAvailable -= mappedFrames;
            } else {
                framesAvailable = 0;
            }
        }
    } else {
        /* readi/writei. */
        while (!pDevice->alsa.breakFromMainLoop) {
            ma_uint32 framesAvailable = ma_device__wait_for_frames__alsa(pDevice, NULL);
            if (framesAvailable == 0) {
                continue;
            }

            /* Don't bother asking the client for more audio data if we're just stopping the device anyway. */
            if (pDevice->alsa.breakFromMainLoop) {
                return MA_FALSE;
            }

            ma_device__read_frames_from_client(pDevice, framesAvailable, pDevice->alsa.pIntermediaryBuffer);

            ma_snd_pcm_sframes_t framesWritten = ((ma_snd_pcm_writei_proc)pDevice->pContext->alsa.snd_pcm_writei)((ma_snd_pcm_t*)pDevice->alsa.pPCM, pDevice->alsa.pIntermediaryBuffer, framesAvailable);
            if (framesWritten < 0) {
                if (framesWritten == -EAGAIN) {
                    continue;   /* Just keep trying... */
                } else if (framesWritten == -EPIPE) {
                    /* Underrun. Just recover and try writing again. */
                    if (((ma_snd_pcm_recover_proc)pDevice->pContext->alsa.snd_pcm_recover)((ma_snd_pcm_t*)pDevice->alsa.pPCM, framesWritten, MA_TRUE) < 0) {
                        ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to recover device after underrun.", MA_FAILED_TO_START_BACKEND_DEVICE);
                        return MA_FALSE;
                    }

                    framesWritten = ((ma_snd_pcm_writei_proc)pDevice->pContext->alsa.snd_pcm_writei)((ma_snd_pcm_t*)pDevice->alsa.pPCM, pDevice->alsa.pIntermediaryBuffer, framesAvailable);
                    if (framesWritten < 0) {
                        ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to write data to the internal device.", ma_result_from_errno((int)-framesWritten));
                        return MA_FALSE;
                    }

                    break;  /* Success. */
                } else {
                    ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] snd_pcm_writei() failed when writing initial data.", ma_result_from_errno((int)-framesWritten));
                    return MA_FALSE;
                }
            } else {
                break;  /* Success. */
            }
        }
    }

    return MA_TRUE;
}

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

static ma_bool32 ma_device_read_and_send_to_client__alsa(ma_device* pDevice)
{
    MA_ASSERT(pDevice != NULL);
    if (!ma_device_is_started(pDevice)) {
        return MA_FALSE;
    }
    if (pDevice->alsa.breakFromMainLoop) {
        return MA_FALSE;
    }

    ma_uint32 framesToSend = 0;
    void* pBuffer = NULL;
    if (pDevice->alsa.pIntermediaryBuffer == NULL) {
        /* mmap. */
        ma_bool32 requiresRestart;
        ma_uint32 framesAvailable = ma_device__wait_for_frames__alsa(pDevice, &requiresRestart);
        if (framesAvailable == 0) {
            return MA_FALSE;
        }

        const ma_snd_pcm_channel_area_t* pAreas;
        ma_snd_pcm_uframes_t mappedOffset;
        ma_snd_pcm_uframes_t mappedFrames = framesAvailable;
        while (framesAvailable > 0) {
            int result = ((ma_snd_pcm_mmap_begin_proc)pDevice->pContext->alsa.snd_pcm_mmap_begin)((ma_snd_pcm_t*)pDevice->alsa.pPCM, &pAreas, &mappedOffset, &mappedFrames);
            if (result < 0) {
                return MA_FALSE;
            }

            if (mappedFrames > 0) {
                void* pBuffer = (ma_uint8*)pAreas[0].addr + ((pAreas[0].first + (mappedOffset * pAreas[0].step)) / 8);
                ma_device__send_frames_to_client(pDevice, mappedFrames, pBuffer);
            }

            result = ((ma_snd_pcm_mmap_commit_proc)pDevice->pContext->alsa.snd_pcm_mmap_commit)((ma_snd_pcm_t*)pDevice->alsa.pPCM, mappedOffset, mappedFrames);
            if (result < 0 || (ma_snd_pcm_uframes_t)result != mappedFrames) {
                ((ma_snd_pcm_recover_proc)pDevice->pContext->alsa.snd_pcm_recover)((ma_snd_pcm_t*)pDevice->alsa.pPCM, result, MA_TRUE);
                return MA_FALSE;
            }

            if (requiresRestart) {
                if (((ma_snd_pcm_start_proc)pDevice->pContext->alsa.snd_pcm_start)((ma_snd_pcm_t*)pDevice->alsa.pPCM) < 0) {
                    return MA_FALSE;
                }
            }

            if (framesAvailable >= mappedFrames) {
                framesAvailable -= mappedFrames;
            } else {
                framesAvailable = 0;
            }
        }
    } else {
        /* readi/writei. */
        ma_snd_pcm_sframes_t framesRead = 0;
        while (!pDevice->alsa.breakFromMainLoop) {
            ma_uint32 framesAvailable = ma_device__wait_for_frames__alsa(pDevice, NULL);
            if (framesAvailable == 0) {
                continue;
            }

            framesRead = ((ma_snd_pcm_readi_proc)pDevice->pContext->alsa.snd_pcm_readi)((ma_snd_pcm_t*)pDevice->alsa.pPCM, pDevice->alsa.pIntermediaryBuffer, framesAvailable);
            if (framesRead < 0) {
                if (framesRead == -EAGAIN) {
                    continue;   /* Just keep trying... */
                } else if (framesRead == -EPIPE) {
                    /* Overrun. Just recover and try reading again. */
                    if (((ma_snd_pcm_recover_proc)pDevice->pContext->alsa.snd_pcm_recover)((ma_snd_pcm_t*)pDevice->alsa.pPCM, framesRead, MA_TRUE) < 0) {
                        ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to recover device after overrun.", MA_FAILED_TO_START_BACKEND_DEVICE);
                        return MA_FALSE;
                    }

                    framesRead = ((ma_snd_pcm_readi_proc)pDevice->pContext->alsa.snd_pcm_readi)((ma_snd_pcm_t*)pDevice->alsa.pPCM, pDevice->alsa.pIntermediaryBuffer, framesAvailable);
                    if (framesRead < 0) {
                        ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to read data from the internal device.", ma_result_from_errno((int)-framesRead));
                        return MA_FALSE;
                    }

                    break;  /* Success. */
                } else {
                    return MA_FALSE;
                }
            } else {
                break;  /* Success. */
            }
        }

        framesToSend = framesRead;
        pBuffer = pDevice->alsa.pIntermediaryBuffer;
    }

    if (framesToSend > 0) {
        ma_device__send_frames_to_client(pDevice, framesToSend, pBuffer);
    }

    return MA_TRUE;
}
#endif /* 0 */

static void ma_device_uninit__alsa(ma_device* pDevice)
{
    MA_ASSERT(pDevice != NULL);

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

    const ma_device_id* pDeviceID;
    ma_format internalFormat;
    ma_uint32 internalChannels;
    ma_uint32 internalSampleRate;
    ma_channel internalChannelMap[MA_MAX_CHANNELS];
    ma_uint32 internalPeriodSizeInFrames;
    ma_uint32 internalPeriods;
    int openMode;
    ma_snd_pcm_hw_params_t* pHWParams;
    ma_snd_pcm_sw_params_t* pSWParams;
    ma_snd_pcm_uframes_t bufferBoundary;
    float bufferSizeScaleFactor;

    MA_ASSERT(pContext != NULL);
    MA_ASSERT(pConfig != NULL);
    MA_ASSERT(deviceType != ma_device_type_duplex); /* This function should only be called for playback _or_ capture, never duplex. */
    MA_ASSERT(pDevice != NULL);

    formatALSA = ma_convert_ma_format_to_alsa_format((deviceType == ma_device_type_capture) ? pConfig->capture.format : pConfig->playback.format);
    shareMode  = (deviceType == ma_device_type_capture) ? pConfig->capture.shareMode : pConfig->playback.shareMode;
    pDeviceID  = (deviceType == ma_device_type_capture) ? pConfig->capture.pDeviceID : pConfig->playback.pDeviceID;

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

        if (resultALSA < 0) {
            ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
            ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set period count. snd_pcm_hw_params_set_periods_near() failed.", ma_result_from_errno(-resultALSA));
        }
        internalPeriods = periods;
    }

    /* Buffer Size */
    {
        ma_snd_pcm_uframes_t actualBufferSizeInFrames = pConfig->periodSizeInFrames * internalPeriods;
        if (actualBufferSizeInFrames == 0) {
            actualBufferSizeInFrames = ma_scale_buffer_size(ma_calculate_buffer_size_in_frames_from_milliseconds(pConfig->periodSizeInMilliseconds, internalSampleRate), bufferSizeScaleFactor) * internalPeriods;
        }

        resultALSA = ((ma_snd_pcm_hw_params_set_buffer_size_near_proc)pContext->alsa.snd_pcm_hw_params_set_buffer_size_near)(pPCM, pHWParams, &actualBufferSizeInFrames);
        if (resultALSA < 0) {
            ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
            ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set buffer size for device. snd_pcm_hw_params_set_buffer_size() failed.", ma_result_from_errno(-resultALSA));
        }
        internalPeriodSizeInFrames = actualBufferSizeInFrames / internalPeriods;
    }

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

    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        ma_result result = ma_device_init_by_type__alsa(pContext, pConfig, ma_device_type_playback, pDevice);
        if (result != MA_SUCCESS) {
            return result;
        }
    }

    return MA_SUCCESS;
}

static ma_result ma_device_read__alsa(ma_device* pDevice, void* pFramesOut, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    ma_snd_pcm_sframes_t resultALSA;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pFramesOut != NULL);

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

    for (;;) {
        resultALSA = ((ma_snd_pcm_readi_proc)pDevice->pContext->alsa.snd_pcm_readi)((ma_snd_pcm_t*)pDevice->alsa.pPCMCapture, pFramesOut, frameCount);
        if (resultALSA >= 0) {
            break;  /* Success. */
        } else {
            if (resultALSA == -EAGAIN) {
                /*printf("TRACE: EGAIN (read)\n");*/
                continue;   /* Try again. */
            } else if (resultALSA == -EPIPE) {
            #if defined(MA_DEBUG_OUTPUT)
                printf("TRACE: EPIPE (read)\n");
            #endif

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

                resultALSA = ((ma_snd_pcm_recover_proc)pDevice->pContext->alsa.snd_pcm_recover)((ma_snd_pcm_t*)pDevice->alsa.pPCMCapture, resultALSA, MA_TRUE);
                if (resultALSA < 0) {
                    return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to recover device after overrun.", ma_result_from_errno((int)-resultALSA));
                }

                resultALSA = ((ma_snd_pcm_start_proc)pDevice->pContext->alsa.snd_pcm_start)((ma_snd_pcm_t*)pDevice->alsa.pPCMCapture);
                if (resultALSA < 0) {
                    return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to start device after underrun.", ma_result_from_errno((int)-resultALSA));
                }

                resultALSA = ((ma_snd_pcm_readi_proc)pDevice->pContext->alsa.snd_pcm_readi)((ma_snd_pcm_t*)pDevice->alsa.pPCMCapture, pFramesOut, frameCount);
                if (resultALSA < 0) {
                    return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to read data from the internal device.", ma_result_from_errno((int)-resultALSA));
                }
            }
        }
    }

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

    return MA_SUCCESS;
}

static ma_result ma_device_write__alsa(ma_device* pDevice, const void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    ma_snd_pcm_sframes_t resultALSA;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pFrames != NULL);

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

    for (;;) {
        resultALSA = ((ma_snd_pcm_writei_proc)pDevice->pContext->alsa.snd_pcm_writei)((ma_snd_pcm_t*)pDevice->alsa.pPCMPlayback, pFrames, frameCount);
        if (resultALSA >= 0) {
            break;  /* Success. */
        } else {
            if (resultALSA == -EAGAIN) {
                /*printf("TRACE: EGAIN (write)\n");*/
                continue;   /* Try again. */
            } else if (resultALSA == -EPIPE) {
            #if defined(MA_DEBUG_OUTPUT)
                printf("TRACE: EPIPE (write)\n");
            #endif

                /* Underrun. Recover and try again. If this fails we need to return an error. */
                resultALSA = ((ma_snd_pcm_recover_proc)pDevice->pContext->alsa.snd_pcm_recover)((ma_snd_pcm_t*)pDevice->alsa.pPCMPlayback, resultALSA, MA_TRUE);
                if (resultALSA < 0) { /* MA_TRUE=silent (don't print anything on error). */
                    return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to recover device after underrun.", ma_result_from_errno((int)-resultALSA));
                }

                /*
                In my testing I have had a situation where writei() does not automatically restart the device even though I've set it
                up as such in the software parameters. What will happen is writei() will block indefinitely even though the number of
                frames is well beyond the auto-start threshold. To work around this I've needed to add an explicit start here. Not sure
                if this is me just being stupid and not recovering the device properly, but this definitely feels like something isn't
                quite right here.
                */
                resultALSA = ((ma_snd_pcm_start_proc)pDevice->pContext->alsa.snd_pcm_start)((ma_snd_pcm_t*)pDevice->alsa.pPCMPlayback);
                if (resultALSA < 0) {
                    return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to start device after underrun.", ma_result_from_errno((int)-resultALSA));
                }

                resultALSA = ((ma_snd_pcm_writei_proc)pDevice->pContext->alsa.snd_pcm_writei)((ma_snd_pcm_t*)pDevice->alsa.pPCMPlayback, pFrames, frameCount);
                if (resultALSA < 0) {
                    return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to write data to device after underrun.", ma_result_from_errno((int)-resultALSA));
                }
            }
        }
    }

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

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

                } else {
                    /* readi() and writei() */

                    /* The process is: device_read -> convert -> callback -> convert -> device_write */
                    ma_uint32 totalCapturedDeviceFramesProcessed = 0;
                    ma_uint32 capturedDevicePeriodSizeInFrames = ma_min(pDevice->capture.internalPeriodSizeInFrames, pDevice->playback.internalPeriodSizeInFrames);
                    
                    while (totalCapturedDeviceFramesProcessed < capturedDevicePeriodSizeInFrames) {
                        ma_uint8  capturedDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint8  playbackDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint32 capturedDeviceDataCapInFrames = sizeof(capturedDeviceData) / ma_get_bytes_per_frame(pDevice->capture.internalFormat,  pDevice->capture.internalChannels);
                        ma_uint32 playbackDeviceDataCapInFrames = sizeof(playbackDeviceData) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                        ma_uint32 capturedDeviceFramesRemaining;
                        ma_uint32 capturedDeviceFramesProcessed;
                        ma_uint32 capturedDeviceFramesToProcess;
                        ma_uint32 capturedDeviceFramesToTryProcessing = capturedDevicePeriodSizeInFrames - totalCapturedDeviceFramesProcessed;
                        if (capturedDeviceFramesToTryProcessing > capturedDeviceDataCapInFrames) {
                            capturedDeviceFramesToTryProcessing = capturedDeviceDataCapInFrames;
                        }

                        result = ma_device_read__alsa(pDevice, capturedDeviceData, capturedDeviceFramesToTryProcessing, &capturedDeviceFramesToProcess);
                        if (result != MA_SUCCESS) {
                            exitLoop = MA_TRUE;
                            break;
                        }

                        capturedDeviceFramesRemaining = capturedDeviceFramesToProcess;
                        capturedDeviceFramesProcessed = 0;

                        for (;;) {
                            ma_uint8  capturedClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                            ma_uint8  playbackClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                            ma_uint32 capturedClientDataCapInFrames = sizeof(capturedClientData) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
                            ma_uint32 playbackClientDataCapInFrames = sizeof(playbackClientData) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
                            ma_uint64 capturedClientFramesToProcessThisIteration = ma_min(capturedClientDataCapInFrames, playbackClientDataCapInFrames);
                            ma_uint64 capturedDeviceFramesToProcessThisIteration = capturedDeviceFramesRemaining;
                            ma_uint8* pRunningCapturedDeviceFrames = ma_offset_ptr(capturedDeviceData, capturedDeviceFramesProcessed * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));

                            /* Convert capture data from device format to client format. */
                            result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningCapturedDeviceFrames, &capturedDeviceFramesToProcessThisIteration, capturedClientData, &capturedClientFramesToProcessThisIteration);
                            if (result != MA_SUCCESS) {
                                break;
                            }

                            /*
                            If we weren't able to generate any output frames it must mean we've exhaused all of our input. The only time this would not be the case is if capturedClientData was too small
                            which should never be the case when it's of the size MA_DATA_CONVERTER_STACK_BUFFER_SIZE.
                            */
                            if (capturedClientFramesToProcessThisIteration == 0) {
                                break;
                            }

                            ma_device__on_data(pDevice, playbackClientData, capturedClientData, (ma_uint32)capturedClientFramesToProcessThisIteration);    /* Safe cast .*/

                            capturedDeviceFramesProcessed += (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */
                            capturedDeviceFramesRemaining -= (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */

                            /* At this point the playbackClientData buffer should be holding data that needs to be written to the device. */
                            for (;;) {
                                ma_uint64 convertedClientFrameCount = capturedClientFramesToProcessThisIteration;
                                ma_uint64 convertedDeviceFrameCount = playbackDeviceDataCapInFrames;
                                result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, playbackClientData, &convertedClientFrameCount, playbackDeviceData, &convertedDeviceFrameCount);
                                if (result != MA_SUCCESS) {
                                    break;
                                }

                                result = ma_device_write__alsa(pDevice, playbackDeviceData, (ma_uint32)convertedDeviceFrameCount, NULL);    /* Safe cast. */
                                if (result != MA_SUCCESS) {
                                    exitLoop = MA_TRUE;
                                    break;
                                }

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

            case ma_device_type_capture:
            {
                if (pDevice->alsa.isUsingMMapCapture) {
                    /* MMAP */
                    return MA_INVALID_OPERATION;    /* Not yet implemented. */
                } else {
                    /* readi() */

                    /* We read in chunks of the period size, but use a stack allocated buffer for the intermediary. */
                    ma_uint8 intermediaryBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint32 intermediaryBufferSizeInFrames = sizeof(intermediaryBuffer) / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
                    ma_uint32 periodSizeInFrames = pDevice->capture.internalPeriodSizeInFrames;
                    ma_uint32 framesReadThisPeriod = 0;
                    while (framesReadThisPeriod < periodSizeInFrames) {
                        ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesReadThisPeriod;
                        ma_uint32 framesProcessed;
                        ma_uint32 framesToReadThisIteration = framesRemainingInPeriod;
                        if (framesToReadThisIteration > intermediaryBufferSizeInFrames) {
                            framesToReadThisIteration = intermediaryBufferSizeInFrames;
                        }

                        result = ma_device_read__alsa(pDevice, intermediaryBuffer, framesToReadThisIteration, &framesProcessed);
                        if (result != MA_SUCCESS) {
                            exitLoop = MA_TRUE;
                            break;
                        }

                        ma_device__send_frames_to_client(pDevice, framesProcessed, intermediaryBuffer);

                        framesReadThisPeriod += framesProcessed;
                    }
                }
            } break;

            case ma_device_type_playback:
            {
                if (pDevice->alsa.isUsingMMapPlayback) {
                    /* MMAP */
                    return MA_INVALID_OPERATION;    /* Not yet implemented. */
                } else {
                    /* writei() */

                    /* We write in chunks of the period size, but use a stack allocated buffer for the intermediary. */
                    ma_uint8 intermediaryBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint32 intermediaryBufferSizeInFrames = sizeof(intermediaryBuffer) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                    ma_uint32 periodSizeInFrames = pDevice->playback.internalPeriodSizeInFrames;
                    ma_uint32 framesWrittenThisPeriod = 0;
                    while (framesWrittenThisPeriod < periodSizeInFrames) {
                        ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesWrittenThisPeriod;
                        ma_uint32 framesProcessed;
                        ma_uint32 framesToWriteThisIteration = framesRemainingInPeriod;
                        if (framesToWriteThisIteration > intermediaryBufferSizeInFrames) {
                            framesToWriteThisIteration = intermediaryBufferSizeInFrames;
                        }

                        ma_device__read_frames_from_client(pDevice, framesToWriteThisIteration, intermediaryBuffer);

                        result = ma_device_write__alsa(pDevice, intermediaryBuffer, framesToWriteThisIteration, &framesProcessed);
                        if (result != MA_SUCCESS) {
                            exitLoop = MA_TRUE;
                            break;
                        }

                        framesWrittenThisPeriod += framesProcessed;
                    }
                }
            } break;

            /* To silence a warning. Will never hit this. */
            case ma_device_type_loopback:
            default: break;
        } 
    }

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

    }

    ((ma_pa_context_disconnect_proc)pContext->pulse.pa_context_disconnect)((ma_pa_context*)pDevice->pulse.pPulseContext);
    ((ma_pa_context_unref_proc)pContext->pulse.pa_context_unref)((ma_pa_context*)pDevice->pulse.pPulseContext);
    ((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)((ma_pa_mainloop*)pDevice->pulse.pMainLoop);
}

static ma_pa_buffer_attr ma_device__pa_buffer_attr_new(ma_uint32 periodSizeInFrames, ma_uint32 periods, const ma_pa_sample_spec* ss)
{
    ma_pa_buffer_attr attr;
    attr.maxlength = periodSizeInFrames * periods * ma_get_bytes_per_frame(ma_format_from_pulse(ss->format), ss->channels);
    attr.tlength   = attr.maxlength / periods;
    attr.prebuf    = (ma_uint32)-1;
    attr.minreq    = (ma_uint32)-1;
    attr.fragsize  = attr.maxlength / periods;

    return attr;
}

static ma_pa_stream* ma_device__pa_stream_new__pulse(ma_device* pDevice, const char* pStreamName, const ma_pa_sample_spec* ss, const ma_pa_channel_map* cmap)
{

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


    if ((pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) && pConfig->playback.pDeviceID != NULL) {
        devPlayback = pConfig->playback.pDeviceID->pulse;
    }
    if ((pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) && pConfig->capture.pDeviceID != NULL) {
        devCapture = pConfig->capture.pDeviceID->pulse;
    }

    periodSizeInMilliseconds = pConfig->periodSizeInMilliseconds;
    if (periodSizeInMilliseconds == 0) {
        periodSizeInMilliseconds = ma_calculate_buffer_size_in_milliseconds_from_frames(pConfig->periodSizeInFrames, pConfig->sampleRate);
    }

    pDevice->pulse.pMainLoop = ((ma_pa_mainloop_new_proc)pContext->pulse.pa_mainloop_new)();
    if (pDevice->pulse.pMainLoop == NULL) {
        result = ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to create main loop for device.", MA_FAILED_TO_INIT_BACKEND);
        goto on_error0;
    }

    pDevice->pulse.pAPI = ((ma_pa_mainloop_get_api_proc)pContext->pulse.pa_mainloop_get_api)((ma_pa_mainloop*)pDevice->pulse.pMainLoop);
    if (pDevice->pulse.pAPI == NULL) {

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

            ma_device__wait_for_operation__pulse(pDevice, pOP);
            ((ma_pa_operation_unref_proc)pContext->pulse.pa_operation_unref)(pOP);
        } else {
            result = ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to retrieve source info for capture device.", ma_result_from_pulse(error));
            goto on_error3;
        }

        ss = sourceInfo.sample_spec;
        cmap = sourceInfo.channel_map;

        pDevice->capture.internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(periodSizeInMilliseconds, ss.rate);
        pDevice->capture.internalPeriods            = pConfig->periods;

        attr = ma_device__pa_buffer_attr_new(pDevice->capture.internalPeriodSizeInFrames, pConfig->periods, &ss);
    #ifdef MA_DEBUG_OUTPUT
        printf("[PulseAudio] Capture attr: maxlength=%d, tlength=%d, prebuf=%d, minreq=%d, fragsize=%d; internalPeriodSizeInFrames=%d\n", attr.maxlength, attr.tlength, attr.prebuf, attr.minreq, attr.fragsize, pDevice->capture.internalPeriodSizeInFram...
    #endif

        pDevice->pulse.pStreamCapture = ma_device__pa_stream_new__pulse(pDevice, pConfig->pulse.pStreamNameCapture, &ss, &cmap);
        if (pDevice->pulse.pStreamCapture == NULL) {
            result = ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to create PulseAudio capture stream.", MA_FAILED_TO_OPEN_BACKEND_DEVICE);

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

        for (iChannel = 0; iChannel < pDevice->capture.internalChannels; ++iChannel) {
            pDevice->capture.internalChannelMap[iChannel] = ma_channel_position_from_pulse(cmap.map[iChannel]);
        }

        /* Buffer. */
        pActualAttr = ((ma_pa_stream_get_buffer_attr_proc)pContext->pulse.pa_stream_get_buffer_attr)((ma_pa_stream*)pDevice->pulse.pStreamCapture);
        if (pActualAttr != NULL) {
            attr = *pActualAttr;
        }
        pDevice->capture.internalPeriods            = attr.maxlength / attr.fragsize;
        pDevice->capture.internalPeriodSizeInFrames = attr.maxlength / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels) / pDevice->capture.internalPeriods;
    #ifdef MA_DEBUG_OUTPUT
        printf("[PulseAudio] Capture actual attr: maxlength=%d, tlength=%d, prebuf=%d, minreq=%d, fragsize=%d; internalPeriodSizeInFrames=%d\n", attr.maxlength, attr.tlength, attr.prebuf, attr.minreq, attr.fragsize, pDevice->capture.internalPeriodSiz...
    #endif

        /* Name. */
        devCapture = ((ma_pa_stream_get_device_name_proc)pContext->pulse.pa_stream_get_device_name)((ma_pa_stream*)pDevice->pulse.pStreamCapture);
        if (devCapture != NULL) {
            ma_pa_operation* pOP = ((ma_pa_context_get_source_info_by_name_proc)pContext->pulse.pa_context_get_source_info_by_name)((ma_pa_context*)pDevice->pulse.pPulseContext, devCapture, ma_device_source_name_callback, pDevice);
            if (pOP != NULL) {
                ma_device__wait_for_operation__pulse(pDevice, pOP);

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

            ma_device__wait_for_operation__pulse(pDevice, pOP);
            ((ma_pa_operation_unref_proc)pContext->pulse.pa_operation_unref)(pOP);
        } else {
            result = ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to retrieve sink info for playback device.", ma_result_from_pulse(error));
            goto on_error3;
        }

        ss = sinkInfo.sample_spec;
        cmap = sinkInfo.channel_map;

        pDevice->playback.internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(periodSizeInMilliseconds, ss.rate);
        pDevice->playback.internalPeriods            = pConfig->periods;

        attr = ma_device__pa_buffer_attr_new(pDevice->playback.internalPeriodSizeInFrames, pConfig->periods, &ss);
    #ifdef MA_DEBUG_OUTPUT
        printf("[PulseAudio] Playback attr: maxlength=%d, tlength=%d, prebuf=%d, minreq=%d, fragsize=%d; internalPeriodSizeInFrames=%d\n", attr.maxlength, attr.tlength, attr.prebuf, attr.minreq, attr.fragsize, pDevice->playback.internalPeriodSizeInFr...
    #endif

        pDevice->pulse.pStreamPlayback = ma_device__pa_stream_new__pulse(pDevice, pConfig->pulse.pStreamNamePlayback, &ss, &cmap);
        if (pDevice->pulse.pStreamPlayback == NULL) {
            result = ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to create PulseAudio playback stream.", MA_FAILED_TO_OPEN_BACKEND_DEVICE);

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

        for (iChannel = 0; iChannel < pDevice->playback.internalChannels; ++iChannel) {
            pDevice->playback.internalChannelMap[iChannel] = ma_channel_position_from_pulse(cmap.map[iChannel]);
        }

        /* Buffer. */
        pActualAttr = ((ma_pa_stream_get_buffer_attr_proc)pContext->pulse.pa_stream_get_buffer_attr)((ma_pa_stream*)pDevice->pulse.pStreamPlayback);
        if (pActualAttr != NULL) {
            attr = *pActualAttr;
        }
        pDevice->playback.internalPeriods            = attr.maxlength / attr.tlength;
        pDevice->playback.internalPeriodSizeInFrames = attr.maxlength / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels) / pDevice->playback.internalPeriods;
    #ifdef MA_DEBUG_OUTPUT
        printf("[PulseAudio] Playback actual attr: maxlength=%d, tlength=%d, prebuf=%d, minreq=%d, fragsize=%d; internalPeriodSizeInFrames=%d\n", attr.maxlength, attr.tlength, attr.prebuf, attr.minreq, attr.fragsize, pDevice->playback.internalPeriodS...
    #endif

        /* Name. */
        devPlayback = ((ma_pa_stream_get_device_name_proc)pContext->pulse.pa_stream_get_device_name)((ma_pa_stream*)pDevice->pulse.pStreamPlayback);
        if (devPlayback != NULL) {
            ma_pa_operation* pOP = ((ma_pa_context_get_sink_info_by_name_proc)pContext->pulse.pa_context_get_sink_info_by_name)((ma_pa_context*)pDevice->pulse.pPulseContext, devPlayback, ma_device_sink_name_callback, pDevice);
            if (pOP != NULL) {
                ma_device__wait_for_operation__pulse(pDevice, pOP);

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


        result = ma_device__cork_stream__pulse(pDevice, ma_device_type_playback, 1);
        if (result != MA_SUCCESS) {
            return result;
        }
    }

    return MA_SUCCESS;
}

static ma_result ma_device_write__pulse(ma_device* pDevice, const void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    ma_uint32 totalFramesWritten;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pPCMFrames != NULL);
    MA_ASSERT(frameCount > 0);

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

    totalFramesWritten = 0;
    while (totalFramesWritten < frameCount) {
        if (ma_device__get_state(pDevice) != MA_STATE_STARTED) {
            return MA_DEVICE_NOT_STARTED;
        }

        /* Place the data into the mapped buffer if we have one. */
        if (pDevice->pulse.pMappedBufferPlayback != NULL && pDevice->pulse.mappedBufferFramesRemainingPlayback > 0) {
            ma_uint32 bpf = ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
            ma_uint32 mappedBufferFramesConsumed = pDevice->pulse.mappedBufferFramesCapacityPlayback - pDevice->pulse.mappedBufferFramesRemainingPlayback;

            void* pDst = (ma_uint8*)pDevice->pulse.pMappedBufferPlayback + (mappedBufferFramesConsumed * bpf);
            const void* pSrc = (const ma_uint8*)pPCMFrames + (totalFramesWritten * bpf);
            ma_uint32  framesToCopy = ma_min(pDevice->pulse.mappedBufferFramesRemainingPlayback, (frameCount - totalFramesWritten));
            MA_COPY_MEMORY(pDst, pSrc, framesToCopy * bpf);

            pDevice->pulse.mappedBufferFramesRemainingPlayback -= framesToCopy;
            totalFramesWritten += framesToCopy;
        }

        /*
        Getting here means we've run out of data in the currently mapped chunk. We need to write this to the device and then try
        mapping another chunk. If this fails we need to wait for space to become available.
        */
        if (pDevice->pulse.mappedBufferFramesCapacityPlayback > 0 && pDevice->pulse.mappedBufferFramesRemainingPlayback == 0) {
            size_t nbytes = pDevice->pulse.mappedBufferFramesCapacityPlayback * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);

            int error = ((ma_pa_stream_write_proc)pDevice->pContext->pulse.pa_stream_write)((ma_pa_stream*)pDevice->pulse.pStreamPlayback, pDevice->pulse.pMappedBufferPlayback, nbytes, NULL, 0, MA_PA_SEEK_RELATIVE);
            if (error < 0) {
                return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to write data to the PulseAudio stream.", ma_result_from_pulse(error));
            }

            pDevice->pulse.pMappedBufferPlayback = NULL;
            pDevice->pulse.mappedBufferFramesRemainingPlayback = 0;
            pDevice->pulse.mappedBufferFramesCapacityPlayback = 0;
        }

        MA_ASSERT(totalFramesWritten <= frameCount);
        if (totalFramesWritten == frameCount) {
            break;
        }

        /* Getting here means we need to map a new buffer. If we don't have enough space we need to wait for more. */
        for (;;) {
            size_t writableSizeInBytes;

            /* If the device has been corked, don't try to continue. */
            if (((ma_pa_stream_is_corked_proc)pDevice->pContext->pulse.pa_stream_is_corked)((ma_pa_stream*)pDevice->pulse.pStreamPlayback)) {
                break;

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

            writableSizeInBytes = ((ma_pa_stream_writable_size_proc)pDevice->pContext->pulse.pa_stream_writable_size)((ma_pa_stream*)pDevice->pulse.pStreamPlayback);
            if (writableSizeInBytes != (size_t)-1) {
                if (writableSizeInBytes > 0) {
                    /* Data is avaialable. */
                    size_t bytesToMap = writableSizeInBytes;
                    int error = ((ma_pa_stream_begin_write_proc)pDevice->pContext->pulse.pa_stream_begin_write)((ma_pa_stream*)pDevice->pulse.pStreamPlayback, &pDevice->pulse.pMappedBufferPlayback, &bytesToMap);
                    if (error < 0) {
                        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to map write buffer.", ma_result_from_pulse(error));
                    }

                    pDevice->pulse.mappedBufferFramesCapacityPlayback  = bytesToMap / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                    pDevice->pulse.mappedBufferFramesRemainingPlayback = pDevice->pulse.mappedBufferFramesCapacityPlayback;

                    break;
                } else {
                    /* No data available. Need to wait for more. */
                    int error = ((ma_pa_mainloop_iterate_proc)pDevice->pContext->pulse.pa_mainloop_iterate)((ma_pa_mainloop*)pDevice->pulse.pMainLoop, 1, NULL);
                    if (error < 0) {
                        return ma_result_from_pulse(error);
                    }

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

        }
    }

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

    return MA_SUCCESS;
}

static ma_result ma_device_read__pulse(ma_device* pDevice, void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    ma_uint32 totalFramesRead;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pPCMFrames != NULL);
    MA_ASSERT(frameCount > 0);

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

    totalFramesRead = 0;
    while (totalFramesRead < frameCount) {
        if (ma_device__get_state(pDevice) != MA_STATE_STARTED) {
            return MA_DEVICE_NOT_STARTED;
        }

        /*
        If a buffer is mapped we need to read from that first. Once it's consumed we need to drop it. Note that pDevice->pulse.pMappedBufferCapture can be null in which
        case it could be a hole. In this case we just write zeros into the output buffer.
        */
        if (pDevice->pulse.mappedBufferFramesRemainingCapture > 0) {
            ma_uint32 bpf = ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
            ma_uint32 mappedBufferFramesConsumed = pDevice->pulse.mappedBufferFramesCapacityCapture - pDevice->pulse.mappedBufferFramesRemainingCapture;

            ma_uint32  framesToCopy = ma_min(pDevice->pulse.mappedBufferFramesRemainingCapture, (frameCount - totalFramesRead));
            void* pDst = (ma_uint8*)pPCMFrames + (totalFramesRead * bpf);

            /*
            This little bit of logic here is specifically for PulseAudio and it's hole management. The buffer pointer will be set to NULL
            when the current fragment is a hole. For a hole we just output silence.
            */
            if (pDevice->pulse.pMappedBufferCapture != NULL) {
                const void* pSrc = (const ma_uint8*)pDevice->pulse.pMappedBufferCapture + (mappedBufferFramesConsumed * bpf);
                MA_COPY_MEMORY(pDst, pSrc, framesToCopy * bpf);
            } else {
                MA_ZERO_MEMORY(pDst, framesToCopy * bpf);
            #if defined(MA_DEBUG_OUTPUT)
                printf("[PulseAudio] ma_device_read__pulse: Filling hole with silence.\n");
            #endif
            }

            pDevice->pulse.mappedBufferFramesRemainingCapture -= framesToCopy;
            totalFramesRead += framesToCopy;
        }

        /*
        Getting here means we've run out of data in the currently mapped chunk. We need to drop this from the device and then try
        mapping another chunk. If this fails we need to wait for data to become available.
        */
        if (pDevice->pulse.mappedBufferFramesCapacityCapture > 0 && pDevice->pulse.mappedBufferFramesRemainingCapture == 0) {
            int error;

        #if defined(MA_DEBUG_OUTPUT)

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

            error = ((ma_pa_stream_drop_proc)pDevice->pContext->pulse.pa_stream_drop)((ma_pa_stream*)pDevice->pulse.pStreamCapture);
            if (error != 0) {
                return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to drop fragment.", ma_result_from_pulse(error));
            }

            pDevice->pulse.pMappedBufferCapture = NULL;
            pDevice->pulse.mappedBufferFramesRemainingCapture = 0;
            pDevice->pulse.mappedBufferFramesCapacityCapture = 0;
        }

        MA_ASSERT(totalFramesRead <= frameCount);
        if (totalFramesRead == frameCount) {
            break;
        }

        /* Getting here means we need to map a new buffer. If we don't have enough data we wait for more. */
        for (;;) {
            int error;
            size_t bytesMapped;

            if (ma_device__get_state(pDevice) != MA_STATE_STARTED) {
                break;

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

            }

            MA_ASSERT(pDevice->pulse.pMappedBufferCapture == NULL); /* <-- We're about to map a buffer which means we shouldn't have an existing mapping. */

            error = ((ma_pa_stream_peek_proc)pDevice->pContext->pulse.pa_stream_peek)((ma_pa_stream*)pDevice->pulse.pStreamCapture, &pDevice->pulse.pMappedBufferCapture, &bytesMapped);
            if (error < 0) {
                return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to peek capture buffer.", ma_result_from_pulse(error));
            }

            if (bytesMapped > 0) {
                pDevice->pulse.mappedBufferFramesCapacityCapture  = bytesMapped / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
                pDevice->pulse.mappedBufferFramesRemainingCapture = pDevice->pulse.mappedBufferFramesCapacityCapture;

                #if defined(MA_DEBUG_OUTPUT)
                    printf("[PulseAudio] ma_device_read__pulse: Mapped. mappedBufferFramesCapacityCapture=%d, mappedBufferFramesRemainingCapture=%d\n", pDevice->pulse.mappedBufferFramesCapacityCapture, pDevice->pulse.mappedBufferFramesRemainingCaptur...
                #endif

                if (pDevice->pulse.pMappedBufferCapture == NULL) {
                    /* It's a hole. */
                    #if defined(MA_DEBUG_OUTPUT)
                        printf("[PulseAudio] ma_device_read__pulse: Call pa_stream_peek(). Hole.\n");

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

        {
            case ma_device_type_duplex:
            {
                /* The process is: device_read -> convert -> callback -> convert -> device_write */
                ma_uint32 totalCapturedDeviceFramesProcessed = 0;
                ma_uint32 capturedDevicePeriodSizeInFrames = ma_min(pDevice->capture.internalPeriodSizeInFrames, pDevice->playback.internalPeriodSizeInFrames);
                    
                while (totalCapturedDeviceFramesProcessed < capturedDevicePeriodSizeInFrames) {
                    ma_uint8  capturedDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint8  playbackDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint32 capturedDeviceDataCapInFrames = sizeof(capturedDeviceData) / ma_get_bytes_per_frame(pDevice->capture.internalFormat,  pDevice->capture.internalChannels);
                    ma_uint32 playbackDeviceDataCapInFrames = sizeof(playbackDeviceData) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                    ma_uint32 capturedDeviceFramesRemaining;
                    ma_uint32 capturedDeviceFramesProcessed;
                    ma_uint32 capturedDeviceFramesToProcess;
                    ma_uint32 capturedDeviceFramesToTryProcessing = capturedDevicePeriodSizeInFrames - totalCapturedDeviceFramesProcessed;
                    if (capturedDeviceFramesToTryProcessing > capturedDeviceDataCapInFrames) {
                        capturedDeviceFramesToTryProcessing = capturedDeviceDataCapInFrames;
                    }

                    result = ma_device_read__pulse(pDevice, capturedDeviceData, capturedDeviceFramesToTryProcessing, &capturedDeviceFramesToProcess);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    capturedDeviceFramesRemaining = capturedDeviceFramesToProcess;
                    capturedDeviceFramesProcessed = 0;

                    for (;;) {
                        ma_uint8  capturedClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint8  playbackClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint32 capturedClientDataCapInFrames = sizeof(capturedClientData) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
                        ma_uint32 playbackClientDataCapInFrames = sizeof(playbackClientData) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
                        ma_uint64 capturedClientFramesToProcessThisIteration = ma_min(capturedClientDataCapInFrames, playbackClientDataCapInFrames);
                        ma_uint64 capturedDeviceFramesToProcessThisIteration = capturedDeviceFramesRemaining;
                        ma_uint8* pRunningCapturedDeviceFrames = ma_offset_ptr(capturedDeviceData, capturedDeviceFramesProcessed * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));

                        /* Convert capture data from device format to client format. */
                        result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningCapturedDeviceFrames, &capturedDeviceFramesToProcessThisIteration, capturedClientData, &capturedClientFramesToProcessThisIteration);
                        if (result != MA_SUCCESS) {
                            break;
                        }

                        /*
                        If we weren't able to generate any output frames it must mean we've exhaused all of our input. The only time this would not be the case is if capturedClientData was too small
                        which should never be the case when it's of the size MA_DATA_CONVERTER_STACK_BUFFER_SIZE.
                        */
                        if (capturedClientFramesToProcessThisIteration == 0) {
                            break;
                        }

                        ma_device__on_data(pDevice, playbackClientData, capturedClientData, (ma_uint32)capturedClientFramesToProcessThisIteration);    /* Safe cast .*/

                        capturedDeviceFramesProcessed += (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */
                        capturedDeviceFramesRemaining -= (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */

                        /* At this point the playbackClientData buffer should be holding data that needs to be written to the device. */
                        for (;;) {
                            ma_uint64 convertedClientFrameCount = capturedClientFramesToProcessThisIteration;
                            ma_uint64 convertedDeviceFrameCount = playbackDeviceDataCapInFrames;
                            result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, playbackClientData, &convertedClientFrameCount, playbackDeviceData, &convertedDeviceFrameCount);
                            if (result != MA_SUCCESS) {
                                break;
                            }

                            result = ma_device_write__pulse(pDevice, playbackDeviceData, (ma_uint32)convertedDeviceFrameCount, NULL);   /* Safe cast. */
                            if (result != MA_SUCCESS) {
                                exitLoop = MA_TRUE;
                                break;
                            }

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

                        }
                    }

                    totalCapturedDeviceFramesProcessed += capturedDeviceFramesProcessed;
                }
            } break;

            case ma_device_type_capture:
            {
                ma_uint8 intermediaryBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                ma_uint32 intermediaryBufferSizeInFrames = sizeof(intermediaryBuffer) / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
                ma_uint32 periodSizeInFrames = pDevice->capture.internalPeriodSizeInFrames;
                ma_uint32 framesReadThisPeriod = 0;
                while (framesReadThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesReadThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToReadThisIteration = framesRemainingInPeriod;
                    if (framesToReadThisIteration > intermediaryBufferSizeInFrames) {
                        framesToReadThisIteration = intermediaryBufferSizeInFrames;
                    }

                    result = ma_device_read__pulse(pDevice, intermediaryBuffer, framesToReadThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    ma_device__send_frames_to_client(pDevice, framesProcessed, intermediaryBuffer);

                    framesReadThisPeriod += framesProcessed;
                }
            } break;

            case ma_device_type_playback:
            {
                ma_uint8 intermediaryBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                ma_uint32 intermediaryBufferSizeInFrames = sizeof(intermediaryBuffer) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                ma_uint32 periodSizeInFrames = pDevice->playback.internalPeriodSizeInFrames;
                ma_uint32 framesWrittenThisPeriod = 0;
                while (framesWrittenThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesWrittenThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToWriteThisIteration = framesRemainingInPeriod;
                    if (framesToWriteThisIteration > intermediaryBufferSizeInFrames) {
                        framesToWriteThisIteration = intermediaryBufferSizeInFrames;
                    }

                    ma_device__read_frames_from_client(pDevice, framesToWriteThisIteration, intermediaryBuffer);

                    result = ma_device_write__pulse(pDevice, intermediaryBuffer, framesToWriteThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    framesWrittenThisPeriod += framesProcessed;
                }
            } break;

            /* To silence a warning. Will never hit this. */
            case ma_device_type_loopback:
            default: break;
        }
    }

    /* Here is where the device needs to be stopped. */

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


JACK Backend

******************************************************************************/
#ifdef MA_HAS_JACK

/* It is assumed jack.h is available when compile-time linking is being used. */
#ifdef MA_NO_RUNTIME_LINKING
#include <jack/jack.h>

typedef jack_nframes_t              ma_jack_nframes_t;
typedef jack_options_t              ma_jack_options_t;
typedef jack_status_t               ma_jack_status_t;
typedef jack_client_t               ma_jack_client_t;
typedef jack_port_t                 ma_jack_port_t;
typedef JackProcessCallback         ma_JackProcessCallback;
typedef JackBufferSizeCallback      ma_JackBufferSizeCallback;
typedef JackShutdownCallback        ma_JackShutdownCallback;
#define MA_JACK_DEFAULT_AUDIO_TYPE  JACK_DEFAULT_AUDIO_TYPE
#define ma_JackNoStartServer        JackNoStartServer
#define ma_JackPortIsInput          JackPortIsInput
#define ma_JackPortIsOutput         JackPortIsOutput
#define ma_JackPortIsPhysical       JackPortIsPhysical
#else
typedef ma_uint32               ma_jack_nframes_t;
typedef int                     ma_jack_options_t;
typedef int                     ma_jack_status_t;
typedef struct ma_jack_client_t ma_jack_client_t;
typedef struct ma_jack_port_t   ma_jack_port_t;
typedef int  (* ma_JackProcessCallback)   (ma_jack_nframes_t nframes, void* arg);
typedef int  (* ma_JackBufferSizeCallback)(ma_jack_nframes_t nframes, void* arg);
typedef void (* ma_JackShutdownCallback)  (void* arg);
#define MA_JACK_DEFAULT_AUDIO_TYPE "32 bit float mono audio"
#define ma_JackNoStartServer       1
#define ma_JackPortIsInput         1
#define ma_JackPortIsOutput        2
#define ma_JackPortIsPhysical      4
#endif

typedef ma_jack_client_t* (* ma_jack_client_open_proc)             (const char* client_name, ma_jack_options_t options, ma_jack_status_t* status, ...);
typedef int               (* ma_jack_client_close_proc)            (ma_jack_client_t* client);
typedef int               (* ma_jack_client_name_size_proc)        (void);
typedef int               (* ma_jack_set_process_callback_proc)    (ma_jack_client_t* client, ma_JackProcessCallback process_callback, void* arg);
typedef int               (* ma_jack_set_buffer_size_callback_proc)(ma_jack_client_t* client, ma_JackBufferSizeCallback bufsize_callback, void* arg);
typedef void              (* ma_jack_on_shutdown_proc)             (ma_jack_client_t* client, ma_JackShutdownCallback function, void* arg);
typedef ma_jack_nframes_t (* ma_jack_get_sample_rate_proc)         (ma_jack_client_t* client);
typedef ma_jack_nframes_t (* ma_jack_get_buffer_size_proc)         (ma_jack_client_t* client);
typedef const char**      (* ma_jack_get_ports_proc)               (ma_jack_client_t* client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags);
typedef int               (* ma_jack_activate_proc)                (ma_jack_client_t* client);
typedef int               (* ma_jack_deactivate_proc)              (ma_jack_client_t* client);
typedef int               (* ma_jack_connect_proc)                 (ma_jack_client_t* client, const char* source_port, const char* destination_port);
typedef ma_jack_port_t*   (* ma_jack_port_register_proc)           (ma_jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size);
typedef const char*       (* ma_jack_port_name_proc)               (const ma_jack_port_t* port);
typedef void*             (* ma_jack_port_get_buffer_proc)         (ma_jack_port_t* port, ma_jack_nframes_t nframes);
typedef void              (* ma_jack_free_proc)                    (void* ptr);

static ma_result ma_context_open_client__jack(ma_context* pContext, ma_jack_client_t** ppClient)
{
    size_t maxClientNameSize;
    char clientName[256];
    ma_jack_status_t status;
    ma_jack_client_t* pClient;

    MA_ASSERT(pContext != NULL);

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


static void ma_device__jack_shutdown_callback(void* pUserData)
{
    /* JACK died. Stop the device. */
    ma_device* pDevice = (ma_device*)pUserData;
    MA_ASSERT(pDevice != NULL);

    ma_device_stop(pDevice);
}

static int ma_device__jack_buffer_size_callback(ma_jack_nframes_t frameCount, void* pUserData)
{
    ma_device* pDevice = (ma_device*)pUserData;
    MA_ASSERT(pDevice != NULL);

    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        size_t newBufferSize = frameCount * (pDevice->capture.internalChannels * ma_get_bytes_per_sample(pDevice->capture.internalFormat));
        float* pNewBuffer = (float*)ma__calloc_from_callbacks(newBufferSize, &pDevice->pContext->allocationCallbacks);
        if (pNewBuffer == NULL) {
            return MA_OUT_OF_MEMORY;
        }

        ma__free_from_callbacks(pDevice->jack.pIntermediaryBufferCapture, &pDevice->pContext->allocationCallbacks);

        pDevice->jack.pIntermediaryBufferCapture = pNewBuffer;
        pDevice->playback.internalPeriodSizeInFrames = frameCount;
    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        size_t newBufferSize = frameCount * (pDevice->playback.internalChannels * ma_get_bytes_per_sample(pDevice->playback.internalFormat));
        float* pNewBuffer = (float*)ma__calloc_from_callbacks(newBufferSize, &pDevice->pContext->allocationCallbacks);
        if (pNewBuffer == NULL) {
            return MA_OUT_OF_MEMORY;
        }

        ma__free_from_callbacks(pDevice->jack.pIntermediaryBufferPlayback, &pDevice->pContext->allocationCallbacks);

        pDevice->jack.pIntermediaryBufferPlayback = pNewBuffer;
        pDevice->playback.internalPeriodSizeInFrames = frameCount;
    }

    return 0;
}

static int ma_device__jack_process_callback(ma_jack_nframes_t frameCount, void* pUserData)
{
    ma_device* pDevice;
    ma_context* pContext;
    ma_uint32 iChannel;

    pDevice = (ma_device*)pUserData;
    MA_ASSERT(pDevice != NULL);

    pContext = pDevice->pContext;
    MA_ASSERT(pContext != NULL);

    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        /* Channels need to be interleaved. */
        for (iChannel = 0; iChannel < pDevice->capture.internalChannels; ++iChannel) {
            const float* pSrc = (const float*)((ma_jack_port_get_buffer_proc)pContext->jack.jack_port_get_buffer)((ma_jack_port_t*)pDevice->jack.pPortsCapture[iChannel], frameCount);
            if (pSrc != NULL) {
                float* pDst = pDevice->jack.pIntermediaryBufferCapture + iChannel;
                ma_jack_nframes_t iFrame;
                for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                    *pDst = *pSrc;

                    pDst += pDevice->capture.internalChannels;
                    pSrc += 1;
                }
            }
        }

        if (pDevice->type == ma_device_type_duplex) {
            ma_device__handle_duplex_callback_capture(pDevice, frameCount, pDevice->jack.pIntermediaryBufferCapture, &pDevice->jack.duplexRB);
        } else {
            ma_device__send_frames_to_client(pDevice, frameCount, pDevice->jack.pIntermediaryBufferCapture);
        }
    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        if (pDevice->type == ma_device_type_duplex) {
            ma_device__handle_duplex_callback_playback(pDevice, frameCount, pDevice->jack.pIntermediaryBufferPlayback, &pDevice->jack.duplexRB);
        } else {
            ma_device__read_frames_from_client(pDevice, frameCount, pDevice->jack.pIntermediaryBufferPlayback);
        }

        /* Channels need to be deinterleaved. */
        for (iChannel = 0; iChannel < pDevice->playback.internalChannels; ++iChannel) {
            float* pDst = (float*)((ma_jack_port_get_buffer_proc)pContext->jack.jack_port_get_buffer)((ma_jack_port_t*)pDevice->jack.pPortsPlayback[iChannel], frameCount);
            if (pDst != NULL) {
                const float* pSrc = pDevice->jack.pIntermediaryBufferPlayback + iChannel;
                ma_jack_nframes_t iFrame;
                for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                    *pDst = *pSrc;

                    pDst += 1;
                    pSrc += pDevice->playback.internalChannels;
                }
            }
        }
    }

    return 0;

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

    if (((ma_jack_set_process_callback_proc)pContext->jack.jack_set_process_callback)((ma_jack_client_t*)pDevice->jack.pClient, ma_device__jack_process_callback, pDevice) != 0) {
        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[JACK] Failed to set process callback.", MA_FAILED_TO_OPEN_BACKEND_DEVICE);
    }
    if (((ma_jack_set_buffer_size_callback_proc)pContext->jack.jack_set_buffer_size_callback)((ma_jack_client_t*)pDevice->jack.pClient, ma_device__jack_buffer_size_callback, pDevice) != 0) {
        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[JACK] Failed to set buffer size callback.", MA_FAILED_TO_OPEN_BACKEND_DEVICE);
    }

    ((ma_jack_on_shutdown_proc)pContext->jack.jack_on_shutdown)((ma_jack_client_t*)pDevice->jack.pClient, ma_device__jack_shutdown_callback, pDevice);


    /* The buffer size in frames can change. */
    periods            = pConfig->periods;
    periodSizeInFrames = ((ma_jack_get_buffer_size_proc)pContext->jack.jack_get_buffer_size)((ma_jack_client_t*)pDevice->jack.pClient);
    
    if (pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) {
        const char** ppPorts;

        pDevice->capture.internalFormat = ma_format_f32;
        pDevice->capture.internalChannels = 0;
        pDevice->capture.internalSampleRate = ((ma_jack_get_sample_rate_proc)pContext->jack.jack_get_sample_rate)((ma_jack_client_t*)pDevice->jack.pClient);
        ma_get_standard_channel_map(ma_standard_channel_map_alsa, pDevice->capture.internalChannels, pDevice->capture.internalChannelMap);

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

            }

            pDevice->capture.internalChannels += 1;
        }

        ((ma_jack_free_proc)pContext->jack.jack_free)((void*)ppPorts);

        pDevice->capture.internalPeriodSizeInFrames = periodSizeInFrames;
        pDevice->capture.internalPeriods            = periods;

        pDevice->jack.pIntermediaryBufferCapture = (float*)ma__calloc_from_callbacks(pDevice->capture.internalPeriodSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels), &pContext->allocationCallba...
        if (pDevice->jack.pIntermediaryBufferCapture == NULL) {
            ma_device_uninit__jack(pDevice);
            return MA_OUT_OF_MEMORY;
        }
    }

    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        const char** ppPorts;

        pDevice->playback.internalFormat = ma_format_f32;

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

            }

            pDevice->playback.internalChannels += 1;
        }

        ((ma_jack_free_proc)pContext->jack.jack_free)((void*)ppPorts);

        pDevice->playback.internalPeriodSizeInFrames = periodSizeInFrames;
        pDevice->playback.internalPeriods            = periods;

        pDevice->jack.pIntermediaryBufferPlayback = (float*)ma__calloc_from_callbacks(pDevice->playback.internalPeriodSizeInFrames * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels), &pContext->allocationCa...
        if (pDevice->jack.pIntermediaryBufferPlayback == NULL) {
            ma_device_uninit__jack(pDevice);
            return MA_OUT_OF_MEMORY;
        }
    }

    if (pDevice->type == ma_device_type_duplex) {
        ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_resampling(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalPeriodSizeInFrames * pDevice->capture.internalPeriods);
        result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->pContext->allocationCallbacks, &pDevice->jack.duplexRB);
        if (result != MA_SUCCESS) {
            ma_device_uninit__jack(pDevice);
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[JACK] Failed to initialize ring buffer.", result);
        }

        /* We need a period to act as a buffer for cases where the playback and capture device's end up desyncing. */
        {
            ma_uint32 marginSizeInFrames = rbSizeInFrames / pDevice->capture.internalPeriods;
            void* pMarginData;
            ma_pcm_rb_acquire_write(&pDevice->jack.duplexRB, &marginSizeInFrames, &pMarginData);
            {
                MA_ZERO_MEMORY(pMarginData, marginSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels));
            }
            ma_pcm_rb_commit_write(&pDevice->jack.duplexRB, marginSizeInFrames, pMarginData);
        }
    }

    return MA_SUCCESS;
}


static ma_result ma_device_start__jack(ma_device* pDevice)

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

        ma_free(pSampleRateRanges, &pContext->allocationCallbacks);
        return MA_SUCCESS;
    }
    
    /* Should never get here, but it would mean we weren't able to find any suitable sample rates. */
    /*ma_free(pSampleRateRanges, &pContext->allocationCallbacks);*/
    /*return MA_ERROR;*/
}
#endif

static ma_result ma_get_AudioObject_closest_buffer_size_in_frames(ma_context* pContext, AudioObjectID deviceObjectID, ma_device_type deviceType, ma_uint32 bufferSizeInFramesIn, ma_uint32* pBufferSizeInFramesOut)
{
    AudioObjectPropertyAddress propAddress;
    AudioValueRange bufferSizeRange;
    UInt32 dataSize;
    OSStatus status;

    MA_ASSERT(pContext != NULL);
    MA_ASSERT(pBufferSizeInFramesOut != NULL);
    
    *pBufferSizeInFramesOut = 0;    /* Safety. */

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

        *pBufferSizeInFramesOut = (ma_uint32)bufferSizeRange.mMinimum;
    } else if (bufferSizeInFramesIn > bufferSizeRange.mMaximum) {
        *pBufferSizeInFramesOut = (ma_uint32)bufferSizeRange.mMaximum;
    } else {
        *pBufferSizeInFramesOut = bufferSizeInFramesIn;
    }

    return MA_SUCCESS;
}

static ma_result ma_set_AudioObject_buffer_size_in_frames(ma_context* pContext, AudioObjectID deviceObjectID, ma_device_type deviceType, ma_uint32* pPeriodSizeInOut)
{
    ma_result result;
    ma_uint32 chosenBufferSizeInFrames;
    AudioObjectPropertyAddress propAddress;
    UInt32 dataSize;
    OSStatus status;

    MA_ASSERT(pContext != NULL);

    result = ma_get_AudioObject_closest_buffer_size_in_frames(pContext, deviceObjectID, deviceType, *pPeriodSizeInOut, &chosenBufferSizeInFrames);
    if (result != MA_SUCCESS) {
        return result;
    }

    /* Try setting the size of the buffer... If this fails we just use whatever is currently set. */
    propAddress.mSelector = kAudioDevicePropertyBufferFrameSize;
    propAddress.mScope    = (deviceType == ma_device_type_playback) ? kAudioObjectPropertyScopeOutput : kAudioObjectPropertyScopeInput;
    propAddress.mElement  = kAudioObjectPropertyElementMaster;
    
    ((ma_AudioObjectSetPropertyData_proc)pContext->coreaudio.AudioObjectSetPropertyData)(deviceObjectID, &propAddress, 0, NULL, sizeof(chosenBufferSizeInFrames), &chosenBufferSizeInFrames);

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

            pDeviceInfo->maxSampleRate = pDeviceInfo->minSampleRate;
        }
    }
#endif
    
    (void)pDeviceInfo; /* Unused. */
    return MA_SUCCESS;
}


static OSStatus ma_on_output__coreaudio(void* pUserData, AudioUnitRenderActionFlags* pActionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufferList)
{
    ma_device* pDevice = (ma_device*)pUserData;
    ma_stream_layout layout;

    MA_ASSERT(pDevice != NULL);

#if defined(MA_DEBUG_OUTPUT)
    printf("INFO: Output Callback: busNumber=%d, frameCount=%d, mNumberBuffers=%d\n", busNumber, frameCount, pBufferList->mNumberBuffers);
#endif

    /* We need to check whether or not we are outputting interleaved or non-interleaved samples. The way we do this is slightly different for each type. */
    layout = ma_stream_layout_interleaved;
    if (pBufferList->mBuffers[0].mNumberChannels != pDevice->playback.internalChannels) {
        layout = ma_stream_layout_deinterleaved;
    }
    
    if (layout == ma_stream_layout_interleaved) {
        /* For now we can assume everything is interleaved. */
        UInt32 iBuffer;
        for (iBuffer = 0; iBuffer < pBufferList->mNumberBuffers; ++iBuffer) {
            if (pBufferList->mBuffers[iBuffer].mNumberChannels == pDevice->playback.internalChannels) {
                ma_uint32 frameCountForThisBuffer = pBufferList->mBuffers[iBuffer].mDataByteSize / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                if (frameCountForThisBuffer > 0) {
                    if (pDevice->type == ma_device_type_duplex) {
                        ma_device__handle_duplex_callback_playback(pDevice, frameCountForThisBuffer, pBufferList->mBuffers[iBuffer].mData, &pDevice->coreaudio.duplexRB);
                    } else {
                        ma_device__read_frames_from_client(pDevice, frameCountForThisBuffer, pBufferList->mBuffers[iBuffer].mData);
                    }
                }
                
            #if defined(MA_DEBUG_OUTPUT)
                printf("  frameCount=%d, mNumberChannels=%d, mDataByteSize=%d\n", frameCount, pBufferList->mBuffers[iBuffer].mNumberChannels, pBufferList->mBuffers[iBuffer].mDataByteSize);
            #endif
            } else {
                /*
                This case is where the number of channels in the output buffer do not match our internal channels. It could mean that it's
                not interleaved, in which case we can't handle right now since miniaudio does not yet support non-interleaved streams. We just
                output silence here.
                */
                MA_ZERO_MEMORY(pBufferList->mBuffers[iBuffer].mData, pBufferList->mBuffers[iBuffer].mDataByteSize);

            #if defined(MA_DEBUG_OUTPUT)
                printf("  WARNING: Outputting silence. frameCount=%d, mNumberChannels=%d, mDataByteSize=%d\n", frameCount, pBufferList->mBuffers[iBuffer].mNumberChannels, pBufferList->mBuffers[iBuffer].mDataByteSize);
            #endif
            }
        }
    } else {
        /* This is the deinterleaved case. We need to update each buffer in groups of internalChannels. This assumes each buffer is the same size. */
        MA_ASSERT(pDevice->playback.internalChannels <= MA_MAX_CHANNELS);   /* This should heve been validated at initialization time. */
        
        /*
        For safety we'll check that the internal channels is a multiple of the buffer count. If it's not it means something
        very strange has happened and we're not going to support it.
        */
        if ((pBufferList->mNumberBuffers % pDevice->playback.internalChannels) == 0) {
            ma_uint8 tempBuffer[4096];
            UInt32 iBuffer;
        
            for (iBuffer = 0; iBuffer < pBufferList->mNumberBuffers; iBuffer += pDevice->playback.internalChannels) {
                ma_uint32 frameCountPerBuffer = pBufferList->mBuffers[iBuffer].mDataByteSize / ma_get_bytes_per_sample(pDevice->playback.internalFormat);
                ma_uint32 framesRemaining = frameCountPerBuffer;

                while (framesRemaining > 0) {
                    void* ppDeinterleavedBuffers[MA_MAX_CHANNELS];
                    ma_uint32 iChannel;
                    ma_uint32 framesToRead = sizeof(tempBuffer) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                    if (framesToRead > framesRemaining) {
                        framesToRead = framesRemaining;
                    }
                    
                    if (pDevice->type == ma_device_type_duplex) {
                        ma_device__handle_duplex_callback_playback(pDevice, framesToRead, tempBuffer, &pDevice->coreaudio.duplexRB);
                    } else {
                        ma_device__read_frames_from_client(pDevice, framesToRead, tempBuffer);
                    }
                    
                    for (iChannel = 0; iChannel < pDevice->playback.internalChannels; ++iChannel) {
                        ppDeinterleavedBuffers[iChannel] = (void*)ma_offset_ptr(pBufferList->mBuffers[iBuffer+iChannel].mData, (frameCountPerBuffer - framesRemaining) * ma_get_bytes_per_sample(pDevice->playback.internalFormat));
                    }
                    
                    ma_deinterleave_pcm_frames(pDevice->playback.internalFormat, pDevice->playback.internalChannels, framesToRead, tempBuffer, ppDeinterleavedBuffers);
                    
                    framesRemaining -= framesToRead;
                }
            }
        }
    }
    
    (void)pActionFlags;
    (void)pTimeStamp;
    (void)busNumber;
    (void)frameCount;

    return noErr;
}

static OSStatus ma_on_input__coreaudio(void* pUserData, AudioUnitRenderActionFlags* pActionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pUnusedBufferList)
{
    ma_device* pDevice = (ma_device*)pUserData;
    AudioBufferList* pRenderedBufferList;
    ma_stream_layout layout;
    OSStatus status;

    MA_ASSERT(pDevice != NULL);
    
    pRenderedBufferList = (AudioBufferList*)pDevice->coreaudio.pAudioBufferList;
    MA_ASSERT(pRenderedBufferList);
    
    /* We need to check whether or not we are outputting interleaved or non-interleaved samples. The way we do this is slightly different for each type. */
    layout = ma_stream_layout_interleaved;
    if (pRenderedBufferList->mBuffers[0].mNumberChannels != pDevice->capture.internalChannels) {
        layout = ma_stream_layout_deinterleaved;
    }
    
#if defined(MA_DEBUG_OUTPUT)
    printf("INFO: Input Callback: busNumber=%d, frameCount=%d, mNumberBuffers=%d\n", busNumber, frameCount, pRenderedBufferList->mNumberBuffers);
#endif
    
    status = ((ma_AudioUnitRender_proc)pDevice->pContext->coreaudio.AudioUnitRender)((AudioUnit)pDevice->coreaudio.audioUnitCapture, pActionFlags, pTimeStamp, busNumber, frameCount, pRenderedBufferList);
    if (status != noErr) {
    #if defined(MA_DEBUG_OUTPUT)
        printf("  ERROR: AudioUnitRender() failed with %d\n", status);
    #endif
        return status;
    }
    
    if (layout == ma_stream_layout_interleaved) {
        UInt32 iBuffer;
        for (iBuffer = 0; iBuffer < pRenderedBufferList->mNumberBuffers; ++iBuffer) {
            if (pRenderedBufferList->mBuffers[iBuffer].mNumberChannels == pDevice->capture.internalChannels) {
                if (pDevice->type == ma_device_type_duplex) {
                    ma_device__handle_duplex_callback_capture(pDevice, frameCount, pRenderedBufferList->mBuffers[iBuffer].mData, &pDevice->coreaudio.duplexRB);
                } else {
                    ma_device__send_frames_to_client(pDevice, frameCount, pRenderedBufferList->mBuffers[iBuffer].mData);
                }
            #if defined(MA_DEBUG_OUTPUT)
                printf("  mDataByteSize=%d\n", pRenderedBufferList->mBuffers[iBuffer].mDataByteSize);
            #endif
            } else {
                /*
                This case is where the number of channels in the output buffer do not match our internal channels. It could mean that it's
                not interleaved, in which case we can't handle right now since miniaudio does not yet support non-interleaved streams.
                */
                ma_uint8 silentBuffer[4096];
                ma_uint32 framesRemaining;
                
                MA_ZERO_MEMORY(silentBuffer, sizeof(silentBuffer));
                
                framesRemaining = frameCount;
                while (framesRemaining > 0) {
                    ma_uint32 framesToSend = sizeof(silentBuffer) / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
                    if (framesToSend > framesRemaining) {
                        framesToSend = framesRemaining;
                    }
                    
                    if (pDevice->type == ma_device_type_duplex) {
                        ma_device__handle_duplex_callback_capture(pDevice, framesToSend, silentBuffer, &pDevice->coreaudio.duplexRB);
                    } else {
                        ma_device__send_frames_to_client(pDevice, framesToSend, silentBuffer);
                    }
                    
                    framesRemaining -= framesToSend;
                }
                
            #if defined(MA_DEBUG_OUTPUT)
                printf("  WARNING: Outputting silence. frameCount=%d, mNumberChannels=%d, mDataByteSize=%d\n", frameCount, pRenderedBufferList->mBuffers[iBuffer].mNumberChannels, pRenderedBufferList->mBuffers[iBuffer].mDataByteSize);
            #endif
            }
        }
    } else {
        /* This is the deinterleaved case. We need to interleave the audio data before sending it to the client. This assumes each buffer is the same size. */
        MA_ASSERT(pDevice->capture.internalChannels <= MA_MAX_CHANNELS);    /* This should have been validated at initialization time. */
        
        /*
        For safety we'll check that the internal channels is a multiple of the buffer count. If it's not it means something
        very strange has happened and we're not going to support it.
        */
        if ((pRenderedBufferList->mNumberBuffers % pDevice->capture.internalChannels) == 0) {
            ma_uint8 tempBuffer[4096];
            UInt32 iBuffer;
            for (iBuffer = 0; iBuffer < pRenderedBufferList->mNumberBuffers; iBuffer += pDevice->capture.internalChannels) {
                ma_uint32 framesRemaining = frameCount;
                while (framesRemaining > 0) {
                    void* ppDeinterleavedBuffers[MA_MAX_CHANNELS];
                    ma_uint32 iChannel;
                    ma_uint32 framesToSend = sizeof(tempBuffer) / ma_get_bytes_per_sample(pDevice->capture.internalFormat);
                    if (framesToSend > framesRemaining) {
                        framesToSend = framesRemaining;
                    }
                    
                    for (iChannel = 0; iChannel < pDevice->capture.internalChannels; ++iChannel) {
                        ppDeinterleavedBuffers[iChannel] = (void*)ma_offset_ptr(pRenderedBufferList->mBuffers[iBuffer+iChannel].mData, (frameCount - framesRemaining) * ma_get_bytes_per_sample(pDevice->capture.internalFormat));
                    }
                    
                    ma_interleave_pcm_frames(pDevice->capture.internalFormat, pDevice->capture.internalChannels, framesToSend, (const void**)ppDeinterleavedBuffers, tempBuffer);

                    if (pDevice->type == ma_device_type_duplex) {
                        ma_device__handle_duplex_callback_capture(pDevice, framesToSend, tempBuffer, &pDevice->coreaudio.duplexRB);
                    } else {
                        ma_device__send_frames_to_client(pDevice, framesToSend, tempBuffer);
                    }

                    framesRemaining -= framesToSend;
                }
            }
        }
    }

    (void)pActionFlags;
    (void)pTimeStamp;
    (void)busNumber;
    (void)frameCount;
    (void)pUnusedBufferList;

    return noErr;
}

static void on_start_stop__coreaudio(void* pUserData, AudioUnit audioUnit, AudioUnitPropertyID propertyID, AudioUnitScope scope, AudioUnitElement element)
{
    ma_device* pDevice = (ma_device*)pUserData;
    MA_ASSERT(pDevice != NULL);
    

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

    /* TODO: Figure out how to get the channel map using AVAudioSession. */
    ma_get_standard_channel_map(ma_standard_channel_map_default, pData->channelsOut, pData->channelMapOut);
#endif
    

    /* Buffer size. Not allowing this to be configurable on iOS. */
    actualPeriodSizeInFrames = pData->periodSizeInFramesIn;
    
#if defined(MA_APPLE_DESKTOP)
    if (actualPeriodSizeInFrames == 0) {
        actualPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(pData->periodSizeInMillisecondsIn, pData->sampleRateOut);
    }
    
    result = ma_set_AudioObject_buffer_size_in_frames(pContext, deviceObjectID, deviceType, &actualPeriodSizeInFrames);
    if (result != MA_SUCCESS) {
        return result;
    }
    
    pData->periodSizeInFramesOut = actualPeriodSizeInFrames;
#else
    actualPeriodSizeInFrames = 2048;
    pData->periodSizeInFramesOut = actualPeriodSizeInFrames;
#endif

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

    /* We need a buffer list if this is an input device. We render into this in the input callback. */
    if (deviceType == ma_device_type_capture) {
        ma_bool32 isInterleaved = (bestFormat.mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
        size_t allocationSize;
        AudioBufferList* pBufferList;

        allocationSize = sizeof(AudioBufferList) - sizeof(AudioBuffer);  /* Subtract sizeof(AudioBuffer) because that part is dynamically sized. */
        if (isInterleaved) {
            /* Interleaved case. This is the simple case because we just have one buffer. */
            allocationSize += sizeof(AudioBuffer) * 1;
            allocationSize += actualPeriodSizeInFrames * ma_get_bytes_per_frame(pData->formatOut, pData->channelsOut);
        } else {
            /* Non-interleaved case. This is the more complex case because there's more than one buffer. */
            allocationSize += sizeof(AudioBuffer) * pData->channelsOut;
            allocationSize += actualPeriodSizeInFrames * ma_get_bytes_per_sample(pData->formatOut) * pData->channelsOut;
        }
        
        pBufferList = (AudioBufferList*)ma__malloc_from_callbacks(allocationSize, &pContext->allocationCallbacks);
        if (pBufferList == NULL) {
            ((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
            return MA_OUT_OF_MEMORY;
        }
        
        if (isInterleaved) {
            pBufferList->mNumberBuffers = 1;
            pBufferList->mBuffers[0].mNumberChannels = pData->channelsOut;
            pBufferList->mBuffers[0].mDataByteSize   = actualPeriodSizeInFrames * ma_get_bytes_per_frame(pData->formatOut, pData->channelsOut);
            pBufferList->mBuffers[0].mData           = (ma_uint8*)pBufferList + sizeof(AudioBufferList);
        } else {
            ma_uint32 iBuffer;
            pBufferList->mNumberBuffers = pData->channelsOut;
            for (iBuffer = 0; iBuffer < pBufferList->mNumberBuffers; ++iBuffer) {
                pBufferList->mBuffers[iBuffer].mNumberChannels = 1;
                pBufferList->mBuffers[iBuffer].mDataByteSize   = actualPeriodSizeInFrames * ma_get_bytes_per_sample(pData->formatOut);
                pBufferList->mBuffers[iBuffer].mData           = (ma_uint8*)pBufferList + ((sizeof(AudioBufferList) - sizeof(AudioBuffer)) + (sizeof(AudioBuffer) * pData->channelsOut)) + (actualPeriodSizeInFrames * ma_get_bytes_per_sample(pData->form...
            }
        }

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

    pDevice->coreaudio.originalPeriods                  = pConfig->periods;
    
    /*
    When stopping the device, a callback is called on another thread. We need to wait for this callback
    before returning from ma_device_stop(). This event is used for this.
    */
    ma_event_init(&pDevice->coreaudio.stopEvent);

    /* Need a ring buffer for duplex mode. */
    if (pConfig->deviceType == ma_device_type_duplex) {
        ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_resampling(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalPeriodSizeInFrames * pDevice->capture.internalPeriods);
        ma_result result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->pContext->allocationCallbacks, &pDevice->coreaudio.duplexRB);
        if (result != MA_SUCCESS) {
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[Core Audio] Failed to initialize ring buffer.", result);
        }

        /* We need a period to act as a buffer for cases where the playback and capture device's end up desyncing. */
        {
            ma_uint32 bufferSizeInFrames = rbSizeInFrames / pDevice->capture.internalPeriods;
            void* pBufferData;
            ma_pcm_rb_acquire_write(&pDevice->coreaudio.duplexRB, &bufferSizeInFrames, &pBufferData);
            {
                MA_ZERO_MEMORY(pBufferData, bufferSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels));
            }
            ma_pcm_rb_commit_write(&pDevice->coreaudio.duplexRB, bufferSizeInFrames, pBufferData);
        }
    }

    /*
    We need to detect when a route has changed so we can update the data conversion pipeline accordingly. This is done
    differently on non-Desktop Apple platforms.
    */
#if defined(MA_APPLE_MOBILE)

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

        
        if (!pConfig->coreaudio.noAudioSessionActivate) {
            if (![pAudioSession setActive:true error:nil]) {
                return ma_context_post_error(pContext, NULL, MA_LOG_LEVEL_ERROR, "Failed to activate audio session.", MA_FAILED_TO_INIT_BACKEND);
            }
        }
    }
#endif
    
#if !defined(MA_NO_RUNTIME_LINKING) && !defined(MA_APPLE_MOBILE)
    pContext->coreaudio.hCoreFoundation = ma_dlopen(pContext, "CoreFoundation.framework/CoreFoundation");
    if (pContext->coreaudio.hCoreFoundation == NULL) {
        return MA_API_NOT_FOUND;
    }
    
    pContext->coreaudio.CFStringGetCString = ma_dlsym(pContext, pContext->coreaudio.hCoreFoundation, "CFStringGetCString");
    pContext->coreaudio.CFRelease          = ma_dlsym(pContext, pContext->coreaudio.hCoreFoundation, "CFRelease");
    
    
    pContext->coreaudio.hCoreAudio = ma_dlopen(pContext, "CoreAudio.framework/CoreAudio");
    if (pContext->coreaudio.hCoreAudio == NULL) {
        ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
        return MA_API_NOT_FOUND;
    }
    
    pContext->coreaudio.AudioObjectGetPropertyData        = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyData");
    pContext->coreaudio.AudioObjectGetPropertyDataSize    = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyDataSize");
    pContext->coreaudio.AudioObjectSetPropertyData        = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectSetPropertyData");
    pContext->coreaudio.AudioObjectAddPropertyListener    = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectAddPropertyListener");
    pContext->coreaudio.AudioObjectRemovePropertyListener = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectRemovePropertyListener");

    /*
    It looks like Apple has moved some APIs from AudioUnit into AudioToolbox on more recent versions of macOS. They are still
    defined in AudioUnit, but just in case they decide to remove them from there entirely I'm going to implement a fallback.
    The way it'll work is that it'll first try AudioUnit, and if the required symbols are not present there we'll fall back to
    AudioToolbox.
    */
    pContext->coreaudio.hAudioUnit = ma_dlopen(pContext, "AudioUnit.framework/AudioUnit");
    if (pContext->coreaudio.hAudioUnit == NULL) {
        ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
        ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
        return MA_API_NOT_FOUND;
    }
    
    if (ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentFindNext") == NULL) {
        /* Couldn't find the required symbols in AudioUnit, so fall back to AudioToolbox. */
        ma_dlclose(pContext, pContext->coreaudio.hAudioUnit);
        pContext->coreaudio.hAudioUnit = ma_dlopen(pContext, "AudioToolbox.framework/AudioToolbox");
        if (pContext->coreaudio.hAudioUnit == NULL) {
            ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
            ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
            return MA_API_NOT_FOUND;
        }
    }
    
    pContext->coreaudio.AudioComponentFindNext            = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentFindNext");
    pContext->coreaudio.AudioComponentInstanceDispose     = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentInstanceDispose");
    pContext->coreaudio.AudioComponentInstanceNew         = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentInstanceNew");

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

    if (deviceType == ma_device_type_capture) {
        par.rchan = channels;
    } else {
        par.pchan = channels;
    }

    par.rate = sampleRate;

    internalPeriodSizeInFrames = pConfig->periodSizeInFrames;
    if (internalPeriodSizeInFrames == 0) {
        internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(pConfig->periodSizeInMilliseconds, par.rate);
    }

    par.round    = internalPeriodSizeInFrames;
    par.appbufsz = par.round * pConfig->periods;
    
    if (((ma_sio_setpar_proc)pContext->sndio.sio_setpar)((struct ma_sio_hdl*)handle, &par) == 0) {
        ((ma_sio_close_proc)pContext->sndio.sio_close)((struct ma_sio_hdl*)handle);
        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[sndio] Failed to set buffer size.", MA_FORMAT_NOT_SUPPORTED);
    }
    if (((ma_sio_getpar_proc)pContext->sndio.sio_getpar)((struct ma_sio_hdl*)handle, &par) == 0) {

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

        ((ma_sio_stop_proc)pDevice->pContext->sndio.sio_stop)((struct ma_sio_hdl*)pDevice->sndio.handleCapture);
    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        ((ma_sio_stop_proc)pDevice->pContext->sndio.sio_stop)((struct ma_sio_hdl*)pDevice->sndio.handlePlayback);
    }

    return MA_SUCCESS;
}

static ma_result ma_device_write__sndio(ma_device* pDevice, const void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    int result;

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

    result = ((ma_sio_write_proc)pDevice->pContext->sndio.sio_write)((struct ma_sio_hdl*)pDevice->sndio.handlePlayback, pPCMFrames, frameCount * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
    if (result == 0) {
        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[sndio] Failed to send data from the client to the device.", MA_IO_ERROR);
    }

    if (pFramesWritten != NULL) {
        *pFramesWritten = frameCount;
    }
    
    return MA_SUCCESS;
}

static ma_result ma_device_read__sndio(ma_device* pDevice, void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    int result;

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

    result = ((ma_sio_read_proc)pDevice->pContext->sndio.sio_read)((struct ma_sio_hdl*)pDevice->sndio.handleCapture, pPCMFrames, frameCount * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));
    if (result == 0) {
        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[sndio] Failed to read data from the device to be sent to the device.", MA_IO_ERROR);
    }

    if (pFramesRead != NULL) {
        *pFramesRead = frameCount;
    }
    
    return MA_SUCCESS;
}

static ma_result ma_device_main_loop__sndio(ma_device* pDevice)
{
    ma_result result = MA_SUCCESS;
    ma_bool32 exitLoop = MA_FALSE;

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

        {
            case ma_device_type_duplex:
            {
                /* The process is: device_read -> convert -> callback -> convert -> device_write */
                ma_uint32 totalCapturedDeviceFramesProcessed = 0;
                ma_uint32 capturedDevicePeriodSizeInFrames = ma_min(pDevice->capture.internalPeriodSizeInFrames, pDevice->playback.internalPeriodSizeInFrames);
                    
                while (totalCapturedDeviceFramesProcessed < capturedDevicePeriodSizeInFrames) {
                    ma_uint8  capturedDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint8  playbackDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint32 capturedDeviceDataCapInFrames = sizeof(capturedDeviceData) / ma_get_bytes_per_frame(pDevice->capture.internalFormat,  pDevice->capture.internalChannels);
                    ma_uint32 playbackDeviceDataCapInFrames = sizeof(playbackDeviceData) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                    ma_uint32 capturedDeviceFramesRemaining;
                    ma_uint32 capturedDeviceFramesProcessed;
                    ma_uint32 capturedDeviceFramesToProcess;
                    ma_uint32 capturedDeviceFramesToTryProcessing = capturedDevicePeriodSizeInFrames - totalCapturedDeviceFramesProcessed;
                    if (capturedDeviceFramesToTryProcessing > capturedDeviceDataCapInFrames) {
                        capturedDeviceFramesToTryProcessing = capturedDeviceDataCapInFrames;
                    }

                    result = ma_device_read__sndio(pDevice, capturedDeviceData, capturedDeviceFramesToTryProcessing, &capturedDeviceFramesToProcess);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    capturedDeviceFramesRemaining = capturedDeviceFramesToProcess;
                    capturedDeviceFramesProcessed = 0;

                    for (;;) {
                        ma_uint8  capturedClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint8  playbackClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint32 capturedClientDataCapInFrames = sizeof(capturedClientData) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
                        ma_uint32 playbackClientDataCapInFrames = sizeof(playbackClientData) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
                        ma_uint64 capturedClientFramesToProcessThisIteration = ma_min(capturedClientDataCapInFrames, playbackClientDataCapInFrames);
                        ma_uint64 capturedDeviceFramesToProcessThisIteration = capturedDeviceFramesRemaining;
                        ma_uint8* pRunningCapturedDeviceFrames = ma_offset_ptr(capturedDeviceData, capturedDeviceFramesProcessed * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));

                        /* Convert capture data from device format to client format. */
                        result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningCapturedDeviceFrames, &capturedDeviceFramesToProcessThisIteration, capturedClientData, &capturedClientFramesToProcessThisIteration);
                        if (result != MA_SUCCESS) {
                            break;
                        }

                        /*
                        If we weren't able to generate any output frames it must mean we've exhaused all of our input. The only time this would not be the case is if capturedClientData was too small
                        which should never be the case when it's of the size MA_DATA_CONVERTER_STACK_BUFFER_SIZE.
                        */
                        if (capturedClientFramesToProcessThisIteration == 0) {
                            break;
                        }

                        ma_device__on_data(pDevice, playbackClientData, capturedClientData, (ma_uint32)capturedClientFramesToProcessThisIteration);    /* Safe cast .*/

                        capturedDeviceFramesProcessed += (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */
                        capturedDeviceFramesRemaining -= (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */

                        /* At this point the playbackClientData buffer should be holding data that needs to be written to the device. */
                        for (;;) {
                            ma_uint64 convertedClientFrameCount = capturedClientFramesToProcessThisIteration;
                            ma_uint64 convertedDeviceFrameCount = playbackDeviceDataCapInFrames;
                            result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, playbackClientData, &convertedClientFrameCount, playbackDeviceData, &convertedDeviceFrameCount);
                            if (result != MA_SUCCESS) {
                                break;
                            }

                            result = ma_device_write__sndio(pDevice, playbackDeviceData, (ma_uint32)convertedDeviceFrameCount, NULL);   /* Safe cast. */
                            if (result != MA_SUCCESS) {
                                exitLoop = MA_TRUE;
                                break;
                            }

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

                    }

                    totalCapturedDeviceFramesProcessed += capturedDeviceFramesProcessed;
                }
            } break;

            case ma_device_type_capture:
            {
                /* We read in chunks of the period size, but use a stack allocated buffer for the intermediary. */
                ma_uint8 intermediaryBuffer[8192];
                ma_uint32 intermediaryBufferSizeInFrames = sizeof(intermediaryBuffer) / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
                ma_uint32 periodSizeInFrames = pDevice->capture.internalPeriodSizeInFrames;
                ma_uint32 framesReadThisPeriod = 0;
                while (framesReadThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesReadThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToReadThisIteration = framesRemainingInPeriod;
                    if (framesToReadThisIteration > intermediaryBufferSizeInFrames) {
                        framesToReadThisIteration = intermediaryBufferSizeInFrames;
                    }

                    result = ma_device_read__sndio(pDevice, intermediaryBuffer, framesToReadThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    ma_device__send_frames_to_client(pDevice, framesProcessed, intermediaryBuffer);

                    framesReadThisPeriod += framesProcessed;
                }
            } break;

            case ma_device_type_playback:
            {
                /* We write in chunks of the period size, but use a stack allocated buffer for the intermediary. */
                ma_uint8 intermediaryBuffer[8192];
                ma_uint32 intermediaryBufferSizeInFrames = sizeof(intermediaryBuffer) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                ma_uint32 periodSizeInFrames = pDevice->playback.internalPeriodSizeInFrames;
                ma_uint32 framesWrittenThisPeriod = 0;
                while (framesWrittenThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesWrittenThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToWriteThisIteration = framesRemainingInPeriod;
                    if (framesToWriteThisIteration > intermediaryBufferSizeInFrames) {
                        framesToWriteThisIteration = intermediaryBufferSizeInFrames;
                    }

                    ma_device__read_frames_from_client(pDevice, framesToWriteThisIteration, intermediaryBuffer);

                    result = ma_device_write__sndio(pDevice, intermediaryBuffer, framesToWriteThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    framesWrittenThisPeriod += framesProcessed;
                }
            } break;

            /* To silence a warning. Will never hit this. */
            case ma_device_type_loopback:
            default: break;
        }
    }


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

        close(fd);
        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[audio4] The device's internal device format is not supported by miniaudio. The device is unusable.", MA_FORMAT_NOT_SUPPORTED);
    }

    /* Buffer. */
    {
        ma_uint32 internalPeriodSizeInBytes;

        internalPeriodSizeInFrames = pConfig->periodSizeInFrames;
        if (internalPeriodSizeInFrames == 0) {
            internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(pConfig->periodSizeInMilliseconds, internalSampleRate);
        }

        internalPeriodSizeInBytes = internalPeriodSizeInFrames * ma_get_bytes_per_frame(internalFormat, internalChannels);
        if (internalPeriodSizeInBytes < 16) {
            internalPeriodSizeInBytes = 16;
        }

        internalPeriods = pConfig->periods;
        if (internalPeriods < 2) {
            internalPeriods = 2;
        }

        /* What miniaudio calls a period, audio4 calls a block. */
        AUDIO_INITINFO(&fdInfo);
        fdInfo.hiwat     = internalPeriods;
        fdInfo.lowat     = internalPeriods-1;
        fdInfo.blocksize = internalPeriodSizeInBytes;
        if (ioctl(fd, AUDIO_SETINFO, &fdInfo) < 0) {
            close(fd);
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[audio4] Failed to set internal buffer size. AUDIO_SETINFO failed.", MA_FORMAT_NOT_SUPPORTED);
        }

        internalPeriods            = fdInfo.hiwat;
        internalPeriodSizeInFrames = fdInfo.blocksize / ma_get_bytes_per_frame(internalFormat, internalChannels);
    }
#else
    /* We need to retrieve the format of the device so we can know the channel count and sample rate. Then we can calculate the buffer size. */
    if (ioctl(fd, AUDIO_GETPAR, &fdPar) < 0) {
        close(fd);
        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[audio4] Failed to retrieve initial device parameters.", MA_FORMAT_NOT_SUPPORTED);
    }

    internalFormat     = ma_format_from_swpar__audio4(&fdPar);
    internalChannels   = (deviceType == ma_device_type_capture) ? fdPar.rchan : fdPar.pchan;

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

        close(fd);
        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[audio4] The device's internal device format is not supported by miniaudio. The device is unusable.", MA_FORMAT_NOT_SUPPORTED);
    }

    /* Buffer. */
    {
        ma_uint32 internalPeriodSizeInBytes;

        internalPeriodSizeInFrames = pConfig->periodSizeInFrames;
        if (internalPeriodSizeInFrames == 0) {
            internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(pConfig->periodSizeInMilliseconds, internalSampleRate);
        }

        /* What miniaudio calls a period, audio4 calls a block. */
        internalPeriodSizeInBytes = internalPeriodSizeInFrames * ma_get_bytes_per_frame(internalFormat, internalChannels);
        if (internalPeriodSizeInBytes < 16) {
            internalPeriodSizeInBytes = 16;
        }
    
        fdPar.nblks = pConfig->periods;
        fdPar.round = internalPeriodSizeInBytes;
    
        if (ioctl(fd, AUDIO_SETPAR, &fdPar) < 0) {
            close(fd);
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[audio4] Failed to set device parameters.", MA_FORMAT_NOT_SUPPORTED);

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

        if (ioctl(fd, AUDIO_GETPAR, &fdPar) < 0) {
            close(fd);
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[audio4] Failed to retrieve actual device parameters.", MA_FORMAT_NOT_SUPPORTED);
        }
    }

    internalFormat             = ma_format_from_swpar__audio4(&fdPar);
    internalChannels           = (deviceType == ma_device_type_capture) ? fdPar.rchan : fdPar.pchan;
    internalSampleRate         = fdPar.rate;
    internalPeriods            = fdPar.nblks;
    internalPeriodSizeInFrames = fdPar.round / ma_get_bytes_per_frame(internalFormat, internalChannels);
#endif

    if (internalFormat == ma_format_unknown) {
        close(fd);
        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[audio4] The device's internal device format is not supported by miniaudio. The device is unusable.", MA_FORMAT_NOT_SUPPORTED);
    }

    if (deviceType == ma_device_type_capture) {
        pDevice->audio4.fdCapture                    = fd;
        pDevice->capture.internalFormat              = internalFormat;

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

        /* Here is where the device is stopped immediately. */
        result = ma_device_stop_fd__audio4(pDevice, pDevice->audio4.fdPlayback);
        if (result != MA_SUCCESS) {
            return result;
        }
    }

    return MA_SUCCESS;
}

static ma_result ma_device_write__audio4(ma_device* pDevice, const void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    int result;

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

    result = write(pDevice->audio4.fdPlayback, pPCMFrames, frameCount * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
    if (result < 0) {
        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[audio4] Failed to write data to the device.", ma_result_from_errno(errno));
    }

    if (pFramesWritten != NULL) {
        *pFramesWritten = (ma_uint32)result / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    }

    return MA_SUCCESS;
}

static ma_result ma_device_read__audio4(ma_device* pDevice, void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    int result;

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

    result = read(pDevice->audio4.fdCapture, pPCMFrames, frameCount * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));
    if (result < 0) {
        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[audio4] Failed to read data from the device.", ma_result_from_errno(errno));
    }

    if (pFramesRead != NULL) {
        *pFramesRead = (ma_uint32)result / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
    }

    return MA_SUCCESS;
}

static ma_result ma_device_main_loop__audio4(ma_device* pDevice)
{
    ma_result result = MA_SUCCESS;
    ma_bool32 exitLoop = MA_FALSE;

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

        {
            case ma_device_type_duplex:
            {
                /* The process is: device_read -> convert -> callback -> convert -> device_write */
                ma_uint32 totalCapturedDeviceFramesProcessed = 0;
                ma_uint32 capturedDevicePeriodSizeInFrames = ma_min(pDevice->capture.internalPeriodSizeInFrames, pDevice->playback.internalPeriodSizeInFrames);
                    
                while (totalCapturedDeviceFramesProcessed < capturedDevicePeriodSizeInFrames) {
                    ma_uint8  capturedDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint8  playbackDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint32 capturedDeviceDataCapInFrames = sizeof(capturedDeviceData) / ma_get_bytes_per_frame(pDevice->capture.internalFormat,  pDevice->capture.internalChannels);
                    ma_uint32 playbackDeviceDataCapInFrames = sizeof(playbackDeviceData) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                    ma_uint32 capturedDeviceFramesRemaining;
                    ma_uint32 capturedDeviceFramesProcessed;
                    ma_uint32 capturedDeviceFramesToProcess;
                    ma_uint32 capturedDeviceFramesToTryProcessing = capturedDevicePeriodSizeInFrames - totalCapturedDeviceFramesProcessed;
                    if (capturedDeviceFramesToTryProcessing > capturedDeviceDataCapInFrames) {
                        capturedDeviceFramesToTryProcessing = capturedDeviceDataCapInFrames;
                    }

                    result = ma_device_read__audio4(pDevice, capturedDeviceData, capturedDeviceFramesToTryProcessing, &capturedDeviceFramesToProcess);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    capturedDeviceFramesRemaining = capturedDeviceFramesToProcess;
                    capturedDeviceFramesProcessed = 0;

                    for (;;) {
                        ma_uint8  capturedClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint8  playbackClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint32 capturedClientDataCapInFrames = sizeof(capturedClientData) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
                        ma_uint32 playbackClientDataCapInFrames = sizeof(playbackClientData) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
                        ma_uint64 capturedClientFramesToProcessThisIteration = ma_min(capturedClientDataCapInFrames, playbackClientDataCapInFrames);
                        ma_uint64 capturedDeviceFramesToProcessThisIteration = capturedDeviceFramesRemaining;
                        ma_uint8* pRunningCapturedDeviceFrames = ma_offset_ptr(capturedDeviceData, capturedDeviceFramesProcessed * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));

                        /* Convert capture data from device format to client format. */
                        result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningCapturedDeviceFrames, &capturedDeviceFramesToProcessThisIteration, capturedClientData, &capturedClientFramesToProcessThisIteration);
                        if (result != MA_SUCCESS) {
                            break;
                        }

                        /*
                        If we weren't able to generate any output frames it must mean we've exhaused all of our input. The only time this would not be the case is if capturedClientData was too small
                        which should never be the case when it's of the size MA_DATA_CONVERTER_STACK_BUFFER_SIZE.
                        */
                        if (capturedClientFramesToProcessThisIteration == 0) {
                            break;
                        }

                        ma_device__on_data(pDevice, playbackClientData, capturedClientData, (ma_uint32)capturedClientFramesToProcessThisIteration);    /* Safe cast .*/

                        capturedDeviceFramesProcessed += (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */
                        capturedDeviceFramesRemaining -= (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */

                        /* At this point the playbackClientData buffer should be holding data that needs to be written to the device. */
                        for (;;) {
                            ma_uint64 convertedClientFrameCount = capturedClientFramesToProcessThisIteration;
                            ma_uint64 convertedDeviceFrameCount = playbackDeviceDataCapInFrames;
                            result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, playbackClientData, &convertedClientFrameCount, playbackDeviceData, &convertedDeviceFrameCount);
                            if (result != MA_SUCCESS) {
                                break;
                            }

                            result = ma_device_write__audio4(pDevice, playbackDeviceData, (ma_uint32)convertedDeviceFrameCount, NULL);  /* Safe cast. */
                            if (result != MA_SUCCESS) {
                                exitLoop = MA_TRUE;
                                break;
                            }

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

                    }

                    totalCapturedDeviceFramesProcessed += capturedDeviceFramesProcessed;
                }
            } break;

            case ma_device_type_capture:
            {
                /* We read in chunks of the period size, but use a stack allocated buffer for the intermediary. */
                ma_uint8 intermediaryBuffer[8192];
                ma_uint32 intermediaryBufferSizeInFrames = sizeof(intermediaryBuffer) / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
                ma_uint32 periodSizeInFrames = pDevice->capture.internalPeriodSizeInFrames;
                ma_uint32 framesReadThisPeriod = 0;
                while (framesReadThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesReadThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToReadThisIteration = framesRemainingInPeriod;
                    if (framesToReadThisIteration > intermediaryBufferSizeInFrames) {
                        framesToReadThisIteration = intermediaryBufferSizeInFrames;
                    }

                    result = ma_device_read__audio4(pDevice, intermediaryBuffer, framesToReadThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    ma_device__send_frames_to_client(pDevice, framesProcessed, intermediaryBuffer);

                    framesReadThisPeriod += framesProcessed;
                }
            } break;

            case ma_device_type_playback:
            {
                /* We write in chunks of the period size, but use a stack allocated buffer for the intermediary. */
                ma_uint8 intermediaryBuffer[8192];
                ma_uint32 intermediaryBufferSizeInFrames = sizeof(intermediaryBuffer) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                ma_uint32 periodSizeInFrames = pDevice->playback.internalPeriodSizeInFrames;
                ma_uint32 framesWrittenThisPeriod = 0;
                while (framesWrittenThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesWrittenThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToWriteThisIteration = framesRemainingInPeriod;
                    if (framesToWriteThisIteration > intermediaryBufferSizeInFrames) {
                        framesToWriteThisIteration = intermediaryBufferSizeInFrames;
                    }

                    ma_device__read_frames_from_client(pDevice, framesToWriteThisIteration, intermediaryBuffer);

                    result = ma_device_write__audio4(pDevice, intermediaryBuffer, framesToWriteThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    framesWrittenThisPeriod += framesProcessed;
                }
            } break;

            /* To silence a warning. Will never hit this. */
            case ma_device_type_loopback:
            default: break;
        }
    }


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

    OSS wants the fragment size in bytes and a power of 2. When setting, we specify the power, not the actual
    value.
    */
    {
        ma_uint32 periodSizeInFrames;
        ma_uint32 periodSizeInBytes;
        ma_uint32 ossFragmentSizePower;
        
        periodSizeInFrames = pConfig->periodSizeInFrames;
        if (periodSizeInFrames == 0) {
            periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(pConfig->periodSizeInMilliseconds, (ma_uint32)ossSampleRate);
        }

        periodSizeInBytes = ma_round_to_power_of_2(periodSizeInFrames * ma_get_bytes_per_frame(ma_format_from_oss(ossFormat), ossChannels));
        if (periodSizeInBytes < 16) {
            periodSizeInBytes = 16;
        }

        ossFragmentSizePower = 4;
        periodSizeInBytes >>= 4;
        while (periodSizeInBytes >>= 1) {
            ossFragmentSizePower += 1;
        }

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

    }

    /* Internal settings. */
    if (deviceType == ma_device_type_capture) {
        pDevice->oss.fdCapture                       = fd;
        pDevice->capture.internalFormat              = ma_format_from_oss(ossFormat);
        pDevice->capture.internalChannels            = ossChannels;
        pDevice->capture.internalSampleRate          = ossSampleRate;
        ma_get_standard_channel_map(ma_standard_channel_map_sound4, pDevice->capture.internalChannels, pDevice->capture.internalChannelMap);
        pDevice->capture.internalPeriods             = (ma_uint32)(ossFragment >> 16);
        pDevice->capture.internalPeriodSizeInFrames  = (ma_uint32)(1 << (ossFragment & 0xFFFF)) / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);

        if (pDevice->capture.internalFormat == ma_format_unknown) {
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OSS] The device's internal format is not supported by miniaudio.", MA_FORMAT_NOT_SUPPORTED);
        }
    } else {
        pDevice->oss.fdPlayback                      = fd;
        pDevice->playback.internalFormat             = ma_format_from_oss(ossFormat);
        pDevice->playback.internalChannels           = ossChannels;
        pDevice->playback.internalSampleRate         = ossSampleRate;
        ma_get_standard_channel_map(ma_standard_channel_map_sound4, pDevice->playback.internalChannels, pDevice->playback.internalChannelMap);
        pDevice->playback.internalPeriods            = (ma_uint32)(ossFragment >> 16);
        pDevice->playback.internalPeriodSizeInFrames = (ma_uint32)(1 << (ossFragment & 0xFFFF)) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);

        if (pDevice->playback.internalFormat == ma_format_unknown) {
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OSS] The device's internal format is not supported by miniaudio.", MA_FORMAT_NOT_SUPPORTED);
        }
    }

    return MA_SUCCESS;
}

static ma_result ma_device_init__oss(ma_context* pContext, const ma_device_config* pConfig, ma_device* pDevice)

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) {
        int result = ioctl(pDevice->oss.fdPlayback, SNDCTL_DSP_HALT, 0);
        if (result == -1) {
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OSS] Failed to stop device. SNDCTL_DSP_HALT failed.", ma_result_from_errno(errno));
        }
    }

    return MA_SUCCESS;
}

static ma_result ma_device_write__oss(ma_device* pDevice, const void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    int resultOSS;

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

    resultOSS = write(pDevice->oss.fdPlayback, pPCMFrames, frameCount * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
    if (resultOSS < 0) {
        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OSS] Failed to send data from the client to the device.", ma_result_from_errno(errno));
    }

    if (pFramesWritten != NULL) {
        *pFramesWritten = (ma_uint32)resultOSS / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    }
    
    return MA_SUCCESS;
}

static ma_result ma_device_read__oss(ma_device* pDevice, void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    int resultOSS;

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

    resultOSS = read(pDevice->oss.fdCapture, pPCMFrames, frameCount * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));
    if (resultOSS < 0) {
        return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OSS] Failed to read data from the device to be sent to the client.", ma_result_from_errno(errno));
    }
    
    if (pFramesRead != NULL) {
        *pFramesRead = (ma_uint32)resultOSS / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
    }

    return MA_SUCCESS;
}

static ma_result ma_device_main_loop__oss(ma_device* pDevice)
{
    ma_result result = MA_SUCCESS;
    ma_bool32 exitLoop = MA_FALSE;

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

        {
            case ma_device_type_duplex:
            {
                /* The process is: device_read -> convert -> callback -> convert -> device_write */
                ma_uint32 totalCapturedDeviceFramesProcessed = 0;
                ma_uint32 capturedDevicePeriodSizeInFrames = ma_min(pDevice->capture.internalPeriodSizeInFrames, pDevice->playback.internalPeriodSizeInFrames);
                    
                while (totalCapturedDeviceFramesProcessed < capturedDevicePeriodSizeInFrames) {
                    ma_uint8  capturedDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint8  playbackDeviceData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint32 capturedDeviceDataCapInFrames = sizeof(capturedDeviceData) / ma_get_bytes_per_frame(pDevice->capture.internalFormat,  pDevice->capture.internalChannels);
                    ma_uint32 playbackDeviceDataCapInFrames = sizeof(playbackDeviceData) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                    ma_uint32 capturedDeviceFramesRemaining;
                    ma_uint32 capturedDeviceFramesProcessed;
                    ma_uint32 capturedDeviceFramesToProcess;
                    ma_uint32 capturedDeviceFramesToTryProcessing = capturedDevicePeriodSizeInFrames - totalCapturedDeviceFramesProcessed;
                    if (capturedDeviceFramesToTryProcessing > capturedDeviceDataCapInFrames) {
                        capturedDeviceFramesToTryProcessing = capturedDeviceDataCapInFrames;
                    }

                    result = ma_device_read__oss(pDevice, capturedDeviceData, capturedDeviceFramesToTryProcessing, &capturedDeviceFramesToProcess);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    capturedDeviceFramesRemaining = capturedDeviceFramesToProcess;
                    capturedDeviceFramesProcessed = 0;

                    for (;;) {
                        ma_uint8  capturedClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint8  playbackClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint32 capturedClientDataCapInFrames = sizeof(capturedClientData) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
                        ma_uint32 playbackClientDataCapInFrames = sizeof(playbackClientData) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
                        ma_uint64 capturedClientFramesToProcessThisIteration = ma_min(capturedClientDataCapInFrames, playbackClientDataCapInFrames);
                        ma_uint64 capturedDeviceFramesToProcessThisIteration = capturedDeviceFramesRemaining;
                        ma_uint8* pRunningCapturedDeviceFrames = ma_offset_ptr(capturedDeviceData, capturedDeviceFramesProcessed * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));

                        /* Convert capture data from device format to client format. */
                        result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningCapturedDeviceFrames, &capturedDeviceFramesToProcessThisIteration, capturedClientData, &capturedClientFramesToProcessThisIteration);
                        if (result != MA_SUCCESS) {
                            break;
                        }

                        /*
                        If we weren't able to generate any output frames it must mean we've exhaused all of our input. The only time this would not be the case is if capturedClientData was too small
                        which should never be the case when it's of the size MA_DATA_CONVERTER_STACK_BUFFER_SIZE.
                        */
                        if (capturedClientFramesToProcessThisIteration == 0) {
                            break;
                        }

                        ma_device__on_data(pDevice, playbackClientData, capturedClientData, (ma_uint32)capturedClientFramesToProcessThisIteration);    /* Safe cast .*/

                        capturedDeviceFramesProcessed += (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */
                        capturedDeviceFramesRemaining -= (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */

                        /* At this point the playbackClientData buffer should be holding data that needs to be written to the device. */
                        for (;;) {
                            ma_uint64 convertedClientFrameCount = capturedClientFramesToProcessThisIteration;
                            ma_uint64 convertedDeviceFrameCount = playbackDeviceDataCapInFrames;
                            result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, playbackClientData, &convertedClientFrameCount, playbackDeviceData, &convertedDeviceFrameCount);
                            if (result != MA_SUCCESS) {
                                break;
                            }

                            result = ma_device_write__oss(pDevice, playbackDeviceData, (ma_uint32)convertedDeviceFrameCount, NULL); /* Safe cast. */
                            if (result != MA_SUCCESS) {
                                exitLoop = MA_TRUE;
                                break;
                            }

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

                    }

                    totalCapturedDeviceFramesProcessed += capturedDeviceFramesProcessed;
                }
            } break;

            case ma_device_type_capture:
            {
                /* We read in chunks of the period size, but use a stack allocated buffer for the intermediary. */
                ma_uint8 intermediaryBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                ma_uint32 intermediaryBufferSizeInFrames = sizeof(intermediaryBuffer) / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
                ma_uint32 periodSizeInFrames = pDevice->capture.internalPeriodSizeInFrames;
                ma_uint32 framesReadThisPeriod = 0;
                while (framesReadThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesReadThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToReadThisIteration = framesRemainingInPeriod;
                    if (framesToReadThisIteration > intermediaryBufferSizeInFrames) {
                        framesToReadThisIteration = intermediaryBufferSizeInFrames;
                    }

                    result = ma_device_read__oss(pDevice, intermediaryBuffer, framesToReadThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    ma_device__send_frames_to_client(pDevice, framesProcessed, intermediaryBuffer);

                    framesReadThisPeriod += framesProcessed;
                }
            } break;

            case ma_device_type_playback:
            {
                /* We write in chunks of the period size, but use a stack allocated buffer for the intermediary. */
                ma_uint8 intermediaryBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                ma_uint32 intermediaryBufferSizeInFrames = sizeof(intermediaryBuffer) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                ma_uint32 periodSizeInFrames = pDevice->playback.internalPeriodSizeInFrames;
                ma_uint32 framesWrittenThisPeriod = 0;
                while (framesWrittenThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesWrittenThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToWriteThisIteration = framesRemainingInPeriod;
                    if (framesToWriteThisIteration > intermediaryBufferSizeInFrames) {
                        framesToWriteThisIteration = intermediaryBufferSizeInFrames;
                    }

                    ma_device__read_frames_from_client(pDevice, framesToWriteThisIteration, intermediaryBuffer);

                    result = ma_device_write__oss(pDevice, intermediaryBuffer, framesToWriteThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    framesWrittenThisPeriod += framesProcessed;
                }
            } break;

            /* To silence a warning. Will never hit this. */
            case ma_device_type_loopback:
            default: break;
        }
    }


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

    From the documentation for AAudio, when a device is disconnected all we can do is stop it. However, we cannot stop it from the callback - we need
    to do it from another thread. Therefore we are going to use an event thread for the AAudio backend to do this cleanly and safely.
    */
    if (((MA_PFN_AAudioStream_getState)pDevice->pContext->aaudio.AAudioStream_getState)(pStream) == MA_AAUDIO_STREAM_STATE_DISCONNECTED) {
#if defined(MA_DEBUG_OUTPUT)
        printf("[AAudio] Device Disconnected.\n");
#endif
    }
}

static ma_aaudio_data_callback_result_t ma_stream_data_callback_capture__aaudio(ma_AAudioStream* pStream, void* pUserData, void* pAudioData, int32_t frameCount)
{
    ma_device* pDevice = (ma_device*)pUserData;
    MA_ASSERT(pDevice != NULL);

    if (pDevice->type == ma_device_type_duplex) {
        ma_device__handle_duplex_callback_capture(pDevice, frameCount, pAudioData, &pDevice->aaudio.duplexRB);
    } else {
        ma_device__send_frames_to_client(pDevice, frameCount, pAudioData);     /* Send directly to the client. */
    }

    (void)pStream;
    return MA_AAUDIO_CALLBACK_RESULT_CONTINUE;
}

static ma_aaudio_data_callback_result_t ma_stream_data_callback_playback__aaudio(ma_AAudioStream* pStream, void* pUserData, void* pAudioData, int32_t frameCount)
{
    ma_device* pDevice = (ma_device*)pUserData;
    MA_ASSERT(pDevice != NULL);

    if (pDevice->type == ma_device_type_duplex) {
        ma_device__handle_duplex_callback_playback(pDevice, frameCount, pAudioData, &pDevice->aaudio.duplexRB);
    } else {
        ma_device__read_frames_from_client(pDevice, frameCount, pAudioData);   /* Read directly from the client. */
    }

    (void)pStream;
    return MA_AAUDIO_CALLBACK_RESULT_CONTINUE;
}

static ma_result ma_open_stream__aaudio(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_share_mode shareMode, const ma_device_config* pConfig, const ma_device* pDevice, ma_AAudioStream** ppStream)
{
    ma_AAudioStreamBuilder* pBuilder;
    ma_aaudio_result_t resultAA;

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

            if (pDevice == NULL || !pDevice->playback.usingDefaultChannels) {
                ((MA_PFN_AAudioStreamBuilder_setChannelCount)pContext->aaudio.AAudioStreamBuilder_setChannelCount)(pBuilder, pConfig->playback.channels);
            }
            if (pDevice == NULL || !pDevice->playback.usingDefaultFormat) {
                ((MA_PFN_AAudioStreamBuilder_setFormat)pContext->aaudio.AAudioStreamBuilder_setFormat)(pBuilder, (pConfig->playback.format == ma_format_s16) ? MA_AAUDIO_FORMAT_PCM_I16 : MA_AAUDIO_FORMAT_PCM_FLOAT);
            }
        }

        bufferCapacityInFrames = pConfig->periodSizeInFrames * pConfig->periods;
        if (bufferCapacityInFrames == 0) {
            bufferCapacityInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(pConfig->periodSizeInMilliseconds, pConfig->sampleRate) * pConfig->periods;
        }

        ((MA_PFN_AAudioStreamBuilder_setBufferCapacityInFrames)pContext->aaudio.AAudioStreamBuilder_setBufferCapacityInFrames)(pBuilder, bufferCapacityInFrames);
        ((MA_PFN_AAudioStreamBuilder_setFramesPerDataCallback)pContext->aaudio.AAudioStreamBuilder_setFramesPerDataCallback)(pBuilder, bufferCapacityInFrames / pConfig->periods);

        if (deviceType == ma_device_type_capture) {
            ((MA_PFN_AAudioStreamBuilder_setDataCallback)pContext->aaudio.AAudioStreamBuilder_setDataCallback)(pBuilder, ma_stream_data_callback_capture__aaudio, (void*)pDevice);
        } else {
            ((MA_PFN_AAudioStreamBuilder_setDataCallback)pContext->aaudio.AAudioStreamBuilder_setDataCallback)(pBuilder, ma_stream_data_callback_playback__aaudio, (void*)pDevice);
        }

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


    /* No exclusive mode with AAudio. */
    if (((pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) && pConfig->playback.shareMode == ma_share_mode_exclusive) ||
        ((pConfig->deviceType == ma_device_type_capture  || pConfig->deviceType == ma_device_type_duplex) && pConfig->capture.shareMode  == ma_share_mode_exclusive)) {
        return MA_SHARE_MODE_NOT_SUPPORTED;
    }

    /* We first need to try opening the stream. */
    if (pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) {
        int32_t bufferCapacityInFrames;
        int32_t framesPerDataCallback;

        result = ma_open_stream__aaudio(pContext, ma_device_type_capture, pConfig->capture.pDeviceID, pConfig->capture.shareMode, pConfig, pDevice, (ma_AAudioStream**)&pDevice->aaudio.pStreamCapture);
        if (result != MA_SUCCESS) {
            return result;  /* Failed to open the AAudio stream. */
        }

        pDevice->capture.internalFormat     = (((MA_PFN_AAudioStream_getFormat)pContext->aaudio.AAudioStream_getFormat)((ma_AAudioStream*)pDevice->aaudio.pStreamCapture) == MA_AAUDIO_FORMAT_PCM_I16) ? ma_format_s16 : ma_format_f32;
        pDevice->capture.internalChannels   = ((MA_PFN_AAudioStream_getChannelCount)pContext->aaudio.AAudioStream_getChannelCount)((ma_AAudioStream*)pDevice->aaudio.pStreamCapture);
        pDevice->capture.internalSampleRate = ((MA_PFN_AAudioStream_getSampleRate)pContext->aaudio.AAudioStream_getSampleRate)((ma_AAudioStream*)pDevice->aaudio.pStreamCapture);
        ma_get_standard_channel_map(ma_standard_channel_map_default, pDevice->capture.internalChannels, pDevice->capture.internalChannelMap); /* <-- Cannot find info on channel order, so assuming a default. */

        bufferCapacityInFrames = ((MA_PFN_AAudioStream_getBufferCapacityInFrames)pContext->aaudio.AAudioStream_getBufferCapacityInFrames)((ma_AAudioStream*)pDevice->aaudio.pStreamCapture);
        framesPerDataCallback = ((MA_PFN_AAudioStream_getFramesPerDataCallback)pContext->aaudio.AAudioStream_getFramesPerDataCallback)((ma_AAudioStream*)pDevice->aaudio.pStreamCapture);

        if (framesPerDataCallback > 0) {
            pDevice->capture.internalPeriodSizeInFrames = framesPerDataCallback;
            pDevice->capture.internalPeriods            = bufferCapacityInFrames / framesPerDataCallback;
        } else {
            pDevice->capture.internalPeriodSizeInFrames = bufferCapacityInFrames;
            pDevice->capture.internalPeriods            = 1;
        }
    }

    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        int32_t bufferCapacityInFrames;
        int32_t framesPerDataCallback;

        result = ma_open_stream__aaudio(pContext, ma_device_type_playback, pConfig->playback.pDeviceID, pConfig->playback.shareMode, pConfig, pDevice, (ma_AAudioStream**)&pDevice->aaudio.pStreamPlayback);
        if (result != MA_SUCCESS) {
            return result;  /* Failed to open the AAudio stream. */
        }

        pDevice->playback.internalFormat     = (((MA_PFN_AAudioStream_getFormat)pContext->aaudio.AAudioStream_getFormat)((ma_AAudioStream*)pDevice->aaudio.pStreamPlayback) == MA_AAUDIO_FORMAT_PCM_I16) ? ma_format_s16 : ma_format_f32;
        pDevice->playback.internalChannels   = ((MA_PFN_AAudioStream_getChannelCount)pContext->aaudio.AAudioStream_getChannelCount)((ma_AAudioStream*)pDevice->aaudio.pStreamPlayback);
        pDevice->playback.internalSampleRate = ((MA_PFN_AAudioStream_getSampleRate)pContext->aaudio.AAudioStream_getSampleRate)((ma_AAudioStream*)pDevice->aaudio.pStreamPlayback);
        ma_get_standard_channel_map(ma_standard_channel_map_default, pDevice->playback.internalChannels, pDevice->playback.internalChannelMap); /* <-- Cannot find info on channel order, so assuming a default. */

        bufferCapacityInFrames = ((MA_PFN_AAudioStream_getBufferCapacityInFrames)pContext->aaudio.AAudioStream_getBufferCapacityInFrames)((ma_AAudioStream*)pDevice->aaudio.pStreamPlayback);
        framesPerDataCallback = ((MA_PFN_AAudioStream_getFramesPerDataCallback)pContext->aaudio.AAudioStream_getFramesPerDataCallback)((ma_AAudioStream*)pDevice->aaudio.pStreamPlayback);

        if (framesPerDataCallback > 0) {
            pDevice->playback.internalPeriodSizeInFrames = framesPerDataCallback;
            pDevice->playback.internalPeriods            = bufferCapacityInFrames / framesPerDataCallback;
        } else {
            pDevice->playback.internalPeriodSizeInFrames = bufferCapacityInFrames;
            pDevice->playback.internalPeriods            = 1;
        }
    }

    if (pConfig->deviceType == ma_device_type_duplex) {
        ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_resampling(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalPeriodSizeInFrames) * pDevice->capture.internalPeriods;
        ma_result result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->pContext->allocationCallbacks, &pDevice->aaudio.duplexRB);
        if (result != MA_SUCCESS) {
            if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
                ma_close_stream__aaudio(pDevice->pContext, (ma_AAudioStream*)pDevice->aaudio.pStreamCapture);
            }
            if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
                ma_close_stream__aaudio(pDevice->pContext, (ma_AAudioStream*)pDevice->aaudio.pStreamPlayback);
            }
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[AAudio] Failed to initialize ring buffer.", result);
        }

        /* We need a period to act as a buffer for cases where the playback and capture device's end up desyncing. */
        {
            ma_uint32 marginSizeInFrames = rbSizeInFrames / pDevice->capture.internalPeriods;
            void* pMarginData;
            ma_pcm_rb_acquire_write(&pDevice->aaudio.duplexRB, &marginSizeInFrames, &pMarginData);
            {
                MA_ZERO_MEMORY(pMarginData, marginSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels));
            }
            ma_pcm_rb_commit_write(&pDevice->aaudio.duplexRB, marginSizeInFrames, pMarginData);
        }
    }

    return MA_SUCCESS;
}

static ma_result ma_device_start_stream__aaudio(ma_device* pDevice, ma_AAudioStream* pStream)
{

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

    /* Don't do anything if the device is not started. */
    if (pDevice->state != MA_STATE_STARTED) {
        return;
    }

    /* Don't do anything if the device is being drained. */
    if (pDevice->opensl.isDrainingCapture) {
        return;
    }

    periodSizeInBytes = pDevice->capture.internalPeriodSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
    pBuffer = pDevice->opensl.pBufferCapture + (pDevice->opensl.currentBufferIndexCapture * periodSizeInBytes);

    if (pDevice->type == ma_device_type_duplex) {
        ma_device__handle_duplex_callback_capture(pDevice, pDevice->capture.internalPeriodSizeInFrames, pBuffer, &pDevice->opensl.duplexRB);
    } else {
        ma_device__send_frames_to_client(pDevice, pDevice->capture.internalPeriodSizeInFrames, pBuffer);
    }

    resultSL = MA_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueueCapture)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueueCapture, pBuffer, periodSizeInBytes);
    if (resultSL != SL_RESULT_SUCCESS) {
        return;
    }

    pDevice->opensl.currentBufferIndexCapture = (pDevice->opensl.currentBufferIndexCapture + 1) % pDevice->capture.internalPeriods;
}

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

    /* Don't do anything if the device is not started. */
    if (pDevice->state != MA_STATE_STARTED) {
        return;
    }

    /* Don't do anything if the device is being drained. */
    if (pDevice->opensl.isDrainingPlayback) {
        return;
    }

    periodSizeInBytes = pDevice->playback.internalPeriodSizeInFrames * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    pBuffer = pDevice->opensl.pBufferPlayback + (pDevice->opensl.currentBufferIndexPlayback * periodSizeInBytes);

    if (pDevice->type == ma_device_type_duplex) {
        ma_device__handle_duplex_callback_playback(pDevice, pDevice->playback.internalPeriodSizeInFrames, pBuffer, &pDevice->opensl.duplexRB);
    } else {
        ma_device__read_frames_from_client(pDevice, pDevice->playback.internalPeriodSizeInFrames, pBuffer);
    }

    resultSL = MA_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueuePlayback)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueuePlayback, pBuffer, periodSizeInBytes);
    if (resultSL != SL_RESULT_SUCCESS) {
        return;
    }

    pDevice->opensl.currentBufferIndexPlayback = (pDevice->opensl.currentBufferIndexPlayback + 1) % pDevice->playback.internalPeriods;
}
#endif

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

            ma_device_uninit__opensl(pDevice);
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to register buffer queue callback.", ma_result_from_OpenSL(resultSL));
        }

        /* The internal format is determined by the "pcm" object. */
        ma_deconstruct_SLDataFormat_PCM__opensl(&pcm, &pDevice->capture.internalFormat, &pDevice->capture.internalChannels, &pDevice->capture.internalSampleRate, pDevice->capture.internalChannelMap, ma_countof(pDevice->capture.internalChannelMap));

        /* Buffer. */
        periodSizeInFrames = pConfig->periodSizeInFrames;
        if (periodSizeInFrames == 0) {
            periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(pConfig->periodSizeInMilliseconds, pDevice->capture.internalSampleRate);
        }
        pDevice->capture.internalPeriods            = pConfig->periods;
        pDevice->capture.internalPeriodSizeInFrames = periodSizeInFrames;
        pDevice->opensl.currentBufferIndexCapture   = 0;

        bufferSizeInBytes = pDevice->capture.internalPeriodSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels) * pDevice->capture.internalPeriods;
        pDevice->opensl.pBufferCapture = (ma_uint8*)ma__calloc_from_callbacks(bufferSizeInBytes, &pContext->allocationCallbacks);
        if (pDevice->opensl.pBufferCapture == NULL) {
            ma_device_uninit__opensl(pDevice);
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to allocate memory for data buffer.", MA_OUT_OF_MEMORY);
        }
        MA_ZERO_MEMORY(pDevice->opensl.pBufferCapture, bufferSizeInBytes);
    }

    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        ma_SLDataFormat_PCM pcm;

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

            ma_device_uninit__opensl(pDevice);
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to register buffer queue callback.", ma_result_from_OpenSL(resultSL));
        }

        /* The internal format is determined by the "pcm" object. */
        ma_deconstruct_SLDataFormat_PCM__opensl(&pcm, &pDevice->playback.internalFormat, &pDevice->playback.internalChannels, &pDevice->playback.internalSampleRate, pDevice->playback.internalChannelMap, ma_countof(pDevice->playback.internalChannelMap...

        /* Buffer. */
        periodSizeInFrames = pConfig->periodSizeInFrames;
        if (periodSizeInFrames == 0) {
            periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(pConfig->periodSizeInMilliseconds, pDevice->playback.internalSampleRate);
        }
        pDevice->playback.internalPeriods            = pConfig->periods;
        pDevice->playback.internalPeriodSizeInFrames = periodSizeInFrames;
        pDevice->opensl.currentBufferIndexPlayback   = 0;

        bufferSizeInBytes = pDevice->playback.internalPeriodSizeInFrames * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels) * pDevice->playback.internalPeriods;
        pDevice->opensl.pBufferPlayback = (ma_uint8*)ma__calloc_from_callbacks(bufferSizeInBytes, &pContext->allocationCallbacks);
        if (pDevice->opensl.pBufferPlayback == NULL) {
            ma_device_uninit__opensl(pDevice);
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to allocate memory for data buffer.", MA_OUT_OF_MEMORY);
        }
        MA_ZERO_MEMORY(pDevice->opensl.pBufferPlayback, bufferSizeInBytes);
    }

    if (pConfig->deviceType == ma_device_type_duplex) {
        ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_resampling(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalPeriodSizeInFrames) * pDevice->capture.internalPeriods;
        ma_result result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->pContext->allocationCallbacks, &pDevice->opensl.duplexRB);
        if (result != MA_SUCCESS) {
            ma_device_uninit__opensl(pDevice);
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to initialize ring buffer.", result);
        }

        /* We need a period to act as a buffer for cases where the playback and capture device's end up desyncing. */
        {
            ma_uint32 marginSizeInFrames = rbSizeInFrames / pDevice->capture.internalPeriods;
            void* pMarginData;
            ma_pcm_rb_acquire_write(&pDevice->opensl.duplexRB, &marginSizeInFrames, &pMarginData);
            {
                MA_ZERO_MEMORY(pMarginData, marginSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels));
            }
            ma_pcm_rb_commit_write(&pDevice->opensl.duplexRB, marginSizeInFrames, pMarginData);
        }
    }

    return MA_SUCCESS;
#else
    return MA_NO_BACKEND;   /* Non-Android implementations are not supported. */
#endif
}

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

    if (g_maOpenSLInitCounter == 0) {
        return MA_INVALID_OPERATION;
    }

    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        resultSL = MA_OPENSL_RECORD(pDevice->opensl.pAudioRecorder)->SetRecordState((SLRecordItf)pDevice->opensl.pAudioRecorder, SL_RECORDSTATE_RECORDING);
        if (resultSL != SL_RESULT_SUCCESS) {
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to start internal capture device.", ma_result_from_OpenSL(resultSL));
        }

        periodSizeInBytes = pDevice->capture.internalPeriodSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
        for (iPeriod = 0; iPeriod < pDevice->capture.internalPeriods; ++iPeriod) {
            resultSL = MA_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueueCapture)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueueCapture, pDevice->opensl.pBufferCapture + (periodSizeInBytes * iPeriod), periodSizeInBytes);
            if (resultSL != SL_RESULT_SUCCESS) {
                MA_OPENSL_RECORD(pDevice->opensl.pAudioRecorder)->SetRecordState((SLRecordItf)pDevice->opensl.pAudioRecorder, SL_RECORDSTATE_STOPPED);
                return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to enqueue buffer for capture device.", ma_result_from_OpenSL(resultSL));
            }
        }
    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        resultSL = MA_OPENSL_PLAY(pDevice->opensl.pAudioPlayer)->SetPlayState((SLPlayItf)pDevice->opensl.pAudioPlayer, SL_PLAYSTATE_PLAYING);
        if (resultSL != SL_RESULT_SUCCESS) {
            return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to start internal playback device.", ma_result_from_OpenSL(resultSL));
        }

        /* In playback mode (no duplex) we need to load some initial buffers. In duplex mode we need to enqueu silent buffers. */
        if (pDevice->type == ma_device_type_duplex) {
            MA_ZERO_MEMORY(pDevice->opensl.pBufferPlayback, pDevice->playback.internalPeriodSizeInFrames * pDevice->playback.internalPeriods * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
        } else {
            ma_device__read_frames_from_client(pDevice, pDevice->playback.internalPeriodSizeInFrames * pDevice->playback.internalPeriods, pDevice->opensl.pBufferPlayback);
        }

        periodSizeInBytes = pDevice->playback.internalPeriodSizeInFrames * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
        for (iPeriod = 0; iPeriod < pDevice->playback.internalPeriods; ++iPeriod) {
            resultSL = MA_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueuePlayback)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueuePlayback, pDevice->opensl.pBufferPlayback + (periodSizeInBytes * iPeriod), periodSizeInBytes);
            if (resultSL != SL_RESULT_SUCCESS) {
                MA_OPENSL_PLAY(pDevice->opensl.pAudioPlayer)->SetPlayState((SLPlayItf)pDevice->opensl.pAudioPlayer, SL_PLAYSTATE_STOPPED);
                return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to enqueue buffer for playback device.", ma_result_from_OpenSL(resultSL));
            }
        }
    }

    return MA_SUCCESS;

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

static ma_bool32 ma_is_capture_supported__webaudio()
{
    return EM_ASM_INT({
        return (navigator.mediaDevices !== undefined && navigator.mediaDevices.getUserMedia !== undefined);
    }, 0) != 0; /* Must pass in a dummy argument for C99 compatibility. */
}

#ifdef __cplusplus
extern "C" {
#endif
void EMSCRIPTEN_KEEPALIVE ma_device_process_pcm_frames_capture__webaudio(ma_device* pDevice, int frameCount, float* pFrames)
{
    if (pDevice->type == ma_device_type_duplex) {
        ma_device__handle_duplex_callback_capture(pDevice, (ma_uint32)frameCount, pFrames, &pDevice->webaudio.duplexRB);
    } else {
        ma_device__send_frames_to_client(pDevice, (ma_uint32)frameCount, pFrames);    /* Send directly to the client. */
    }
}

void EMSCRIPTEN_KEEPALIVE ma_device_process_pcm_frames_playback__webaudio(ma_device* pDevice, int frameCount, float* pFrames)
{
    if (pDevice->type == ma_device_type_duplex) {
        ma_device__handle_duplex_callback_playback(pDevice, (ma_uint32)frameCount, pFrames, &pDevice->webaudio.duplexRB);
    } else {
        ma_device__read_frames_from_client(pDevice, (ma_uint32)frameCount, pFrames);  /* Read directly from the device. */
    }
}
#ifdef __cplusplus
}
#endif

static ma_bool32 ma_context_is_device_id_equal__webaudio(ma_context* pContext, const ma_device_id* pID0, const ma_device_id* pID1)
{
    MA_ASSERT(pContext != NULL);
    MA_ASSERT(pID0 != NULL);

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


    /*
    Try calculating an appropriate buffer size. There have been reports of the default buffer size being too small on some browsers. If we're using default buffer size, we'll make sure
    the period size is a big biffer than our standard defaults.
    */
    internalPeriodSizeInFrames = pConfig->periodSizeInFrames;
    if (internalPeriodSizeInFrames == 0) {
        ma_uint32 periodSizeInMilliseconds = pConfig->periodSizeInMilliseconds;
        if (pDevice->usingDefaultBufferSize) {
            if (pConfig->performanceProfile == ma_performance_profile_low_latency) {
                periodSizeInMilliseconds = 33;  /* 1 frame @ 30 FPS */
            } else {
                periodSizeInMilliseconds = 333;
            }
        }

        internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(periodSizeInMilliseconds, pConfig->sampleRate);
    }

    /* The size of the buffer must be a power of 2 and between 256 and 16384. */
    if (internalPeriodSizeInFrames < 256) {
        internalPeriodSizeInFrames = 256;
    } else if (internalPeriodSizeInFrames > 16384) {
        internalPeriodSizeInFrames = 16384;
    } else {
        internalPeriodSizeInFrames = ma_next_power_of_2(internalPeriodSizeInFrames);
    }

    /* We create the device on the JavaScript side and reference it using an index. We use this to make it possible to reference the device between JavaScript and C. */
    deviceIndex = EM_ASM_INT({
        var channels   = $0;
        var sampleRate = $1;
        var bufferSize = $2;    /* In PCM frames. */
        var isCapture  = $3;
        var pDevice    = $4;

        if (typeof(miniaudio) === 'undefined') {
            return -1;  /* Context not initialized. */
        }

        var device = {};

        /* The AudioContext must be created in a suspended state. */

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


                /* Sanity check. This will never happen, right? */
                if (e.inputBuffer.numberOfChannels != channels) {
                    console.log("Capture: Channel count mismatch. " + e.inputBufer.numberOfChannels + " != " + channels + ". Sending silence.");
                    sendSilence = true;
                }

                /* This looped design guards against the situation where e.inputBuffer is a different size to the original buffer size. Should never happen in practice. */
                var totalFramesProcessed = 0;
                while (totalFramesProcessed < e.inputBuffer.length) {
                    var framesRemaining = e.inputBuffer.length - totalFramesProcessed;
                    var framesToProcess = framesRemaining;
                    if (framesToProcess > (device.intermediaryBufferSizeInBytes/channels/4)) {
                        framesToProcess = (device.intermediaryBufferSizeInBytes/channels/4);
                    }

                    /* We need to do the reverse of the playback case. We need to interleave the input data and copy it into the intermediary buffer. Then we send it to the client. */
                    if (sendSilence) {
                        device.intermediaryBufferView.fill(0.0);
                    } else {
                        for (var iFrame = 0; iFrame < framesToProcess; ++iFrame) {
                            for (var iChannel = 0; iChannel < e.inputBuffer.numberOfChannels; ++iChannel) {
                                device.intermediaryBufferView[iFrame*channels + iChannel] = e.inputBuffer.getChannelData(iChannel)[totalFramesProcessed + iFrame];
                            }
                        }
                    }

                    /* Send data to the client from our intermediary buffer. */
                    ccall("ma_device_process_pcm_frames_capture__webaudio", "undefined", ["number", "number", "number"], [pDevice, framesToProcess, device.intermediaryBuffer]);

                    totalFramesProcessed += framesToProcess;
                }
            };

            navigator.mediaDevices.getUserMedia({audio:true, video:false})
                .then(function(stream) {
                    device.streamNode = device.webaudio.createMediaStreamSource(stream);
                    device.streamNode.connect(device.scriptNode);
                    device.scriptNode.connect(device.webaudio.destination);
                })
                .catch(function(error) {

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

                /* Sanity check. This will never happen, right? */
                if (e.outputBuffer.numberOfChannels != channels) {
                    console.log("Playback: Channel count mismatch. " + e.outputBufer.numberOfChannels + " != " + channels + ". Outputting silence.");
                    outputSilence = true;
                    return;
                }

                /* This looped design guards against the situation where e.outputBuffer is a different size to the original buffer size. Should never happen in practice. */
                var totalFramesProcessed = 0;
                while (totalFramesProcessed < e.outputBuffer.length) {
                    var framesRemaining = e.outputBuffer.length - totalFramesProcessed;
                    var framesToProcess = framesRemaining;
                    if (framesToProcess > (device.intermediaryBufferSizeInBytes/channels/4)) {
                        framesToProcess = (device.intermediaryBufferSizeInBytes/channels/4);
                    }

                    /* Read data from the client into our intermediary buffer. */
                    ccall("ma_device_process_pcm_frames_playback__webaudio", "undefined", ["number", "number", "number"], [pDevice, framesToProcess, device.intermediaryBuffer]);

                    /* At this point we'll have data in our intermediary buffer which we now need to deinterleave and copy over to the output buffers. */
                    if (outputSilence) {
                        for (var iChannel = 0; iChannel < e.outputBuffer.numberOfChannels; ++iChannel) {
                            e.outputBuffer.getChannelData(iChannel).fill(0.0);
                        }
                    } else {
                        for (var iChannel = 0; iChannel < e.outputBuffer.numberOfChannels; ++iChannel) {
                            for (var iFrame = 0; iFrame < framesToProcess; ++iFrame) {
                                e.outputBuffer.getChannelData(iChannel)[totalFramesProcessed + iFrame] = device.intermediaryBufferView[iFrame*channels + iChannel];
                            }
                        }
                    }

                    totalFramesProcessed += framesToProcess;
                }
            };

            device.scriptNode.connect(device.webaudio.destination);
        }

        return miniaudio.track_device(device);
    }, (deviceType == ma_device_type_capture) ? pConfig->capture.channels : pConfig->playback.channels, pConfig->sampleRate, internalPeriodSizeInFrames, deviceType == ma_device_type_capture, pDevice);

    if (deviceIndex < 0) {

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

            return result;
        }
    }

    /*
    We need a ring buffer for moving data from the capture device to the playback device. The capture callback is the producer
    and the playback callback is the consumer. The buffer needs to be large enough to hold internalPeriodSizeInFrames based on
    the external sample rate.
    */
    if (pConfig->deviceType == ma_device_type_duplex) {
        ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_resampling(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalPeriodSizeInFrames) * 2;
        result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->pContext->allocationCallbacks, &pDevice->webaudio.duplexRB);
        if (result != MA_SUCCESS) {
            if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
                ma_device_uninit_by_index__webaudio(pDevice, ma_device_type_capture, pDevice->webaudio.indexCapture);
            }
            if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
                ma_device_uninit_by_index__webaudio(pDevice, ma_device_type_playback, pDevice->webaudio.indexPlayback);
            }
            return result;
        }

        /* We need a period to act as a buffer for cases where the playback and capture device's end up desyncing. */
        {
            ma_uint32 marginSizeInFrames = rbSizeInFrames / 3;  /* <-- Dividing by 3 because internalPeriods is always set to 1 for WebAudio. */
            void* pMarginData;
            ma_pcm_rb_acquire_write(&pDevice->webaudio.duplexRB, &marginSizeInFrames, &pMarginData);
            {
                MA_ZERO_MEMORY(pMarginData, marginSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels));
            }
            ma_pcm_rb_commit_write(&pDevice->webaudio.duplexRB, marginSizeInFrames, pMarginData);
        }
    }

    return MA_SUCCESS;
}

static ma_result ma_device_start__webaudio(ma_device* pDevice)
{

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

    return MA_SUCCESS;
}
#endif  /* MA_NO_DEVICE_IO */


MA_API ma_uint32 ma_scale_buffer_size(ma_uint32 baseBufferSize, float scale)
{
    return ma_max(1, (ma_uint32)(baseBufferSize*scale));
}

MA_API ma_uint32 ma_calculate_buffer_size_in_milliseconds_from_frames(ma_uint32 bufferSizeInFrames, ma_uint32 sampleRate)
{
    return bufferSizeInFrames / (sampleRate/1000);
}

MA_API ma_uint32 ma_calculate_buffer_size_in_frames_from_milliseconds(ma_uint32 bufferSizeInMilliseconds, ma_uint32 sampleRate)
{
    return bufferSizeInMilliseconds * (sampleRate/1000); 
}

MA_API void ma_copy_pcm_frames(void* dst, const void* src, ma_uint64 frameCount, ma_format format, ma_uint32 channels)
{
    if (dst == src) {
        return; /* No-op. */
    }

    ma_copy_memory_64(dst, src, frameCount * ma_get_bytes_per_frame(format, channels));
}

MA_API void ma_silence_pcm_frames(void* p, ma_uint64 frameCount, ma_format format, ma_uint32 channels)
{
    if (format == ma_format_u8) {
        ma_uint64 sampleCount = frameCount * channels;
        ma_uint64 iSample;
        for (iSample = 0; iSample < sampleCount; iSample += 1) {
            ((ma_uint8*)p)[iSample] = 128;
        }
    } else {
        ma_zero_memory_64(p, frameCount * ma_get_bytes_per_frame(format, channels));
    }
}

MA_API void* ma_offset_pcm_frames_ptr(void* p, ma_uint64 offsetInFrames, ma_format format, ma_uint32 channels)
{
    return ma_offset_ptr(p, offsetInFrames * ma_get_bytes_per_frame(format, channels));
}

MA_API const void* ma_offset_pcm_frames_const_ptr(const void* p, ma_uint64 offsetInFrames, ma_format format, ma_uint32 channels)
{
    return ma_offset_ptr(p, offsetInFrames * ma_get_bytes_per_frame(format, channels));
}


MA_API void ma_clip_samples_f32(float* p, ma_uint64 sampleCount)
{
    ma_uint32 iSample;

    /* TODO: Research a branchless SSE implementation. */
    for (iSample = 0; iSample < sampleCount; iSample += 1) {
        p[iSample] = ma_clip_f32(p[iSample]);

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

MA_API void ma_apply_volume_factor_s32(ma_int32* pSamples, ma_uint64 sampleCount, float factor)
{
    ma_copy_and_apply_volume_factor_s32(pSamples, pSamples, sampleCount, factor);
}

MA_API void ma_apply_volume_factor_f32(float* pSamples, ma_uint64 sampleCount, float factor)
{
    ma_copy_and_apply_volume_factor_f32(pSamples, pSamples, sampleCount, factor);
}

MA_API void ma_copy_and_apply_volume_factor_pcm_frames_u8(ma_uint8* pPCMFramesOut, const ma_uint8* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_u8(pPCMFramesOut, pPCMFramesIn, frameCount*channels, factor);
}

MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s16(ma_int16* pPCMFramesOut, const ma_int16* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_s16(pPCMFramesOut, pPCMFramesIn, frameCount*channels, factor);
}

MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s24(void* pPCMFramesOut, const void* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_s24(pPCMFramesOut, pPCMFramesIn, frameCount*channels, factor);
}

MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s32(ma_int32* pPCMFramesOut, const ma_int32* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_s32(pPCMFramesOut, pPCMFramesIn, frameCount*channels, factor);
}

MA_API void ma_copy_and_apply_volume_factor_pcm_frames_f32(float* pPCMFramesOut, const float* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_f32(pPCMFramesOut, pPCMFramesIn, frameCount*channels, factor);
}

MA_API void ma_copy_and_apply_volume_factor_pcm_frames(void* pPCMFramesOut, const void* pPCMFramesIn, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float factor)
{
    switch (format)
    {
    case ma_format_u8:  ma_copy_and_apply_volume_factor_pcm_frames_u8 ((ma_uint8*)pPCMFramesOut, (const ma_uint8*)pPCMFramesIn, frameCount, channels, factor); return;
    case ma_format_s16: ma_copy_and_apply_volume_factor_pcm_frames_s16((ma_int16*)pPCMFramesOut, (const ma_int16*)pPCMFramesIn, frameCount, channels, factor); return;
    case ma_format_s24: ma_copy_and_apply_volume_factor_pcm_frames_s24(           pPCMFramesOut,                  pPCMFramesIn, frameCount, channels, factor); return;
    case ma_format_s32: ma_copy_and_apply_volume_factor_pcm_frames_s32((ma_int32*)pPCMFramesOut, (const ma_int32*)pPCMFramesIn, frameCount, channels, factor); return;
    case ma_format_f32: ma_copy_and_apply_volume_factor_pcm_frames_f32(   (float*)pPCMFramesOut,    (const float*)pPCMFramesIn, frameCount, channels, factor); return;
    default: return;    /* Do nothing. */
    }
}

MA_API void ma_apply_volume_factor_pcm_frames_u8(ma_uint8* pPCMFrames, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_pcm_frames_u8(pPCMFrames, pPCMFrames, frameCount, channels, factor);
}

MA_API void ma_apply_volume_factor_pcm_frames_s16(ma_int16* pPCMFrames, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_pcm_frames_s16(pPCMFrames, pPCMFrames, frameCount, channels, factor);
}

MA_API void ma_apply_volume_factor_pcm_frames_s24(void* pPCMFrames, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_pcm_frames_s24(pPCMFrames, pPCMFrames, frameCount, channels, factor);
}

MA_API void ma_apply_volume_factor_pcm_frames_s32(ma_int32* pPCMFrames, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_pcm_frames_s32(pPCMFrames, pPCMFrames, frameCount, channels, factor);
}

MA_API void ma_apply_volume_factor_pcm_frames_f32(float* pPCMFrames, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_pcm_frames_f32(pPCMFrames, pPCMFrames, frameCount, channels, factor);
}

MA_API void ma_apply_volume_factor_pcm_frames(void* pPCMFrames, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_pcm_frames(pPCMFrames, pPCMFrames, frameCount, format, channels, factor);
}


MA_API float ma_factor_to_gain_db(float factor)
{
    return (float)(20*ma_log10f(factor));
}

MA_API float ma_gain_db_to_factor(float gain)
{

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

        } else
    #endif
        {
            ma_pcm_u8_to_f32__optimized(dst, src, count, ditherMode);
        }
#endif
}


#ifdef MA_USE_REFERENCE_CONVERSION_APIS
static MA_INLINE void ma_pcm_interleave_u8__reference(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_uint8* dst_u8 = (ma_uint8*)dst;
    const ma_uint8** src_u8 = (const ma_uint8**)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_u8[iFrame*channels + iChannel] = src_u8[iChannel][iFrame];
        }
    }
}
#else
static MA_INLINE void ma_pcm_interleave_u8__optimized(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_uint8* dst_u8 = (ma_uint8*)dst;
    const ma_uint8** src_u8 = (const ma_uint8**)src;

    if (channels == 1) {
        ma_copy_memory_64(dst, src[0], frameCount * sizeof(ma_uint8));
    } else if (channels == 2) {
        ma_uint64 iFrame;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            dst_u8[iFrame*2 + 0] = src_u8[0][iFrame];
            dst_u8[iFrame*2 + 1] = src_u8[1][iFrame];
        }
    } else {
        ma_uint64 iFrame;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            ma_uint32 iChannel;
            for (iChannel = 0; iChannel < channels; iChannel += 1) {
                dst_u8[iFrame*channels + iChannel] = src_u8[iChannel][iFrame];
            }
        }
    }
}
#endif

MA_API void ma_pcm_interleave_u8(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_interleave_u8__reference(dst, src, frameCount, channels);
#else
    ma_pcm_interleave_u8__optimized(dst, src, frameCount, channels);
#endif
}


static MA_INLINE void ma_pcm_deinterleave_u8__reference(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_uint8** dst_u8 = (ma_uint8**)dst;
    const ma_uint8* src_u8 = (const ma_uint8*)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_u8[iChannel][iFrame] = src_u8[iFrame*channels + iChannel];
        }
    }
}

static MA_INLINE void ma_pcm_deinterleave_u8__optimized(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_deinterleave_u8__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_deinterleave_u8(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_deinterleave_u8__reference(dst, src, frameCount, channels);
#else
    ma_pcm_deinterleave_u8__optimized(dst, src, frameCount, channels);
#endif
}


/* s16 */
static MA_INLINE void ma_pcm_s16_to_u8__reference(void* dst, const void* src, ma_uint64 count, ma_dither_mode ditherMode)
{
    ma_uint8* dst_u8 = (ma_uint8*)dst;
    const ma_int16* src_s16 = (const ma_int16*)src;

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

            ma_pcm_s16_to_f32__neon(dst, src, count, ditherMode);
        } else
    #endif
        {
            ma_pcm_s16_to_f32__optimized(dst, src, count, ditherMode);
        }
#endif
}


static MA_INLINE void ma_pcm_interleave_s16__reference(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_int16* dst_s16 = (ma_int16*)dst;
    const ma_int16** src_s16 = (const ma_int16**)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_s16[iFrame*channels + iChannel] = src_s16[iChannel][iFrame];
        }
    }
}

static MA_INLINE void ma_pcm_interleave_s16__optimized(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_interleave_s16__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_interleave_s16(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_interleave_s16__reference(dst, src, frameCount, channels);
#else
    ma_pcm_interleave_s16__optimized(dst, src, frameCount, channels);
#endif
}


static MA_INLINE void ma_pcm_deinterleave_s16__reference(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_int16** dst_s16 = (ma_int16**)dst;
    const ma_int16* src_s16 = (const ma_int16*)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_s16[iChannel][iFrame] = src_s16[iFrame*channels + iChannel];
        }
    }
}

static MA_INLINE void ma_pcm_deinterleave_s16__optimized(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_deinterleave_s16__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_deinterleave_s16(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_deinterleave_s16__reference(dst, src, frameCount, channels);
#else
    ma_pcm_deinterleave_s16__optimized(dst, src, frameCount, channels);
#endif
}


/* s24 */
static MA_INLINE void ma_pcm_s24_to_u8__reference(void* dst, const void* src, ma_uint64 count, ma_dither_mode ditherMode)
{
    ma_uint8* dst_u8 = (ma_uint8*)dst;
    const ma_uint8* src_s24 = (const ma_uint8*)src;

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

            ma_pcm_s24_to_f32__neon(dst, src, count, ditherMode);
        } else
    #endif
        {
            ma_pcm_s24_to_f32__optimized(dst, src, count, ditherMode);
        }
#endif
}


static MA_INLINE void ma_pcm_interleave_s24__reference(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_uint8* dst8 = (ma_uint8*)dst;
    const ma_uint8** src8 = (const ma_uint8**)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst8[iFrame*3*channels + iChannel*3 + 0] = src8[iChannel][iFrame*3 + 0];
            dst8[iFrame*3*channels + iChannel*3 + 1] = src8[iChannel][iFrame*3 + 1];
            dst8[iFrame*3*channels + iChannel*3 + 2] = src8[iChannel][iFrame*3 + 2];
        }
    }
}

static MA_INLINE void ma_pcm_interleave_s24__optimized(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_interleave_s24__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_interleave_s24(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_interleave_s24__reference(dst, src, frameCount, channels);
#else
    ma_pcm_interleave_s24__optimized(dst, src, frameCount, channels);
#endif
}


static MA_INLINE void ma_pcm_deinterleave_s24__reference(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_uint8** dst8 = (ma_uint8**)dst;
    const ma_uint8* src8 = (const ma_uint8*)src;

    ma_uint32 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst8[iChannel][iFrame*3 + 0] = src8[iFrame*3*channels + iChannel*3 + 0];
            dst8[iChannel][iFrame*3 + 1] = src8[iFrame*3*channels + iChannel*3 + 1];
            dst8[iChannel][iFrame*3 + 2] = src8[iFrame*3*channels + iChannel*3 + 2];
        }
    }
}

static MA_INLINE void ma_pcm_deinterleave_s24__optimized(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_deinterleave_s24__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_deinterleave_s24(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_deinterleave_s24__reference(dst, src, frameCount, channels);
#else
    ma_pcm_deinterleave_s24__optimized(dst, src, frameCount, channels);
#endif
}



/* s32 */
static MA_INLINE void ma_pcm_s32_to_u8__reference(void* dst, const void* src, ma_uint64 count, ma_dither_mode ditherMode)
{
    ma_uint8* dst_u8 = (ma_uint8*)dst;
    const ma_int32* src_s32 = (const ma_int32*)src;

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

            ma_pcm_s32_to_f32__neon(dst, src, count, ditherMode);
        } else
    #endif
        {
            ma_pcm_s32_to_f32__optimized(dst, src, count, ditherMode);
        }
#endif
}


static MA_INLINE void ma_pcm_interleave_s32__reference(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_int32* dst_s32 = (ma_int32*)dst;
    const ma_int32** src_s32 = (const ma_int32**)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_s32[iFrame*channels + iChannel] = src_s32[iChannel][iFrame];
        }
    }
}

static MA_INLINE void ma_pcm_interleave_s32__optimized(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_interleave_s32__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_interleave_s32(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_interleave_s32__reference(dst, src, frameCount, channels);
#else
    ma_pcm_interleave_s32__optimized(dst, src, frameCount, channels);
#endif
}


static MA_INLINE void ma_pcm_deinterleave_s32__reference(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_int32** dst_s32 = (ma_int32**)dst;
    const ma_int32* src_s32 = (const ma_int32*)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_s32[iChannel][iFrame] = src_s32[iFrame*channels + iChannel];
        }
    }
}

static MA_INLINE void ma_pcm_deinterleave_s32__optimized(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_deinterleave_s32__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_deinterleave_s32(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_deinterleave_s32__reference(dst, src, frameCount, channels);
#else
    ma_pcm_deinterleave_s32__optimized(dst, src, frameCount, channels);
#endif
}


/* f32 */
static MA_INLINE void ma_pcm_f32_to_u8__reference(void* dst, const void* src, ma_uint64 count, ma_dither_mode ditherMode)
{
    ma_uint64 i;

    ma_uint8* dst_u8 = (ma_uint8*)dst;

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



MA_API void ma_pcm_f32_to_f32(void* dst, const void* src, ma_uint64 count, ma_dither_mode ditherMode)
{
    (void)ditherMode;

    ma_copy_memory_64(dst, src, count * sizeof(float));
}


static void ma_pcm_interleave_f32__reference(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    float* dst_f32 = (float*)dst;
    const float** src_f32 = (const float**)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_f32[iFrame*channels + iChannel] = src_f32[iChannel][iFrame];
        }
    }
}

static void ma_pcm_interleave_f32__optimized(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_interleave_f32__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_interleave_f32(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_interleave_f32__reference(dst, src, frameCount, channels);
#else
    ma_pcm_interleave_f32__optimized(dst, src, frameCount, channels);
#endif
}


static void ma_pcm_deinterleave_f32__reference(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    float** dst_f32 = (float**)dst;
    const float* src_f32 = (const float*)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_f32[iChannel][iFrame] = src_f32[iFrame*channels + iChannel];
        }
    }
}

static void ma_pcm_deinterleave_f32__optimized(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_deinterleave_f32__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_deinterleave_f32(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_deinterleave_f32__reference(dst, src, frameCount, channels);
#else
    ma_pcm_deinterleave_f32__optimized(dst, src, frameCount, channels);
#endif
}


MA_API void ma_pcm_convert(void* pOut, ma_format formatOut, const void* pIn, ma_format formatIn, ma_uint64 sampleCount, ma_dither_mode ditherMode)
{
    if (formatOut == formatIn) {
        ma_copy_memory_64(pOut, pIn, sampleCount * ma_get_bytes_per_sample(formatOut));
        return;
    }

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

                case ma_format_s24: ma_pcm_f32_to_s24(pOut, pIn, sampleCount, ditherMode); return;
                case ma_format_s32: ma_pcm_f32_to_s32(pOut, pIn, sampleCount, ditherMode); return;
                default: break;
            }
        } break;

        default: break;
    }
}

MA_API void ma_convert_pcm_frames_format(void* pOut, ma_format formatOut, const void* pIn, ma_format formatIn, ma_uint64 frameCount, ma_uint32 channels, ma_dither_mode ditherMode)
{
    ma_pcm_convert(pOut, formatOut, pIn, formatIn, frameCount * channels, ditherMode);
}

MA_API void ma_deinterleave_pcm_frames(ma_format format, ma_uint32 channels, ma_uint64 frameCount, const void* pInterleavedPCMFrames, void** ppDeinterleavedPCMFrames)
{
    if (pInterleavedPCMFrames == NULL || ppDeinterleavedPCMFrames == NULL) {
        return; /* Invalid args. */
    }

    /* For efficiency we do this per format. */
    switch (format) {
        case ma_format_s16:
        {
            const ma_int16* pSrcS16 = (const ma_int16*)pInterleavedPCMFrames;
            ma_uint64 iPCMFrame;
            for (iPCMFrame = 0; iPCMFrame < frameCount; ++iPCMFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < channels; ++iChannel) {
                    ma_int16* pDstS16 = (ma_int16*)ppDeinterleavedPCMFrames[iChannel];
                    pDstS16[iPCMFrame] = pSrcS16[iPCMFrame*channels+iChannel];
                }
            }
        } break;
        
        case ma_format_f32:
        {
            const float* pSrcF32 = (const float*)pInterleavedPCMFrames;
            ma_uint64 iPCMFrame;
            for (iPCMFrame = 0; iPCMFrame < frameCount; ++iPCMFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < channels; ++iChannel) {
                    float* pDstF32 = (float*)ppDeinterleavedPCMFrames[iChannel];
                    pDstF32[iPCMFrame] = pSrcF32[iPCMFrame*channels+iChannel];
                }
            }
        } break;
        
        default:
        {
            ma_uint32 sampleSizeInBytes = ma_get_bytes_per_sample(format);
            ma_uint64 iPCMFrame;
            for (iPCMFrame = 0; iPCMFrame < frameCount; ++iPCMFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < channels; ++iChannel) {
                          void* pDst = ma_offset_ptr(ppDeinterleavedPCMFrames[iChannel], iPCMFrame*sampleSizeInBytes);
                    const void* pSrc = ma_offset_ptr(pInterleavedPCMFrames, (iPCMFrame*channels+iChannel)*sampleSizeInBytes);
                    memcpy(pDst, pSrc, sampleSizeInBytes);
                }
            }
        } break;
    }
}

MA_API void ma_interleave_pcm_frames(ma_format format, ma_uint32 channels, ma_uint64 frameCount, const void** ppDeinterleavedPCMFrames, void* pInterleavedPCMFrames)
{
    switch (format)
    {
        case ma_format_s16:
        {
            ma_int16* pDstS16 = (ma_int16*)pInterleavedPCMFrames;
            ma_uint64 iPCMFrame;
            for (iPCMFrame = 0; iPCMFrame < frameCount; ++iPCMFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < channels; ++iChannel) {
                    const ma_int16* pSrcS16 = (const ma_int16*)ppDeinterleavedPCMFrames[iChannel];
                    pDstS16[iPCMFrame*channels+iChannel] = pSrcS16[iPCMFrame];
                }
            }
        } break;
        
        case ma_format_f32:
        {
            float* pDstF32 = (float*)pInterleavedPCMFrames;
            ma_uint64 iPCMFrame;
            for (iPCMFrame = 0; iPCMFrame < frameCount; ++iPCMFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < channels; ++iChannel) {
                    const float* pSrcF32 = (const float*)ppDeinterleavedPCMFrames[iChannel];
                    pDstF32[iPCMFrame*channels+iChannel] = pSrcF32[iPCMFrame];
                }
            }
        } break;
    
        default:
        {
            ma_uint32 sampleSizeInBytes = ma_get_bytes_per_sample(format);
            ma_uint64 iPCMFrame;
            for (iPCMFrame = 0; iPCMFrame < frameCount; ++iPCMFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < channels; ++iChannel) {
                          void* pDst = ma_offset_ptr(pInterleavedPCMFrames, (iPCMFrame*channels+iChannel)*sampleSizeInBytes);
                    const void* pSrc = ma_offset_ptr(ppDeinterleavedPCMFrames[iChannel], iPCMFrame*sampleSizeInBytes);
                    memcpy(pDst, pSrc, sampleSizeInBytes);
                }
            }
        } break;
    }
}

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

        pBQ->b0.s32 = ma_biquad_float_to_fp(pConfig->b0 / pConfig->a0);
        pBQ->b1.s32 = ma_biquad_float_to_fp(pConfig->b1 / pConfig->a0);
        pBQ->b2.s32 = ma_biquad_float_to_fp(pConfig->b2 / pConfig->a0);
        pBQ->a1.s32 = ma_biquad_float_to_fp(pConfig->a1 / pConfig->a0);
        pBQ->a2.s32 = ma_biquad_float_to_fp(pConfig->a2 / pConfig->a0);
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_biquad_process_pcm_frame_f32__direct_form_2_transposed(ma_biquad* pBQ, float* pY, const float* pX)
{
    ma_uint32 c;
    const float b0 = pBQ->b0.f32;
    const float b1 = pBQ->b1.f32;
    const float b2 = pBQ->b2.f32;
    const float a1 = pBQ->a1.f32;
    const float a2 = pBQ->a2.f32;
    
    for (c = 0; c < pBQ->channels; c += 1) {
        float r1 = pBQ->r1[c].f32;

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

        y  = b0*x        + r1;
        r1 = b1*x - a1*y + r2;
        r2 = b2*x - a2*y;

        pY[c]          = y;
        pBQ->r1[c].f32 = r1;
        pBQ->r2[c].f32 = r2;
    }
}

static MA_INLINE void ma_biquad_process_pcm_frame_f32(ma_biquad* pBQ, float* pY, const float* pX)
{
    ma_biquad_process_pcm_frame_f32__direct_form_2_transposed(pBQ, pY, pX);
}

static MA_INLINE void ma_biquad_process_pcm_frame_s16__direct_form_2_transposed(ma_biquad* pBQ, ma_int16* pY, const ma_int16* pX)
{
    ma_uint32 c;
    const ma_int32 b0 = pBQ->b0.s32;
    const ma_int32 b1 = pBQ->b1.s32;
    const ma_int32 b2 = pBQ->b2.s32;
    const ma_int32 a1 = pBQ->a1.s32;
    const ma_int32 a2 = pBQ->a2.s32;
    
    for (c = 0; c < pBQ->channels; c += 1) {
        ma_int32 r1 = pBQ->r1[c].s32;

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

        y  = (b0*x        + r1) >> MA_BIQUAD_FIXED_POINT_SHIFT;
        r1 = (b1*x - a1*y + r2);
        r2 = (b2*x - a2*y);

        pY[c]          = (ma_int16)ma_clamp(y, -32768, 32767);
        pBQ->r1[c].s32 = r1;
        pBQ->r2[c].s32 = r2;
    }
}

static MA_INLINE void ma_biquad_process_pcm_frame_s16(ma_biquad* pBQ, ma_int16* pY, const ma_int16* pX)
{
    ma_biquad_process_pcm_frame_s16__direct_form_2_transposed(pBQ, pY, pX);
}

MA_API ma_result ma_biquad_process_pcm_frames(ma_biquad* pBQ, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint32 n;

    if (pBQ == NULL || pFramesOut == NULL || pFramesIn == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Note that the logic below needs to support in-place filtering. That is, it must support the case where pFramesOut and pFramesIn are the same. */

    if (pBQ->format == ma_format_f32) {
        /* */ float* pY = (      float*)pFramesOut;
        const float* pX = (const float*)pFramesIn;

        for (n = 0; n < frameCount; n += 1) {
            ma_biquad_process_pcm_frame_f32__direct_form_2_transposed(pBQ, pY, pX);
            pY += pBQ->channels;
            pX += pBQ->channels;
        }
    } else if (pBQ->format == ma_format_s16) {
        /* */ ma_int16* pY = (      ma_int16*)pFramesOut;
        const ma_int16* pX = (const ma_int16*)pFramesIn;

        for (n = 0; n < frameCount; n += 1) {
            ma_biquad_process_pcm_frame_s16__direct_form_2_transposed(pBQ, pY, pX);
            pY += pBQ->channels;
            pX += pBQ->channels;
        }
    } else {
        MA_ASSERT(MA_FALSE);
        return MA_INVALID_ARGS; /* Format not supported. Should never hit this because it's checked in ma_biquad_init() and ma_biquad_reinit(). */
    }

    return MA_SUCCESS;
}

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

    a = ma_exp(-2 * MA_PI_D * pConfig->cutoffFrequency / pConfig->sampleRate);
    if (pConfig->format == ma_format_f32) {
        pLPF->a.f32 = (float)a;
    } else {
        pLPF->a.s32 = ma_biquad_float_to_fp(a);
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_lpf1_process_pcm_frame_f32(ma_lpf1* pLPF, float* pY, const float* pX)
{
    ma_uint32 c;
    const float a = pLPF->a.f32;
    const float b = 1 - a;
    
    for (c = 0; c < pLPF->channels; c += 1) {
        float r1 = pLPF->r1[c].f32;
        float x  = pX[c];
        float y;

        y = b*x + a*r1;

        pY[c]           = y;
        pLPF->r1[c].f32 = y;
    }
}

static MA_INLINE void ma_lpf1_process_pcm_frame_s16(ma_lpf1* pLPF, ma_int16* pY, const ma_int16* pX)
{
    ma_uint32 c;
    const ma_int32 a = pLPF->a.s32;
    const ma_int32 b = ((1 << MA_BIQUAD_FIXED_POINT_SHIFT) - a);
    
    for (c = 0; c < pLPF->channels; c += 1) {
        ma_int32 r1 = pLPF->r1[c].s32;
        ma_int32 x  = pX[c];
        ma_int32 y;

        y = (b*x + a*r1) >> MA_BIQUAD_FIXED_POINT_SHIFT;

        pY[c]           = (ma_int16)y;
        pLPF->r1[c].s32 = (ma_int32)y;
    }
}

MA_API ma_result ma_lpf1_process_pcm_frames(ma_lpf1* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint32 n;

    if (pLPF == NULL || pFramesOut == NULL || pFramesIn == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Note that the logic below needs to support in-place filtering. That is, it must support the case where pFramesOut and pFramesIn are the same. */

    if (pLPF->format == ma_format_f32) {
        /* */ float* pY = (      float*)pFramesOut;
        const float* pX = (const float*)pFramesIn;

        for (n = 0; n < frameCount; n += 1) {
            ma_lpf1_process_pcm_frame_f32(pLPF, pY, pX);
            pY += pLPF->channels;
            pX += pLPF->channels;
        }
    } else if (pLPF->format == ma_format_s16) {
        /* */ ma_int16* pY = (      ma_int16*)pFramesOut;
        const ma_int16* pX = (const ma_int16*)pFramesIn;

        for (n = 0; n < frameCount; n += 1) {
            ma_lpf1_process_pcm_frame_s16(pLPF, pY, pX);
            pY += pLPF->channels;
            pX += pLPF->channels;
        }
    } else {
        MA_ASSERT(MA_FALSE);
        return MA_INVALID_ARGS; /* Format not supported. Should never hit this because it's checked in ma_biquad_init() and ma_biquad_reinit(). */
    }

    return MA_SUCCESS;
}

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


    bqConfig = ma_lpf2__get_biquad_config(pConfig);
    result = ma_biquad_reinit(&bqConfig, &pLPF->bq);
    if (result != MA_SUCCESS) {
        return result;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_lpf2_process_pcm_frame_s16(ma_lpf2* pLPF, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pLPF->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_lpf2_process_pcm_frame_f32(ma_lpf2* pLPF, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pLPF->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_lpf2_process_pcm_frames(ma_lpf2* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pLPF == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pLPF->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_lpf2_get_latency(ma_lpf2* pLPF)
{
    if (pLPF == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pLPF->bq);
}

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

    }

    return ma_lpf_reinit__internal(pConfig, pLPF, /*isNew*/MA_TRUE);
}

MA_API ma_result ma_lpf_reinit(const ma_lpf_config* pConfig, ma_lpf* pLPF)
{
    return ma_lpf_reinit__internal(pConfig, pLPF, /*isNew*/MA_FALSE);
}

static MA_INLINE void ma_lpf_process_pcm_frame_f32(ma_lpf* pLPF, float* pY, const void* pX)
{
    ma_uint32 ilpf1;
    ma_uint32 ilpf2;

    MA_ASSERT(pLPF->format == ma_format_f32);

    MA_COPY_MEMORY(pY, pX, ma_get_bytes_per_frame(pLPF->format, pLPF->channels));

    for (ilpf1 = 0; ilpf1 < pLPF->lpf1Count; ilpf1 += 1) {
        ma_lpf1_process_pcm_frame_f32(&pLPF->lpf1[ilpf1], pY, pY);
    }

    for (ilpf2 = 0; ilpf2 < pLPF->lpf2Count; ilpf2 += 1) {
        ma_lpf2_process_pcm_frame_f32(&pLPF->lpf2[ilpf2], pY, pY);
    }
}

static MA_INLINE void ma_lpf_process_pcm_frame_s16(ma_lpf* pLPF, ma_int16* pY, const ma_int16* pX)
{
    ma_uint32 ilpf1;
    ma_uint32 ilpf2;

    MA_ASSERT(pLPF->format == ma_format_s16);

    MA_COPY_MEMORY(pY, pX, ma_get_bytes_per_frame(pLPF->format, pLPF->channels));

    for (ilpf1 = 0; ilpf1 < pLPF->lpf1Count; ilpf1 += 1) {
        ma_lpf1_process_pcm_frame_s16(&pLPF->lpf1[ilpf1], pY, pY);
    }

    for (ilpf2 = 0; ilpf2 < pLPF->lpf2Count; ilpf2 += 1) {
        ma_lpf2_process_pcm_frame_s16(&pLPF->lpf2[ilpf2], pY, pY);
    }
}

MA_API ma_result ma_lpf_process_pcm_frames(ma_lpf* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_result result;
    ma_uint32 ilpf1;
    ma_uint32 ilpf2;

    if (pLPF == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Faster path for in-place. */
    if (pFramesOut == pFramesIn) {
        for (ilpf1 = 0; ilpf1 < pLPF->lpf1Count; ilpf1 += 1) {
            result = ma_lpf1_process_pcm_frames(&pLPF->lpf1[ilpf1], pFramesOut, pFramesOut, frameCount);
            if (result != MA_SUCCESS) {
                return result;
            }
        }

        for (ilpf2 = 0; ilpf2 < pLPF->lpf2Count; ilpf2 += 1) {
            result = ma_lpf2_process_pcm_frames(&pLPF->lpf2[ilpf2], pFramesOut, pFramesOut, frameCount);
            if (result != MA_SUCCESS) {
                return result;
            }
        }
    }

    /* Slightly slower path for copying. */
    if (pFramesOut != pFramesIn) {
        ma_uint32 iFrame;

        /*  */ if (pLPF->format == ma_format_f32) {
            /* */ float* pFramesOutF32 = (      float*)pFramesOut;
            const float* pFramesInF32  = (const float*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                ma_lpf_process_pcm_frame_f32(pLPF, pFramesOutF32, pFramesInF32);
                pFramesOutF32 += pLPF->channels;
                pFramesInF32  += pLPF->channels;
            }
        } else if (pLPF->format == ma_format_s16) {
            /* */ ma_int16* pFramesOutS16 = (      ma_int16*)pFramesOut;
            const ma_int16* pFramesInS16  = (const ma_int16*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                ma_lpf_process_pcm_frame_s16(pLPF, pFramesOutS16, pFramesInS16);
                pFramesOutS16 += pLPF->channels;
                pFramesInS16  += pLPF->channels;
            }
        } else {
            MA_ASSERT(MA_FALSE);
            return MA_INVALID_OPERATION;    /* Should never hit this. */
        }
    }

    return MA_SUCCESS;

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

    a = ma_exp(-2 * MA_PI_D * pConfig->cutoffFrequency / pConfig->sampleRate);
    if (pConfig->format == ma_format_f32) {
        pHPF->a.f32 = (float)a;
    } else {
        pHPF->a.s32 = ma_biquad_float_to_fp(a);
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_hpf1_process_pcm_frame_f32(ma_hpf1* pHPF, float* pY, const float* pX)
{
    ma_uint32 c;
    const float a = 1 - pHPF->a.f32;
    const float b = 1 - a;
    
    for (c = 0; c < pHPF->channels; c += 1) {
        float r1 = pHPF->r1[c].f32;
        float x  = pX[c];
        float y;

        y = b*x - a*r1;

        pY[c]           = y;
        pHPF->r1[c].f32 = y;
    }
}

static MA_INLINE void ma_hpf1_process_pcm_frame_s16(ma_hpf1* pHPF, ma_int16* pY, const ma_int16* pX)
{
    ma_uint32 c;
    const ma_int32 a = ((1 << MA_BIQUAD_FIXED_POINT_SHIFT) - pHPF->a.s32);
    const ma_int32 b = ((1 << MA_BIQUAD_FIXED_POINT_SHIFT) - a);
    
    for (c = 0; c < pHPF->channels; c += 1) {
        ma_int32 r1 = pHPF->r1[c].s32;
        ma_int32 x  = pX[c];
        ma_int32 y;

        y = (b*x - a*r1) >> MA_BIQUAD_FIXED_POINT_SHIFT;

        pY[c]           = (ma_int16)y;
        pHPF->r1[c].s32 = (ma_int32)y;
    }
}

MA_API ma_result ma_hpf1_process_pcm_frames(ma_hpf1* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint32 n;

    if (pHPF == NULL || pFramesOut == NULL || pFramesIn == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Note that the logic below needs to support in-place filtering. That is, it must support the case where pFramesOut and pFramesIn are the same. */

    if (pHPF->format == ma_format_f32) {
        /* */ float* pY = (      float*)pFramesOut;
        const float* pX = (const float*)pFramesIn;

        for (n = 0; n < frameCount; n += 1) {
            ma_hpf1_process_pcm_frame_f32(pHPF, pY, pX);
            pY += pHPF->channels;
            pX += pHPF->channels;
        }
    } else if (pHPF->format == ma_format_s16) {
        /* */ ma_int16* pY = (      ma_int16*)pFramesOut;
        const ma_int16* pX = (const ma_int16*)pFramesIn;

        for (n = 0; n < frameCount; n += 1) {
            ma_hpf1_process_pcm_frame_s16(pHPF, pY, pX);
            pY += pHPF->channels;
            pX += pHPF->channels;
        }
    } else {
        MA_ASSERT(MA_FALSE);
        return MA_INVALID_ARGS; /* Format not supported. Should never hit this because it's checked in ma_biquad_init() and ma_biquad_reinit(). */
    }

    return MA_SUCCESS;
}

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


    bqConfig = ma_hpf2__get_biquad_config(pConfig);
    result = ma_biquad_reinit(&bqConfig, &pHPF->bq);
    if (result != MA_SUCCESS) {
        return result;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_hpf2_process_pcm_frame_s16(ma_hpf2* pHPF, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pHPF->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_hpf2_process_pcm_frame_f32(ma_hpf2* pHPF, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pHPF->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_hpf2_process_pcm_frames(ma_hpf2* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pHPF == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pHPF->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_hpf2_get_latency(ma_hpf2* pHPF)
{
    if (pHPF == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pHPF->bq);
}

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

    }

    return ma_hpf_reinit__internal(pConfig, pHPF, /*isNew*/MA_TRUE);
}

MA_API ma_result ma_hpf_reinit(const ma_hpf_config* pConfig, ma_hpf* pHPF)
{
    return ma_hpf_reinit__internal(pConfig, pHPF, /*isNew*/MA_FALSE);
}

MA_API ma_result ma_hpf_process_pcm_frames(ma_hpf* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_result result;
    ma_uint32 ihpf1;
    ma_uint32 ihpf2;

    if (pHPF == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Faster path for in-place. */
    if (pFramesOut == pFramesIn) {
        for (ihpf1 = 0; ihpf1 < pHPF->hpf1Count; ihpf1 += 1) {
            result = ma_hpf1_process_pcm_frames(&pHPF->hpf1[ihpf1], pFramesOut, pFramesOut, frameCount);
            if (result != MA_SUCCESS) {
                return result;
            }
        }

        for (ihpf2 = 0; ihpf2 < pHPF->hpf2Count; ihpf2 += 1) {
            result = ma_hpf2_process_pcm_frames(&pHPF->hpf2[ihpf2], pFramesOut, pFramesOut, frameCount);
            if (result != MA_SUCCESS) {
                return result;
            }
        }
    }

    /* Slightly slower path for copying. */
    if (pFramesOut != pFramesIn) {
        ma_uint32 iFrame;

        /*  */ if (pHPF->format == ma_format_f32) {
            /* */ float* pFramesOutF32 = (      float*)pFramesOut;
            const float* pFramesInF32  = (const float*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                MA_COPY_MEMORY(pFramesOutF32, pFramesInF32, ma_get_bytes_per_frame(pHPF->format, pHPF->channels));

                for (ihpf1 = 0; ihpf1 < pHPF->hpf1Count; ihpf1 += 1) {
                    ma_hpf1_process_pcm_frame_f32(&pHPF->hpf1[ihpf1], pFramesOutF32, pFramesOutF32);
                }

                for (ihpf2 = 0; ihpf2 < pHPF->hpf2Count; ihpf2 += 1) {
                    ma_hpf2_process_pcm_frame_f32(&pHPF->hpf2[ihpf2], pFramesOutF32, pFramesOutF32);
                }

                pFramesOutF32 += pHPF->channels;
                pFramesInF32  += pHPF->channels;
            }
        } else if (pHPF->format == ma_format_s16) {
            /* */ ma_int16* pFramesOutS16 = (      ma_int16*)pFramesOut;
            const ma_int16* pFramesInS16  = (const ma_int16*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                MA_COPY_MEMORY(pFramesOutS16, pFramesInS16, ma_get_bytes_per_frame(pHPF->format, pHPF->channels));

                for (ihpf1 = 0; ihpf1 < pHPF->hpf1Count; ihpf1 += 1) {
                    ma_hpf1_process_pcm_frame_s16(&pHPF->hpf1[ihpf1], pFramesOutS16, pFramesOutS16);
                }

                for (ihpf2 = 0; ihpf2 < pHPF->hpf2Count; ihpf2 += 1) {
                    ma_hpf2_process_pcm_frame_s16(&pHPF->hpf2[ihpf2], pFramesOutS16, pFramesOutS16);
                }

                pFramesOutS16 += pHPF->channels;
                pFramesInS16  += pHPF->channels;
            }
        } else {
            MA_ASSERT(MA_FALSE);
            return MA_INVALID_OPERATION;    /* Should never hit this. */
        }
    }

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


    bqConfig = ma_bpf2__get_biquad_config(pConfig);
    result = ma_biquad_reinit(&bqConfig, &pBPF->bq);
    if (result != MA_SUCCESS) {
        return result;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_bpf2_process_pcm_frame_s16(ma_bpf2* pBPF, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pBPF->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_bpf2_process_pcm_frame_f32(ma_bpf2* pBPF, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pBPF->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_bpf2_process_pcm_frames(ma_bpf2* pBPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pBPF == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pBPF->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_bpf2_get_latency(ma_bpf2* pBPF)
{
    if (pBPF == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pBPF->bq);
}

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

    }

    return ma_bpf_reinit__internal(pConfig, pBPF, /*isNew*/MA_TRUE);
}

MA_API ma_result ma_bpf_reinit(const ma_bpf_config* pConfig, ma_bpf* pBPF)
{
    return ma_bpf_reinit__internal(pConfig, pBPF, /*isNew*/MA_FALSE);
}

MA_API ma_result ma_bpf_process_pcm_frames(ma_bpf* pBPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_result result;
    ma_uint32 ibpf2;

    if (pBPF == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Faster path for in-place. */
    if (pFramesOut == pFramesIn) {
        for (ibpf2 = 0; ibpf2 < pBPF->bpf2Count; ibpf2 += 1) {
            result = ma_bpf2_process_pcm_frames(&pBPF->bpf2[ibpf2], pFramesOut, pFramesOut, frameCount);
            if (result != MA_SUCCESS) {
                return result;
            }
        }
    }

    /* Slightly slower path for copying. */
    if (pFramesOut != pFramesIn) {
        ma_uint32 iFrame;

        /*  */ if (pBPF->format == ma_format_f32) {
            /* */ float* pFramesOutF32 = (      float*)pFramesOut;
            const float* pFramesInF32  = (const float*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                MA_COPY_MEMORY(pFramesOutF32, pFramesInF32, ma_get_bytes_per_frame(pBPF->format, pBPF->channels));

                for (ibpf2 = 0; ibpf2 < pBPF->bpf2Count; ibpf2 += 1) {
                    ma_bpf2_process_pcm_frame_f32(&pBPF->bpf2[ibpf2], pFramesOutF32, pFramesOutF32);
                }

                pFramesOutF32 += pBPF->channels;
                pFramesInF32  += pBPF->channels;
            }
        } else if (pBPF->format == ma_format_s16) {
            /* */ ma_int16* pFramesOutS16 = (      ma_int16*)pFramesOut;
            const ma_int16* pFramesInS16  = (const ma_int16*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                MA_COPY_MEMORY(pFramesOutS16, pFramesInS16, ma_get_bytes_per_frame(pBPF->format, pBPF->channels));

                for (ibpf2 = 0; ibpf2 < pBPF->bpf2Count; ibpf2 += 1) {
                    ma_bpf2_process_pcm_frame_s16(&pBPF->bpf2[ibpf2], pFramesOutS16, pFramesOutS16);
                }

                pFramesOutS16 += pBPF->channels;
                pFramesInS16  += pBPF->channels;
            }
        } else {
            MA_ASSERT(MA_FALSE);
            return MA_INVALID_OPERATION;    /* Should never hit this. */
        }
    }

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


    bqConfig = ma_notch2__get_biquad_config(pConfig);
    result = ma_biquad_reinit(&bqConfig, &pFilter->bq);
    if (result != MA_SUCCESS) {
        return result;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_notch2_process_pcm_frame_s16(ma_notch2* pFilter, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pFilter->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_notch2_process_pcm_frame_f32(ma_notch2* pFilter, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pFilter->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_notch2_process_pcm_frames(ma_notch2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pFilter == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pFilter->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_notch2_get_latency(ma_notch2* pFilter)
{
    if (pFilter == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pFilter->bq);
}

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


    bqConfig = ma_peak2__get_biquad_config(pConfig);
    result = ma_biquad_reinit(&bqConfig, &pFilter->bq);
    if (result != MA_SUCCESS) {
        return result;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_peak2_process_pcm_frame_s16(ma_peak2* pFilter, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pFilter->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_peak2_process_pcm_frame_f32(ma_peak2* pFilter, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pFilter->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_peak2_process_pcm_frames(ma_peak2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pFilter == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pFilter->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_peak2_get_latency(ma_peak2* pFilter)
{
    if (pFilter == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pFilter->bq);
}

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


    bqConfig = ma_loshelf2__get_biquad_config(pConfig);
    result = ma_biquad_reinit(&bqConfig, &pFilter->bq);
    if (result != MA_SUCCESS) {
        return result;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_loshelf2_process_pcm_frame_s16(ma_loshelf2* pFilter, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pFilter->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_loshelf2_process_pcm_frame_f32(ma_loshelf2* pFilter, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pFilter->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_loshelf2_process_pcm_frames(ma_loshelf2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pFilter == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pFilter->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_loshelf2_get_latency(ma_loshelf2* pFilter)
{
    if (pFilter == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pFilter->bq);
}

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


    bqConfig = ma_hishelf2__get_biquad_config(pConfig);
    result = ma_biquad_reinit(&bqConfig, &pFilter->bq);
    if (result != MA_SUCCESS) {
        return result;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_hishelf2_process_pcm_frame_s16(ma_hishelf2* pFilter, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pFilter->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_hishelf2_process_pcm_frame_f32(ma_hishelf2* pFilter, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pFilter->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_hishelf2_process_pcm_frames(ma_hishelf2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pFilter == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pFilter->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_hishelf2_get_latency(ma_hishelf2* pFilter)
{
    if (pFilter == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pFilter->bq);
}

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

    if (pResampler->config.lpfOrder > MA_MAX_FILTER_ORDER) {
        return MA_INVALID_ARGS;
    }

    lpfSampleRate      = (ma_uint32)(ma_max(pResampler->config.sampleRateIn, pResampler->config.sampleRateOut));
    lpfCutoffFrequency = (   double)(ma_min(pResampler->config.sampleRateIn, pResampler->config.sampleRateOut) * 0.5 * pResampler->config.lpfNyquistFactor);

    lpfConfig = ma_lpf_config_init(pResampler->config.format, pResampler->config.channels, lpfSampleRate, lpfCutoffFrequency, pResampler->config.lpfOrder);

    /*
    If the resampler is alreay initialized we don't want to do a fresh initialization of the low-pass filter because it will result in the cached frames
    getting cleared. Instead we re-initialize the filter which will maintain any cached frames.
    */
    if (isResamplerAlreadyInitialized) {
        result = ma_lpf_reinit(&lpfConfig, &pResampler->lpf);
    } else {
        result = ma_lpf_init(&lpfConfig, &pResampler->lpf);
    }

    if (result != MA_SUCCESS) {
        return result;
    }

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

    }

    pResampler->config = *pConfig;

    /* Setting the rate will set up the filter and time advances for us. */
    result = ma_linear_resampler_set_rate_internal(pResampler, pConfig->sampleRateIn, pConfig->sampleRateOut, /* isResamplerAlreadyInitialized = */ MA_FALSE);
    if (result != MA_SUCCESS) {
        return result;
    }

    pResampler->inTimeInt  = 1;  /* Set this to one to force an input sample to always be loaded for the first output frame. */
    pResampler->inTimeFrac = 0;

    return MA_SUCCESS;
}

MA_API void ma_linear_resampler_uninit(ma_linear_resampler* pResampler)
{
    if (pResampler == NULL) {
        return;
    }

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


    MA_ASSERT(a <= (1<<shift));

    b = x * ((1<<shift) - a);
    c = y * a;
    r = b + c;
    
    return (ma_int16)(r >> shift);
}

static void ma_linear_resampler_interpolate_frame_s16(ma_linear_resampler* pResampler, ma_int16* pFrameOut)
{
    ma_uint32 c;
    ma_uint32 a;
    const ma_uint32 shift = 12;

    MA_ASSERT(pResampler != NULL);
    MA_ASSERT(pFrameOut  != NULL);

    a = (pResampler->inTimeFrac << shift) / pResampler->config.sampleRateOut;

    for (c = 0; c < pResampler->config.channels; c += 1) {
        ma_int16 s = ma_linear_resampler_mix_s16(pResampler->x0.s16[c], pResampler->x1.s16[c], a, shift);
        pFrameOut[c] = s;
    }
}


static void ma_linear_resampler_interpolate_frame_f32(ma_linear_resampler* pResampler, float* pFrameOut)
{
    ma_uint32 c;
    float a;

    MA_ASSERT(pResampler != NULL);
    MA_ASSERT(pFrameOut  != NULL);

    a = (float)pResampler->inTimeFrac / pResampler->config.sampleRateOut;

    for (c = 0; c < pResampler->config.channels; c += 1) {
        float s = ma_mix_f32_fast(pResampler->x0.f32[c], pResampler->x1.f32[c], a);
        pFrameOut[c] = s;
    }
}

static ma_result ma_linear_resampler_process_pcm_frames_s16_downsample(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    const ma_int16* pFramesInS16;
    /* */ ma_int16* pFramesOutS16;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;

    MA_ASSERT(pResampler     != NULL);
    MA_ASSERT(pFrameCountIn  != NULL);
    MA_ASSERT(pFrameCountOut != NULL);

    pFramesInS16       = (const ma_int16*)pFramesIn;
    pFramesOutS16      = (      ma_int16*)pFramesOut;
    frameCountIn       = *pFrameCountIn;
    frameCountOut      = *pFrameCountOut;
    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    while (framesProcessedOut < frameCountOut) {
        /* Before interpolating we need to load the buffers. When doing this we need to ensure we run every input sample through the filter. */
        while (pResampler->inTimeInt > 0 && frameCountIn > framesProcessedIn) {
            ma_uint32 iChannel;

            if (pFramesInS16 != NULL) {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.s16[iChannel] = pResampler->x1.s16[iChannel];
                    pResampler->x1.s16[iChannel] = pFramesInS16[iChannel];
                }
                pFramesInS16 += pResampler->config.channels;
            } else {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.s16[iChannel] = pResampler->x1.s16[iChannel];
                    pResampler->x1.s16[iChannel] = 0;
                }
            }

            /* Filter. */
            ma_lpf_process_pcm_frame_s16(&pResampler->lpf, pResampler->x1.s16, pResampler->x1.s16);

            framesProcessedIn     += 1;
            pResampler->inTimeInt -= 1;
        }

        if (pResampler->inTimeInt > 0) {
            break;  /* Ran out of input data. */
        }

        /* Getting here means the frames have been loaded and filtered and we can generate the next output frame. */
        if (pFramesOutS16 != NULL) {
            MA_ASSERT(pResampler->inTimeInt == 0);
            ma_linear_resampler_interpolate_frame_s16(pResampler, pFramesOutS16);

            pFramesOutS16 += pResampler->config.channels;
        }

        framesProcessedOut += 1;

        /* Advance time forward. */
        pResampler->inTimeInt  += pResampler->inAdvanceInt;
        pResampler->inTimeFrac += pResampler->inAdvanceFrac;
        if (pResampler->inTimeFrac >= pResampler->config.sampleRateOut) {
            pResampler->inTimeFrac -= pResampler->config.sampleRateOut;
            pResampler->inTimeInt  += 1;
        }
    }

    *pFrameCountIn  = framesProcessedIn;
    *pFrameCountOut = framesProcessedOut;

    return MA_SUCCESS;
}

static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    const ma_int16* pFramesInS16;
    /* */ ma_int16* pFramesOutS16;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;

    MA_ASSERT(pResampler     != NULL);
    MA_ASSERT(pFrameCountIn  != NULL);
    MA_ASSERT(pFrameCountOut != NULL);

    pFramesInS16       = (const ma_int16*)pFramesIn;
    pFramesOutS16      = (      ma_int16*)pFramesOut;
    frameCountIn       = *pFrameCountIn;
    frameCountOut      = *pFrameCountOut;
    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    while (framesProcessedOut < frameCountOut) {
        /* Before interpolating we need to load the buffers. */
        while (pResampler->inTimeInt > 0 && frameCountIn > framesProcessedIn) {
            ma_uint32 iChannel;

            if (pFramesInS16 != NULL) {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.s16[iChannel] = pResampler->x1.s16[iChannel];
                    pResampler->x1.s16[iChannel] = pFramesInS16[iChannel];
                }
                pFramesInS16 += pResampler->config.channels;
            } else {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.s16[iChannel] = pResampler->x1.s16[iChannel];
                    pResampler->x1.s16[iChannel] = 0;
                }
            }

            framesProcessedIn     += 1;
            pResampler->inTimeInt -= 1;
        }

        if (pResampler->inTimeInt > 0) {
            break;  /* Ran out of input data. */
        }

        /* Getting here means the frames have been loaded and we can generate the next output frame. */
        if (pFramesOutS16 != NULL) {
            MA_ASSERT(pResampler->inTimeInt == 0);
            ma_linear_resampler_interpolate_frame_s16(pResampler, pFramesOutS16);

            /* Filter. */
            ma_lpf_process_pcm_frame_s16(&pResampler->lpf, pFramesOutS16, pFramesOutS16);

            pFramesOutS16 += pResampler->config.channels;
        }

        framesProcessedOut += 1;

        /* Advance time forward. */
        pResampler->inTimeInt  += pResampler->inAdvanceInt;
        pResampler->inTimeFrac += pResampler->inAdvanceFrac;
        if (pResampler->inTimeFrac >= pResampler->config.sampleRateOut) {
            pResampler->inTimeFrac -= pResampler->config.sampleRateOut;
            pResampler->inTimeInt  += 1;
        }
    }

    *pFrameCountIn  = framesProcessedIn;
    *pFrameCountOut = framesProcessedOut;

    return MA_SUCCESS;
}

static ma_result ma_linear_resampler_process_pcm_frames_s16(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    MA_ASSERT(pResampler != NULL);

    if (pResampler->config.sampleRateIn > pResampler->config.sampleRateOut) {
        return ma_linear_resampler_process_pcm_frames_s16_downsample(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    } else {
        return ma_linear_resampler_process_pcm_frames_s16_upsample(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    }
}


static ma_result ma_linear_resampler_process_pcm_frames_f32_downsample(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    const float* pFramesInF32;
    /* */ float* pFramesOutF32;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;

    MA_ASSERT(pResampler     != NULL);
    MA_ASSERT(pFrameCountIn  != NULL);
    MA_ASSERT(pFrameCountOut != NULL);

    pFramesInF32       = (const float*)pFramesIn;
    pFramesOutF32      = (      float*)pFramesOut;
    frameCountIn       = *pFrameCountIn;
    frameCountOut      = *pFrameCountOut;
    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    while (framesProcessedOut < frameCountOut) {
        /* Before interpolating we need to load the buffers. When doing this we need to ensure we run every input sample through the filter. */
        while (pResampler->inTimeInt > 0 && frameCountIn > framesProcessedIn) {
            ma_uint32 iChannel;

            if (pFramesInF32 != NULL) {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.f32[iChannel] = pResampler->x1.f32[iChannel];
                    pResampler->x1.f32[iChannel] = pFramesInF32[iChannel];
                }
                pFramesInF32 += pResampler->config.channels;
            } else {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.f32[iChannel] = pResampler->x1.f32[iChannel];
                    pResampler->x1.f32[iChannel] = 0;
                }
            }

            /* Filter. */
            ma_lpf_process_pcm_frame_f32(&pResampler->lpf, pResampler->x1.f32, pResampler->x1.f32);

            framesProcessedIn     += 1;
            pResampler->inTimeInt -= 1;
        }

        if (pResampler->inTimeInt > 0) {
            break;  /* Ran out of input data. */
        }

        /* Getting here means the frames have been loaded and filtered and we can generate the next output frame. */
        if (pFramesOutF32 != NULL) {
            MA_ASSERT(pResampler->inTimeInt == 0);
            ma_linear_resampler_interpolate_frame_f32(pResampler, pFramesOutF32);

            pFramesOutF32 += pResampler->config.channels;
        }

        framesProcessedOut += 1;

        /* Advance time forward. */
        pResampler->inTimeInt  += pResampler->inAdvanceInt;
        pResampler->inTimeFrac += pResampler->inAdvanceFrac;
        if (pResampler->inTimeFrac >= pResampler->config.sampleRateOut) {
            pResampler->inTimeFrac -= pResampler->config.sampleRateOut;
            pResampler->inTimeInt  += 1;
        }
    }

    *pFrameCountIn  = framesProcessedIn;
    *pFrameCountOut = framesProcessedOut;

    return MA_SUCCESS;
}

static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    const float* pFramesInF32;
    /* */ float* pFramesOutF32;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;

    MA_ASSERT(pResampler     != NULL);
    MA_ASSERT(pFrameCountIn  != NULL);
    MA_ASSERT(pFrameCountOut != NULL);

    pFramesInF32       = (const float*)pFramesIn;
    pFramesOutF32      = (      float*)pFramesOut;
    frameCountIn       = *pFrameCountIn;
    frameCountOut      = *pFrameCountOut;
    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    while (framesProcessedOut < frameCountOut) {
        /* Before interpolating we need to load the buffers. */
        while (pResampler->inTimeInt > 0 && frameCountIn > framesProcessedIn) {
            ma_uint32 iChannel;

            if (pFramesInF32 != NULL) {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.f32[iChannel] = pResampler->x1.f32[iChannel];
                    pResampler->x1.f32[iChannel] = pFramesInF32[iChannel];
                }
                pFramesInF32 += pResampler->config.channels;
            } else {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.f32[iChannel] = pResampler->x1.f32[iChannel];
                    pResampler->x1.f32[iChannel] = 0;
                }
            }

            framesProcessedIn     += 1;
            pResampler->inTimeInt -= 1;
        }

        if (pResampler->inTimeInt > 0) {
            break;  /* Ran out of input data. */
        }

        /* Getting here means the frames have been loaded and we can generate the next output frame. */
        if (pFramesOutF32 != NULL) {
            MA_ASSERT(pResampler->inTimeInt == 0);
            ma_linear_resampler_interpolate_frame_f32(pResampler, pFramesOutF32);

            /* Filter. */
            ma_lpf_process_pcm_frame_f32(&pResampler->lpf, pFramesOutF32, pFramesOutF32);

            pFramesOutF32 += pResampler->config.channels;
        }

        framesProcessedOut += 1;

        /* Advance time forward. */
        pResampler->inTimeInt  += pResampler->inAdvanceInt;
        pResampler->inTimeFrac += pResampler->inAdvanceFrac;
        if (pResampler->inTimeFrac >= pResampler->config.sampleRateOut) {
            pResampler->inTimeFrac -= pResampler->config.sampleRateOut;
            pResampler->inTimeInt  += 1;
        }
    }

    *pFrameCountIn  = framesProcessedIn;
    *pFrameCountOut = framesProcessedOut;

    return MA_SUCCESS;
}

static ma_result ma_linear_resampler_process_pcm_frames_f32(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    MA_ASSERT(pResampler != NULL);

    if (pResampler->config.sampleRateIn > pResampler->config.sampleRateOut) {
        return ma_linear_resampler_process_pcm_frames_f32_downsample(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    } else {
        return ma_linear_resampler_process_pcm_frames_f32_upsample(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    }
}


MA_API ma_result ma_linear_resampler_process_pcm_frames(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    if (pResampler == NULL) {
        return MA_INVALID_ARGS;
    }

    /*  */ if (pResampler->config.format == ma_format_s16) {
        return ma_linear_resampler_process_pcm_frames_s16(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    } else if (pResampler->config.format == ma_format_f32) {
        return ma_linear_resampler_process_pcm_frames_f32(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    } else {
        /* Should never get here. Getting here means the format is not supported and you didn't check the return value of ma_linear_resampler_init(). */
        MA_ASSERT(MA_FALSE);
        return MA_INVALID_ARGS;
    }
}


MA_API ma_result ma_linear_resampler_set_rate(ma_linear_resampler* pResampler, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut)
{

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

    if (n == 0) {
        return MA_INVALID_ARGS; /* Ratio too small. */
    }

    MA_ASSERT(n != 0);
    
    return ma_linear_resampler_set_rate(pResampler, n, d);
}


MA_API ma_uint64 ma_linear_resampler_get_required_input_frame_count(ma_linear_resampler* pResampler, ma_uint64 outputFrameCount)
{
    ma_uint64 inputFrameCount;

    if (pResampler == NULL) {
        return 0;
    }

    if (outputFrameCount == 0) {
        return 0;
    }

    /* Any whole input frames are consumed before the first output frame is generated. */
    inputFrameCount = pResampler->inTimeInt;
    outputFrameCount -= 1;

    /* The rest of the output frames can be calculated in constant time. */
    inputFrameCount += outputFrameCount * pResampler->inAdvanceInt;
    inputFrameCount += (pResampler->inTimeFrac + (outputFrameCount * pResampler->inAdvanceFrac)) / pResampler->config.sampleRateOut;

    return inputFrameCount;
}

MA_API ma_uint64 ma_linear_resampler_get_expected_output_frame_count(ma_linear_resampler* pResampler, ma_uint64 inputFrameCount)
{
    ma_uint64 outputFrameCount;
    ma_uint64 preliminaryInputFrameCountFromFrac;
    ma_uint64 preliminaryInputFrameCount;
    
    if (pResampler == NULL) {
        return 0;
    }

    /*
    The first step is to get a preliminary output frame count. This will either be exactly equal to what we need, or less by 1. We need to
    determine how many input frames will be consumed by this value. If it's greater than our original input frame count it means we won't
    be able to generate an extra frame because we will have run out of input data. Otherwise we will have enough input for the generation
    of an extra output frame. This add-by-one logic is necessary due to how the data loading logic works when processing frames.
    */
    outputFrameCount = (inputFrameCount * pResampler->config.sampleRateOut) / pResampler->config.sampleRateIn;

    /*
    We need to determine how many *whole* input frames will have been processed to generate our preliminary output frame count. This is
    used in the logic below to determine whether or not we need to add an extra output frame.
    */
    preliminaryInputFrameCountFromFrac = (pResampler->inTimeFrac + outputFrameCount*pResampler->inAdvanceFrac) / pResampler->config.sampleRateOut;
    preliminaryInputFrameCount         = (pResampler->inTimeInt  + outputFrameCount*pResampler->inAdvanceInt ) + preliminaryInputFrameCountFromFrac;

    /*
    If the total number of *whole* input frames that would be required to generate our preliminary output frame count is greather than
    the amount of whole input frames we have available as input we need to *not* add an extra output frame as there won't be enough data
    to actually process. Otherwise we need to add the extra output frame.
    */
    if (preliminaryInputFrameCount <= inputFrameCount) {
        outputFrameCount += 1;
    }

    return outputFrameCount;
}

MA_API ma_uint64 ma_linear_resampler_get_input_latency(ma_linear_resampler* pResampler)
{

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

        ma_linear_resampler_uninit(&pResampler->state.linear);
    }

#if defined(MA_HAS_SPEEX_RESAMPLER)
    if (pResampler->config.algorithm == ma_resample_algorithm_speex) {
        speex_resampler_destroy((SpeexResamplerState*)pResampler->state.speex.pSpeexResamplerState);
    }
#endif
}

static ma_result ma_resampler_process_pcm_frames__read__linear(ma_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    return ma_linear_resampler_process_pcm_frames(&pResampler->state.linear, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
}

#if defined(MA_HAS_SPEEX_RESAMPLER)
static ma_result ma_resampler_process_pcm_frames__read__speex(ma_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    int speexErr;
    ma_uint64 frameCountOut;
    ma_uint64 frameCountIn;
    ma_uint64 framesProcessedOut;
    ma_uint64 framesProcessedIn;
    unsigned int framesPerIteration = UINT_MAX;

    MA_ASSERT(pResampler     != NULL);
    MA_ASSERT(pFramesOut     != NULL);
    MA_ASSERT(pFrameCountOut != NULL);
    MA_ASSERT(pFrameCountIn  != NULL);

    /*
    Reading from the Speex resampler requires a bit of dancing around for a few reasons. The first thing is that it's frame counts
    are in unsigned int's whereas ours is in ma_uint64. We therefore need to run the conversion in a loop. The other, more complicated
    problem, is that we need to keep track of the input time, similar to what we do with the linear resampler. The reason we need to
    do this is for ma_resampler_get_required_input_frame_count() and ma_resampler_get_expected_output_frame_count().
    */
    frameCountOut      = *pFrameCountOut;
    frameCountIn       = *pFrameCountIn;
    framesProcessedOut = 0;
    framesProcessedIn  = 0;

    while (framesProcessedOut < frameCountOut && framesProcessedIn < frameCountIn) {
        unsigned int frameCountInThisIteration;
        unsigned int frameCountOutThisIteration;
        const void* pFramesInThisIteration;
        void* pFramesOutThisIteration;

        frameCountInThisIteration = framesPerIteration;
        if ((ma_uint64)frameCountInThisIteration > (frameCountIn - framesProcessedIn)) {
            frameCountInThisIteration = (unsigned int)(frameCountIn - framesProcessedIn);
        }

        frameCountOutThisIteration = framesPerIteration;
        if ((ma_uint64)frameCountOutThisIteration > (frameCountOut - framesProcessedOut)) {
            frameCountOutThisIteration = (unsigned int)(frameCountOut - framesProcessedOut);
        }

        pFramesInThisIteration  = ma_offset_ptr(pFramesIn,  framesProcessedIn  * ma_get_bytes_per_frame(pResampler->config.format, pResampler->config.channels));
        pFramesOutThisIteration = ma_offset_ptr(pFramesOut, framesProcessedOut * ma_get_bytes_per_frame(pResampler->config.format, pResampler->config.channels));

        if (pResampler->config.format == ma_format_f32) {
            speexErr = speex_resampler_process_interleaved_float((SpeexResamplerState*)pResampler->state.speex.pSpeexResamplerState, (const float*)pFramesInThisIteration, &frameCountInThisIteration, (float*)pFramesOutThisIteration, &frameCountOutThis...
        } else if (pResampler->config.format == ma_format_s16) {
            speexErr = speex_resampler_process_interleaved_int((SpeexResamplerState*)pResampler->state.speex.pSpeexResamplerState, (const spx_int16_t*)pFramesInThisIteration, &frameCountInThisIteration, (spx_int16_t*)pFramesOutThisIteration, &frameCo...
        } else {
            /* Format not supported. Should never get here. */
            MA_ASSERT(MA_FALSE);
            return MA_INVALID_OPERATION;
        }

        if (speexErr != RESAMPLER_ERR_SUCCESS) {
            return ma_result_from_speex_err(speexErr);
        }

        framesProcessedIn  += frameCountInThisIteration;
        framesProcessedOut += frameCountOutThisIteration;
    }

    *pFrameCountOut = framesProcessedOut;
    *pFrameCountIn  = framesProcessedIn;

    return MA_SUCCESS;
}
#endif

static ma_result ma_resampler_process_pcm_frames__read(ma_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    MA_ASSERT(pResampler != NULL);
    MA_ASSERT(pFramesOut != NULL);

    /* pFramesOut is not NULL, which means we must have a capacity. */
    if (pFrameCountOut == NULL) {
        return MA_INVALID_ARGS;
    }

    /* It doesn't make sense to not have any input frames to process. */
    if (pFrameCountIn == NULL || pFramesIn == NULL) {
        return MA_INVALID_ARGS;
    }

    switch (pResampler->config.algorithm)
    {
        case ma_resample_algorithm_linear:
        {
            return ma_resampler_process_pcm_frames__read__linear(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
        }

        case ma_resample_algorithm_speex:
        {
        #if defined(MA_HAS_SPEEX_RESAMPLER)
            return ma_resampler_process_pcm_frames__read__speex(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
        #else
            break;
        #endif
        }
    
        default: break;
    }

    /* Should never get here. */
    MA_ASSERT(MA_FALSE);
    return MA_INVALID_ARGS;
}


static ma_result ma_resampler_process_pcm_frames__seek__linear(ma_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, ma_uint64* pFrameCountOut)
{
    MA_ASSERT(pResampler != NULL);

    /* Seeking is supported natively by the linear resampler. */
    return ma_linear_resampler_process_pcm_frames(&pResampler->state.linear, pFramesIn, pFrameCountIn, NULL, pFrameCountOut);
}

#if defined(MA_HAS_SPEEX_RESAMPLER)
static ma_result ma_resampler_process_pcm_frames__seek__speex(ma_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, ma_uint64* pFrameCountOut)
{
    /* The generic seek method is implemented in on top of ma_resampler_process_pcm_frames__read() by just processing into a dummy buffer. */
    float devnull[4096];
    ma_uint64 totalOutputFramesToProcess;
    ma_uint64 totalOutputFramesProcessed;
    ma_uint64 totalInputFramesProcessed;
    ma_uint32 bpf;
    ma_result result;

    MA_ASSERT(pResampler != NULL);

    totalOutputFramesProcessed = 0;
    totalInputFramesProcessed = 0;
    bpf = ma_get_bytes_per_frame(pResampler->config.format, pResampler->config.channels);

    if (pFrameCountOut != NULL) {
        /* Seek by output frames. */
        totalOutputFramesToProcess = *pFrameCountOut;
    } else {
        /* Seek by input frames. */
        MA_ASSERT(pFrameCountIn != NULL);
        totalOutputFramesToProcess = ma_resampler_get_expected_output_frame_count(pResampler, *pFrameCountIn);
    }

    if (pFramesIn != NULL) {
        /* Process input data. */
        MA_ASSERT(pFrameCountIn != NULL);
        while (totalOutputFramesProcessed < totalOutputFramesToProcess && totalInputFramesProcessed < *pFrameCountIn) {
            ma_uint64 inputFramesToProcessThisIteration  = (*pFrameCountIn - totalInputFramesProcessed);
            ma_uint64 outputFramesToProcessThisIteration = (totalOutputFramesToProcess - totalOutputFramesProcessed);
            if (outputFramesToProcessThisIteration > sizeof(devnull) / bpf) {
                outputFramesToProcessThisIteration = sizeof(devnull) / bpf;
            }

            result = ma_resampler_process_pcm_frames__read(pResampler, ma_offset_ptr(pFramesIn, totalInputFramesProcessed*bpf), &inputFramesToProcessThisIteration, ma_offset_ptr(devnull, totalOutputFramesProcessed*bpf), &outputFramesToProcessThisIter...
            if (result != MA_SUCCESS) {
                return result;
            }

            totalOutputFramesProcessed += outputFramesToProcessThisIteration;
            totalInputFramesProcessed  += inputFramesToProcessThisIteration;
        }
    } else {
        /* Don't process input data - just update timing and filter state as if zeroes were passed in. */
        while (totalOutputFramesProcessed < totalOutputFramesToProcess) {
            ma_uint64 inputFramesToProcessThisIteration  = 16384;
            ma_uint64 outputFramesToProcessThisIteration = (totalOutputFramesToProcess - totalOutputFramesProcessed);
            if (outputFramesToProcessThisIteration > sizeof(devnull) / bpf) {
                outputFramesToProcessThisIteration = sizeof(devnull) / bpf;
            }

            result = ma_resampler_process_pcm_frames__read(pResampler, NULL, &inputFramesToProcessThisIteration, ma_offset_ptr(devnull, totalOutputFramesProcessed*bpf), &outputFramesToProcessThisIteration);
            if (result != MA_SUCCESS) {
                return result;
            }

            totalOutputFramesProcessed += outputFramesToProcessThisIteration;
            totalInputFramesProcessed  += inputFramesToProcessThisIteration;
        }
    }


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

        *pFrameCountIn = totalInputFramesProcessed;
    }
    if (pFrameCountOut != NULL) {
        *pFrameCountOut = totalOutputFramesProcessed;
    }

    return MA_SUCCESS;
}
#endif

static ma_result ma_resampler_process_pcm_frames__seek(ma_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, ma_uint64* pFrameCountOut)
{
    MA_ASSERT(pResampler != NULL);

    switch (pResampler->config.algorithm)
    {
        case ma_resample_algorithm_linear:
        {
            return ma_resampler_process_pcm_frames__seek__linear(pResampler, pFramesIn, pFrameCountIn, pFrameCountOut);
        } break;

        case ma_resample_algorithm_speex:
        {
        #if defined(MA_HAS_SPEEX_RESAMPLER)
            return ma_resampler_process_pcm_frames__seek__speex(pResampler, pFramesIn, pFrameCountIn, pFrameCountOut);
        #else
            break;
        #endif
        };

        default: break;
    }

    /* Should never hit this. */
    MA_ASSERT(MA_FALSE);
    return MA_INVALID_ARGS;
}


MA_API ma_result ma_resampler_process_pcm_frames(ma_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    if (pResampler == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pFrameCountOut == NULL && pFrameCountIn == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pFramesOut != NULL) {
        /* Reading. */
        return ma_resampler_process_pcm_frames__read(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    } else {
        /* Seeking. */
        return ma_resampler_process_pcm_frames__seek(pResampler, pFramesIn, pFrameCountIn, pFrameCountOut);
    }
}

MA_API ma_result ma_resampler_set_rate(ma_resampler* pResampler, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut)
{
    if (pResampler == NULL) {
        return MA_INVALID_ARGS;
    }

    if (sampleRateIn == 0 || sampleRateOut == 0) {

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

        if (n == 0) {
            return MA_INVALID_ARGS; /* Ratio too small. */
        }

        MA_ASSERT(n != 0);
    
        return ma_resampler_set_rate(pResampler, n, d);
    }
}

MA_API ma_uint64 ma_resampler_get_required_input_frame_count(ma_resampler* pResampler, ma_uint64 outputFrameCount)
{
    if (pResampler == NULL) {
        return 0;
    }

    if (outputFrameCount == 0) {
        return 0;
    }

    switch (pResampler->config.algorithm)
    {
        case ma_resample_algorithm_linear:
        {
            return ma_linear_resampler_get_required_input_frame_count(&pResampler->state.linear, outputFrameCount);
        }

        case ma_resample_algorithm_speex:
        {
        #if defined(MA_HAS_SPEEX_RESAMPLER)
            ma_uint64 count;
            int speexErr = ma_speex_resampler_get_required_input_frame_count((SpeexResamplerState*)pResampler->state.speex.pSpeexResamplerState, outputFrameCount, &count);
            if (speexErr != RESAMPLER_ERR_SUCCESS) {
                return 0;
            }

            return count;
        #else
            break;
        #endif
        }

        default: break;
    }

    /* Should never get here. */
    MA_ASSERT(MA_FALSE);
    return 0;
}

MA_API ma_uint64 ma_resampler_get_expected_output_frame_count(ma_resampler* pResampler, ma_uint64 inputFrameCount)
{
    if (pResampler == NULL) {
        return 0;   /* Invalid args. */
    }

    if (inputFrameCount == 0) {
        return 0;
    }

    switch (pResampler->config.algorithm)
    {
        case ma_resample_algorithm_linear:
        {
            return ma_linear_resampler_get_expected_output_frame_count(&pResampler->state.linear, inputFrameCount);
        }

        case ma_resample_algorithm_speex:
        {
        #if defined(MA_HAS_SPEEX_RESAMPLER)
            ma_uint64 count;
            int speexErr = ma_speex_resampler_get_expected_output_frame_count((SpeexResamplerState*)pResampler->state.speex.pSpeexResamplerState, inputFrameCount, &count);
            if (speexErr != RESAMPLER_ERR_SUCCESS) {
                return 0;
            }

            return count;
        #else
            break;
        #endif
        }

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

    return MA_SUCCESS;
}

MA_API void ma_channel_converter_uninit(ma_channel_converter* pConverter)
{
    if (pConverter == NULL) {
        return;
    }
}

static ma_result ma_channel_converter_process_pcm_frames__passthrough(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pFramesOut != NULL);
    MA_ASSERT(pFramesIn  != NULL);

    ma_copy_memory_64(pFramesOut, pFramesIn, frameCount * ma_get_bytes_per_frame(pConverter->format, pConverter->channelsOut));
    return MA_SUCCESS;
}

static ma_result ma_channel_converter_process_pcm_frames__simple_shuffle(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint32 iFrame;
    ma_uint32 iChannelIn;

    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pFramesOut != NULL);
    MA_ASSERT(pFramesIn  != NULL);
    MA_ASSERT(pConverter->channelsIn == pConverter->channelsOut);

    switch (pConverter->format)
    {
        case ma_format_u8:
        {
            /* */ ma_uint8* pFramesOutU8 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInU8  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    pFramesOutU8[pConverter->shuffleTable[iChannelIn]] = pFramesInU8[iChannelIn];
                }

                pFramesOutU8 += pConverter->channelsOut;
                pFramesInU8  += pConverter->channelsIn;
            }
        } break;

        case ma_format_s16:
        {
            /* */ ma_int16* pFramesOutS16 = (      ma_int16*)pFramesOut;
            const ma_int16* pFramesInS16  = (const ma_int16*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    pFramesOutS16[pConverter->shuffleTable[iChannelIn]] = pFramesInS16[iChannelIn];
                }

                pFramesOutS16 += pConverter->channelsOut;
                pFramesInS16  += pConverter->channelsIn;
            }
        } break;

        case ma_format_s24:
        {
            /* */ ma_uint8* pFramesOutS24 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInS24  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    ma_uint32 iChannelOut = pConverter->shuffleTable[iChannelIn];
                    pFramesOutS24[iChannelOut*3 + 0] = pFramesInS24[iChannelIn*3 + 0];
                    pFramesOutS24[iChannelOut*3 + 1] = pFramesInS24[iChannelIn*3 + 1];
                    pFramesOutS24[iChannelOut*3 + 2] = pFramesInS24[iChannelIn*3 + 2];
                }

                pFramesOutS24 += pConverter->channelsOut*3;
                pFramesInS24  += pConverter->channelsIn*3;
            }
        } break;

        case ma_format_s32:
        {
            /* */ ma_int32* pFramesOutS32 = (      ma_int32*)pFramesOut;
            const ma_int32* pFramesInS32  = (const ma_int32*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    pFramesOutS32[pConverter->shuffleTable[iChannelIn]] = pFramesInS32[iChannelIn];
                }

                pFramesOutS32 += pConverter->channelsOut;
                pFramesInS32  += pConverter->channelsIn;
            }
        } break;
        
        case ma_format_f32:
        {
            /* */ float* pFramesOutF32 = (      float*)pFramesOut;
            const float* pFramesInF32  = (const float*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    pFramesOutF32[pConverter->shuffleTable[iChannelIn]] = pFramesInF32[iChannelIn];
                }

                pFramesOutF32 += pConverter->channelsOut;
                pFramesInF32  += pConverter->channelsIn;
            }
        } break;

        default: return MA_INVALID_OPERATION;   /* Unknown format. */
    }

    return MA_SUCCESS;
}

static ma_result ma_channel_converter_process_pcm_frames__simple_mono_expansion(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint64 iFrame;

    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pFramesOut != NULL);
    MA_ASSERT(pFramesIn  != NULL);
    MA_ASSERT(pConverter->channelsIn == 1);

    switch (pConverter->format)
    {
        case ma_format_u8:
        {
            /* */ ma_uint8* pFramesOutU8 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInU8  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < pConverter->channelsOut; iChannel += 1) {
                    pFramesOutU8[iFrame*pConverter->channelsOut + iChannel] = pFramesInU8[iFrame];
                }
            }
        } break;

        case ma_format_s16:
        {
            /* */ ma_int16* pFramesOutS16 = (      ma_int16*)pFramesOut;
            const ma_int16* pFramesInS16  = (const ma_int16*)pFramesIn;

            if (pConverter->channelsOut == 2) {
                for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                    pFramesOutS16[iFrame*2 + 0] = pFramesInS16[iFrame];
                    pFramesOutS16[iFrame*2 + 1] = pFramesInS16[iFrame];
                }
            } else {
                for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                    ma_uint32 iChannel;
                    for (iChannel = 0; iChannel < pConverter->channelsOut; iChannel += 1) {
                        pFramesOutS16[iFrame*pConverter->channelsOut + iChannel] = pFramesInS16[iFrame];
                    }
                }
            }
        } break;

        case ma_format_s24:
        {
            /* */ ma_uint8* pFramesOutS24 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInS24  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < pConverter->channelsOut; iChannel += 1) {
                    ma_uint64 iSampleOut = iFrame*pConverter->channelsOut + iChannel;
                    ma_uint64 iSampleIn  = iFrame;
                    pFramesOutS24[iSampleOut*3 + 0] = pFramesInS24[iSampleIn*3 + 0];
                    pFramesOutS24[iSampleOut*3 + 1] = pFramesInS24[iSampleIn*3 + 1];
                    pFramesOutS24[iSampleOut*3 + 2] = pFramesInS24[iSampleIn*3 + 2];
                }
            }
        } break;

        case ma_format_s32:
        {
            /* */ ma_int32* pFramesOutS32 = (      ma_int32*)pFramesOut;
            const ma_int32* pFramesInS32  = (const ma_int32*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < pConverter->channelsOut; iChannel += 1) {
                    pFramesOutS32[iFrame*pConverter->channelsOut + iChannel] = pFramesInS32[iFrame];
                }
            }
        } break;
        
        case ma_format_f32:
        {
            /* */ float* pFramesOutF32 = (      float*)pFramesOut;
            const float* pFramesInF32  = (const float*)pFramesIn;

            if (pConverter->channelsOut == 2) {
                for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                    pFramesOutF32[iFrame*2 + 0] = pFramesInF32[iFrame];
                    pFramesOutF32[iFrame*2 + 1] = pFramesInF32[iFrame];
                }
            } else {
                for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                    ma_uint32 iChannel;
                    for (iChannel = 0; iChannel < pConverter->channelsOut; iChannel += 1) {
                        pFramesOutF32[iFrame*pConverter->channelsOut + iChannel] = pFramesInF32[iFrame];
                    }
                }
            }
        } break;

        default: return MA_INVALID_OPERATION;   /* Unknown format. */
    }

    return MA_SUCCESS;
}

static ma_result ma_channel_converter_process_pcm_frames__stereo_to_mono(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint64 iFrame;

    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pFramesOut != NULL);
    MA_ASSERT(pFramesIn  != NULL);
    MA_ASSERT(pConverter->channelsIn  == 2);
    MA_ASSERT(pConverter->channelsOut == 1);

    switch (pConverter->format)
    {
        case ma_format_u8:
        {
            /* */ ma_uint8* pFramesOutU8 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInU8  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                pFramesOutU8[iFrame] = ma_clip_u8((ma_int16)((ma_pcm_sample_u8_to_s16_no_scale(pFramesInU8[iFrame*2+0]) + ma_pcm_sample_u8_to_s16_no_scale(pFramesInU8[iFrame*2+1])) / 2));
            }
        } break;

        case ma_format_s16:
        {
            /* */ ma_int16* pFramesOutS16 = (      ma_int16*)pFramesOut;
            const ma_int16* pFramesInS16  = (const ma_int16*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                pFramesOutS16[iFrame] = (ma_int16)(((ma_int32)pFramesInS16[iFrame*2+0] + (ma_int32)pFramesInS16[iFrame*2+1]) / 2);
            }
        } break;

        case ma_format_s24:
        {
            /* */ ma_uint8* pFramesOutS24 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInS24  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                ma_int64 s24_0 = ma_pcm_sample_s24_to_s32_no_scale(&pFramesInS24[(iFrame*2+0)*3]);
                ma_int64 s24_1 = ma_pcm_sample_s24_to_s32_no_scale(&pFramesInS24[(iFrame*2+1)*3]);
                ma_pcm_sample_s32_to_s24_no_scale((s24_0 + s24_1) / 2, &pFramesOutS24[iFrame*3]);
            }
        } break;

        case ma_format_s32:
        {
            /* */ ma_int32* pFramesOutS32 = (      ma_int32*)pFramesOut;
            const ma_int32* pFramesInS32  = (const ma_int32*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                pFramesOutS32[iFrame] = (ma_int16)(((ma_int32)pFramesInS32[iFrame*2+0] + (ma_int32)pFramesInS32[iFrame*2+1]) / 2);
            }
        } break;
        
        case ma_format_f32:
        {
            /* */ float* pFramesOutF32 = (      float*)pFramesOut;
            const float* pFramesInF32  = (const float*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                pFramesOutF32[iFrame] = (pFramesInF32[iFrame*2+0] + pFramesInF32[iFrame*2+0]) * 0.5f;
            }
        } break;

        default: return MA_INVALID_OPERATION;   /* Unknown format. */
    }

    return MA_SUCCESS;
}

static ma_result ma_channel_converter_process_pcm_frames__weights(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint32 iFrame;
    ma_uint32 iChannelIn;
    ma_uint32 iChannelOut;

    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pFramesOut != NULL);
    MA_ASSERT(pFramesIn  != NULL);

    /* This is the more complicated case. Each of the output channels is accumulated with 0 or more input channels. */

    /* Clear. */
    ma_zero_memory_64(pFramesOut, frameCount * ma_get_bytes_per_frame(pConverter->format, pConverter->channelsOut));

    /* Accumulate. */
    switch (pConverter->format)
    {
        case ma_format_u8:
        {
            /* */ ma_uint8* pFramesOutU8 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInU8  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
                        ma_int16 u8_O = ma_pcm_sample_u8_to_s16_no_scale(pFramesOutU8[iFrame*pConverter->channelsOut + iChannelOut]);
                        ma_int16 u8_I = ma_pcm_sample_u8_to_s16_no_scale(pFramesInU8 [iFrame*pConverter->channelsIn  + iChannelIn ]);
                        ma_int32 s    = (ma_int32)ma_clamp(u8_O + ((u8_I * pConverter->weights.s16[iChannelIn][iChannelOut]) >> MA_CHANNEL_CONVERTER_FIXED_POINT_SHIFT), -128, 127);
                        pFramesOutU8[iFrame*pConverter->channelsOut + iChannelOut] = ma_clip_u8((ma_int16)s);
                    }
                }
            }
        } break;

        case ma_format_s16:
        {
            /* */ ma_int16* pFramesOutS16 = (      ma_int16*)pFramesOut;
            const ma_int16* pFramesInS16  = (const ma_int16*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
                        ma_int32 s = pFramesOutS16[iFrame*pConverter->channelsOut + iChannelOut];
                        s += (pFramesInS16[iFrame*pConverter->channelsIn + iChannelIn] * pConverter->weights.s16[iChannelIn][iChannelOut]) >> MA_CHANNEL_CONVERTER_FIXED_POINT_SHIFT;

                        pFramesOutS16[iFrame*pConverter->channelsOut + iChannelOut] = (ma_int16)ma_clamp(s, -32768, 32767);
                    }
                }
            }
        } break;

        case ma_format_s24:
        {
            /* */ ma_uint8* pFramesOutS24 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInS24  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
                        ma_int64 s24_O = ma_pcm_sample_s24_to_s32_no_scale(&pFramesOutS24[(iFrame*pConverter->channelsOut + iChannelOut)*3]);
                        ma_int64 s24_I = ma_pcm_sample_s24_to_s32_no_scale(&pFramesInS24 [(iFrame*pConverter->channelsIn  + iChannelIn )*3]);
                        ma_int64 s24   = (ma_int32)ma_clamp(s24_O + ((s24_I * pConverter->weights.s16[iChannelIn][iChannelOut]) >> MA_CHANNEL_CONVERTER_FIXED_POINT_SHIFT), -8388608, 8388607);
                        ma_pcm_sample_s32_to_s24_no_scale(s24, &pFramesOutS24[(iFrame*pConverter->channelsOut + iChannelOut)*3]);
                    }
                }
            }
        } break;

        case ma_format_s32:
        {
            /* */ ma_int32* pFramesOutS32 = (      ma_int32*)pFramesOut;
            const ma_int32* pFramesInS32  = (const ma_int32*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
                        ma_int64 s = pFramesOutS32[iFrame*pConverter->channelsOut + iChannelOut];
                        s += ((ma_int64)pFramesInS32[iFrame*pConverter->channelsIn + iChannelIn] * pConverter->weights.s16[iChannelIn][iChannelOut]) >> MA_CHANNEL_CONVERTER_FIXED_POINT_SHIFT;

                        pFramesOutS32[iFrame*pConverter->channelsOut + iChannelOut] = ma_clip_s32(s);
                    }
                }
            }
        } break;
        
        case ma_format_f32:
        {
            /* */ float* pFramesOutF32 = (      float*)pFramesOut;
            const float* pFramesInF32  = (const float*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
                        pFramesOutF32[iFrame*pConverter->channelsOut + iChannelOut] += pFramesInF32[iFrame*pConverter->channelsIn + iChannelIn] * pConverter->weights.f32[iChannelIn][iChannelOut];
                    }
                }
            }
        } break;

        default: return MA_INVALID_OPERATION;   /* Unknown format. */
    }

    return MA_SUCCESS;
}

MA_API ma_result ma_channel_converter_process_pcm_frames(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pConverter == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pFramesOut == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pFramesIn == NULL) {
        ma_zero_memory_64(pFramesOut, frameCount * ma_get_bytes_per_frame(pConverter->format, pConverter->channelsOut));
        return MA_SUCCESS;
    }

    if (pConverter->isPassthrough) {
        return ma_channel_converter_process_pcm_frames__passthrough(pConverter, pFramesOut, pFramesIn, frameCount);
    } else if (pConverter->isSimpleShuffle) {
        return ma_channel_converter_process_pcm_frames__simple_shuffle(pConverter, pFramesOut, pFramesIn, frameCount);
    } else if (pConverter->isSimpleMonoExpansion) {
        return ma_channel_converter_process_pcm_frames__simple_mono_expansion(pConverter, pFramesOut, pFramesIn, frameCount);
    } else if (pConverter->isStereoToMono) {
        return ma_channel_converter_process_pcm_frames__stereo_to_mono(pConverter, pFramesOut, pFramesIn, frameCount);
    } else {
        return ma_channel_converter_process_pcm_frames__weights(pConverter, pFramesOut, pFramesIn, frameCount);
    }
}


/**************************************************************************************************************************************************************

Data Conversion

**************************************************************************************************************************************************************/
MA_API ma_data_converter_config ma_data_converter_config_init_default()

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

{
    if (pConverter == NULL) {
        return;
    }

    if (pConverter->hasResampler) {
        ma_resampler_uninit(&pConverter->resampler);
    }
}

static ma_result ma_data_converter_process_pcm_frames__passthrough(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 frameCount;

    MA_ASSERT(pConverter != NULL);
    
    frameCountIn = 0;
    if (pFrameCountIn != NULL) {
        frameCountIn = *pFrameCountIn;
    }

    frameCountOut = 0;
    if (pFrameCountOut != NULL) {
        frameCountOut = *pFrameCountOut;
    }

    frameCount = ma_min(frameCountIn, frameCountOut);

    if (pFramesOut != NULL) {
        if (pFramesIn != NULL) {
            ma_copy_memory_64(pFramesOut, pFramesIn, frameCount * ma_get_bytes_per_frame(pConverter->config.formatOut, pConverter->config.channelsOut));
        } else {
            ma_zero_memory_64(pFramesOut,            frameCount * ma_get_bytes_per_frame(pConverter->config.formatOut, pConverter->config.channelsOut));
        }
    }

    if (pFrameCountIn != NULL) {
        *pFrameCountIn = frameCount;
    }
    if (pFrameCountOut != NULL) {
        *pFrameCountOut = frameCount;
    }

    return MA_SUCCESS;
}

static ma_result ma_data_converter_process_pcm_frames__format_only(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 frameCount;

    MA_ASSERT(pConverter != NULL);
    
    frameCountIn = 0;
    if (pFrameCountIn != NULL) {
        frameCountIn = *pFrameCountIn;
    }

    frameCountOut = 0;
    if (pFrameCountOut != NULL) {
        frameCountOut = *pFrameCountOut;
    }

    frameCount = ma_min(frameCountIn, frameCountOut);

    if (pFramesOut != NULL) {
        if (pFramesIn != NULL) {
            ma_convert_pcm_frames_format(pFramesOut, pConverter->config.formatOut, pFramesIn, pConverter->config.formatIn, frameCount, pConverter->config.channelsIn, pConverter->config.ditherMode);
        } else {
            ma_zero_memory_64(pFramesOut, frameCount * ma_get_bytes_per_frame(pConverter->config.formatOut, pConverter->config.channelsOut));
        }
    }

    if (pFrameCountIn != NULL) {
        *pFrameCountIn = frameCount;
    }
    if (pFrameCountOut != NULL) {
        *pFrameCountOut = frameCount;
    }

    return MA_SUCCESS;
}


static ma_result ma_data_converter_process_pcm_frames__resample_with_format_conversion(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    ma_result result = MA_SUCCESS;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;

    MA_ASSERT(pConverter != NULL);

    frameCountIn = 0;
    if (pFrameCountIn != NULL) {
        frameCountIn = *pFrameCountIn;
    }

    frameCountOut = 0;
    if (pFrameCountOut != NULL) {
        frameCountOut = *pFrameCountOut;
    }

    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    while (framesProcessedOut < frameCountOut) {
        ma_uint8 pTempBufferOut[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
        const ma_uint32 tempBufferOutCap = sizeof(pTempBufferOut) / ma_get_bytes_per_frame(pConverter->resampler.config.format, pConverter->resampler.config.channels);
        const void* pFramesInThisIteration;
        /* */ void* pFramesOutThisIteration;
        ma_uint64 frameCountInThisIteration;
        ma_uint64 frameCountOutThisIteration;

        if (pFramesIn != NULL) {
            pFramesInThisIteration = ma_offset_ptr(pFramesIn, framesProcessedIn * ma_get_bytes_per_frame(pConverter->config.formatIn, pConverter->config.channelsIn));
        } else {
            pFramesInThisIteration = NULL;
        }

        if (pFramesOut != NULL) {
            pFramesOutThisIteration = ma_offset_ptr(pFramesOut, framesProcessedOut * ma_get_bytes_per_frame(pConverter->config.formatOut, pConverter->config.channelsOut));
        } else {
            pFramesOutThisIteration = NULL;
        }

        /* Do a pre format conversion if necessary. */
        if (pConverter->hasPreFormatConversion) {
            ma_uint8 pTempBufferIn[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
            const ma_uint32 tempBufferInCap = sizeof(pTempBufferIn) / ma_get_bytes_per_frame(pConverter->resampler.config.format, pConverter->resampler.config.channels);

            frameCountInThisIteration  = (frameCountIn - framesProcessedIn);
            if (frameCountInThisIteration > tempBufferInCap) {
                frameCountInThisIteration = tempBufferInCap;
            }

            if (pConverter->hasPostFormatConversion) {
               if (frameCountInThisIteration > tempBufferOutCap) {
                   frameCountInThisIteration = tempBufferOutCap;
               }
            }

            if (pFramesInThisIteration != NULL) {
                ma_convert_pcm_frames_format(pTempBufferIn, pConverter->resampler.config.format, pFramesInThisIteration, pConverter->config.formatIn, frameCountInThisIteration, pConverter->config.channelsIn, pConverter->config.ditherMode);
            } else {
                MA_ZERO_MEMORY(pTempBufferIn, sizeof(pTempBufferIn));
            }

            frameCountOutThisIteration = (frameCountOut - framesProcessedOut);

            if (pConverter->hasPostFormatConversion) {
                /* Both input and output conversion required. Output to the temp buffer. */
                if (frameCountOutThisIteration > tempBufferOutCap) {
                    frameCountOutThisIteration = tempBufferOutCap;
                }

                result = ma_resampler_process_pcm_frames(&pConverter->resampler, pTempBufferIn, &frameCountInThisIteration, pTempBufferOut, &frameCountOutThisIteration);
            } else {
                /* Only pre-format required. Output straight to the output buffer. */
                result = ma_resampler_process_pcm_frames(&pConverter->resampler, pTempBufferIn, &frameCountInThisIteration, pFramesOutThisIteration, &frameCountOutThisIteration);
            }

            if (result != MA_SUCCESS) {
                break;
            }
        } else {
            /* No pre-format required. Just read straight from the input buffer. */
            MA_ASSERT(pConverter->hasPostFormatConversion == MA_TRUE);

            frameCountInThisIteration  = (frameCountIn  - framesProcessedIn);
            frameCountOutThisIteration = (frameCountOut - framesProcessedOut);
            if (frameCountOutThisIteration > tempBufferOutCap) {
                frameCountOutThisIteration = tempBufferOutCap;
            }

            result = ma_resampler_process_pcm_frames(&pConverter->resampler, pFramesInThisIteration, &frameCountInThisIteration, pTempBufferOut, &frameCountOutThisIteration);
            if (result != MA_SUCCESS) {
                break;
            }
        }

        /* If we are doing a post format conversion we need to do that now. */
        if (pConverter->hasPostFormatConversion) {
            if (pFramesOutThisIteration != NULL) {
                ma_convert_pcm_frames_format(pFramesOutThisIteration, pConverter->config.formatOut, pTempBufferOut, pConverter->resampler.config.format, frameCountOutThisIteration, pConverter->resampler.config.channels, pConverter->config.ditherMode)...
            }
        }

        framesProcessedIn  += frameCountInThisIteration;
        framesProcessedOut += frameCountOutThisIteration;

        MA_ASSERT(framesProcessedIn  <= frameCountIn);
        MA_ASSERT(framesProcessedOut <= frameCountOut);

        if (frameCountOutThisIteration == 0) {
            break;  /* Consumed all of our input data. */
        }
    }

    if (pFrameCountIn != NULL) {
        *pFrameCountIn = framesProcessedIn;
    }
    if (pFrameCountOut != NULL) {
        *pFrameCountOut = framesProcessedOut;
    }

    return result;
}

static ma_result ma_data_converter_process_pcm_frames__resample_only(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    MA_ASSERT(pConverter != NULL);

    if (pConverter->hasPreFormatConversion == MA_FALSE && pConverter->hasPostFormatConversion == MA_FALSE) {
        /* Neither pre- nor post-format required. This is simple case where only resampling is required. */
        return ma_resampler_process_pcm_frames(&pConverter->resampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    } else {
        /* Format conversion required. */
        return ma_data_converter_process_pcm_frames__resample_with_format_conversion(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    }
}

static ma_result ma_data_converter_process_pcm_frames__channels_only(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    ma_result result;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 frameCount;

    MA_ASSERT(pConverter != NULL);

    frameCountIn = 0;
    if (pFrameCountIn != NULL) {
        frameCountIn = *pFrameCountIn;
    }

    frameCountOut = 0;
    if (pFrameCountOut != NULL) {
        frameCountOut = *pFrameCountOut;
    }

    frameCount = ma_min(frameCountIn, frameCountOut);

    if (pConverter->hasPreFormatConversion == MA_FALSE && pConverter->hasPostFormatConversion == MA_FALSE) {
        /* No format conversion required. */
        result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pFramesOut, pFramesIn, frameCount);
        if (result != MA_SUCCESS) {
            return result;
        }
    } else {
        /* Format conversion required. */
        ma_uint64 framesProcessed = 0;

        while (framesProcessed < frameCount) {
            ma_uint8 pTempBufferOut[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
            const ma_uint32 tempBufferOutCap = sizeof(pTempBufferOut) / ma_get_bytes_per_frame(pConverter->channelConverter.format, pConverter->channelConverter.channelsOut);
            const void* pFramesInThisIteration;
            /* */ void* pFramesOutThisIteration;
            ma_uint64 frameCountThisIteration;

            if (pFramesIn != NULL) {
                pFramesInThisIteration = ma_offset_ptr(pFramesIn, framesProcessed * ma_get_bytes_per_frame(pConverter->config.formatIn, pConverter->config.channelsIn));
            } else {
                pFramesInThisIteration = NULL;
            }

            if (pFramesOut != NULL) {
                pFramesOutThisIteration = ma_offset_ptr(pFramesOut, framesProcessed * ma_get_bytes_per_frame(pConverter->config.formatOut, pConverter->config.channelsOut));
            } else {
                pFramesOutThisIteration = NULL;
            }

            /* Do a pre format conversion if necessary. */
            if (pConverter->hasPreFormatConversion) {
                ma_uint8 pTempBufferIn[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                const ma_uint32 tempBufferInCap = sizeof(pTempBufferIn) / ma_get_bytes_per_frame(pConverter->channelConverter.format, pConverter->channelConverter.channelsIn);

                frameCountThisIteration = (frameCount - framesProcessed);
                if (frameCountThisIteration > tempBufferInCap) {
                    frameCountThisIteration = tempBufferInCap;
                }

                if (pConverter->hasPostFormatConversion) {
                    if (frameCountThisIteration > tempBufferOutCap) {
                        frameCountThisIteration = tempBufferOutCap;
                    }
                }

                if (pFramesInThisIteration != NULL) {
                    ma_convert_pcm_frames_format(pTempBufferIn, pConverter->channelConverter.format, pFramesInThisIteration, pConverter->config.formatIn, frameCountThisIteration, pConverter->config.channelsIn, pConverter->config.ditherMode);
                } else {
                    MA_ZERO_MEMORY(pTempBufferIn, sizeof(pTempBufferIn));
                }

                if (pConverter->hasPostFormatConversion) {
                    /* Both input and output conversion required. Output to the temp buffer. */
                    result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pTempBufferOut, pTempBufferIn, frameCountThisIteration);
                } else {
                    /* Only pre-format required. Output straight to the output buffer. */
                    result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pFramesOutThisIteration, pTempBufferIn, frameCountThisIteration);
                }

                if (result != MA_SUCCESS) {
                    break;
                }
            } else {
                /* No pre-format required. Just read straight from the input buffer. */
                MA_ASSERT(pConverter->hasPostFormatConversion == MA_TRUE);

                frameCountThisIteration = (frameCount - framesProcessed);
                if (frameCountThisIteration > tempBufferOutCap) {
                    frameCountThisIteration = tempBufferOutCap;
                }

                result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pTempBufferOut, pFramesInThisIteration, frameCountThisIteration);
                if (result != MA_SUCCESS) {
                    break;
                }
            }

            /* If we are doing a post format conversion we need to do that now. */
            if (pConverter->hasPostFormatConversion) {
                if (pFramesOutThisIteration != NULL) {
                    ma_convert_pcm_frames_format(pFramesOutThisIteration, pConverter->config.formatOut, pTempBufferOut, pConverter->channelConverter.format, frameCountThisIteration, pConverter->channelConverter.channelsOut, pConverter->config.ditherM...
                }
            }

            framesProcessed += frameCountThisIteration;
        }
    }

    if (pFrameCountIn != NULL) {
        *pFrameCountIn = frameCount;
    }
    if (pFrameCountOut != NULL) {
        *pFrameCountOut = frameCount;
    }

    return MA_SUCCESS;
}

static ma_result ma_data_converter_process_pcm_frames__resampling_first(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    ma_result result;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;
    ma_uint8  pTempBufferIn[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];   /* In resampler format. */
    ma_uint64 tempBufferInCap;
    ma_uint8  pTempBufferMid[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];  /* In resampler format, channel converter input format. */
    ma_uint64 tempBufferMidCap;
    ma_uint8  pTempBufferOut[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];  /* In channel converter output format. */
    ma_uint64 tempBufferOutCap;

    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pConverter->resampler.config.format   == pConverter->channelConverter.format);
    MA_ASSERT(pConverter->resampler.config.channels == pConverter->channelConverter.channelsIn);
    MA_ASSERT(pConverter->resampler.config.channels <  pConverter->channelConverter.channelsOut);

    frameCountIn = 0;
    if (pFrameCountIn != NULL) {
        frameCountIn = *pFrameCountIn;
    }

    frameCountOut = 0;
    if (pFrameCountOut != NULL) {
        frameCountOut = *pFrameCountOut;
    }

    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    tempBufferInCap  = sizeof(pTempBufferIn)  / ma_get_bytes_per_frame(pConverter->resampler.config.format, pConverter->resampler.config.channels);
    tempBufferMidCap = sizeof(pTempBufferIn)  / ma_get_bytes_per_frame(pConverter->resampler.config.format, pConverter->resampler.config.channels);
    tempBufferOutCap = sizeof(pTempBufferOut) / ma_get_bytes_per_frame(pConverter->channelConverter.format, pConverter->channelConverter.channelsOut);

    while (framesProcessedOut < frameCountOut) {
        ma_uint64 frameCountInThisIteration;
        ma_uint64 frameCountOutThisIteration;
        const void* pRunningFramesIn = NULL;
        void* pRunningFramesOut = NULL;
        const void* pResampleBufferIn;
        void* pChannelsBufferOut;

        if (pFramesIn != NULL) {
            pRunningFramesIn  = ma_offset_ptr(pFramesIn,  framesProcessedIn  * ma_get_bytes_per_frame(pConverter->config.formatIn, pConverter->config.channelsIn));
        }
        if (pFramesOut != NULL) {
            pRunningFramesOut = ma_offset_ptr(pFramesOut, framesProcessedOut * ma_get_bytes_per_frame(pConverter->config.formatOut, pConverter->config.channelsOut));
        }

        /* Run input data through the resampler and output it to the temporary buffer. */
        frameCountInThisIteration = (frameCountIn - framesProcessedIn);

        if (pConverter->hasPreFormatConversion) {
            if (frameCountInThisIteration > tempBufferInCap) {
                frameCountInThisIteration = tempBufferInCap;
            }
        }

        frameCountOutThisIteration = (frameCountOut - framesProcessedOut);
        if (frameCountOutThisIteration > tempBufferMidCap) {
            frameCountOutThisIteration = tempBufferMidCap;
        }

        /* We can't read more frames than can fit in the output buffer. */
        if (pConverter->hasPostFormatConversion) {
            if (frameCountOutThisIteration > tempBufferOutCap) {
                frameCountOutThisIteration = tempBufferOutCap;
            }
        }

        /* We need to ensure we don't try to process too many input frames that we run out of room in the output buffer. If this happens we'll end up glitching. */
        {
            ma_uint64 requiredInputFrameCount = ma_resampler_get_required_input_frame_count(&pConverter->resampler, frameCountOutThisIteration);
            if (frameCountInThisIteration > requiredInputFrameCount) {
                frameCountInThisIteration = requiredInputFrameCount;
            }
        }

        if (pConverter->hasPreFormatConversion) {
            if (pFramesIn != NULL) {
                ma_convert_pcm_frames_format(pTempBufferIn, pConverter->resampler.config.format, pRunningFramesIn, pConverter->config.formatIn, frameCountInThisIteration, pConverter->config.channelsIn, pConverter->config.ditherMode);
                pResampleBufferIn = pTempBufferIn;
            } else {
                pResampleBufferIn = NULL;
            }
        } else {
            pResampleBufferIn = pRunningFramesIn;
        }

        result = ma_resampler_process_pcm_frames(&pConverter->resampler, pResampleBufferIn, &frameCountInThisIteration, pTempBufferMid, &frameCountOutThisIteration);
        if (result != MA_SUCCESS) {
            return result;
        }


        /*
        The input data has been resampled so now we need to run it through the channel converter. The input data is always contained in pTempBufferMid. We only need to do
        this part if we have an output buffer.
        */
        if (pFramesOut != NULL) {
            if (pConverter->hasPostFormatConversion) {
                pChannelsBufferOut = pTempBufferOut;
            } else {
                pChannelsBufferOut = pRunningFramesOut;
            }

            result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pChannelsBufferOut, pTempBufferMid, frameCountOutThisIteration);
            if (result != MA_SUCCESS) {
                return result;
            }

            /* Finally we do post format conversion. */
            if (pConverter->hasPostFormatConversion) {
                ma_convert_pcm_frames_format(pRunningFramesOut, pConverter->config.formatOut, pChannelsBufferOut, pConverter->channelConverter.format, frameCountOutThisIteration, pConverter->channelConverter.channelsOut, pConverter->config.ditherMode...
            }
        }


        framesProcessedIn  += frameCountInThisIteration;
        framesProcessedOut += frameCountOutThisIteration;

        MA_ASSERT(framesProcessedIn  <= frameCountIn);
        MA_ASSERT(framesProcessedOut <= frameCountOut);

        if (frameCountOutThisIteration == 0) {
            break;  /* Consumed all of our input data. */
        }
    }

    if (pFrameCountIn != NULL) {
        *pFrameCountIn = framesProcessedIn;
    }
    if (pFrameCountOut != NULL) {
        *pFrameCountOut = framesProcessedOut;
    }

    return MA_SUCCESS;
}

static ma_result ma_data_converter_process_pcm_frames__channels_first(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    ma_result result;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;
    ma_uint8  pTempBufferIn[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];   /* In resampler format. */
    ma_uint64 tempBufferInCap;
    ma_uint8  pTempBufferMid[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];  /* In resampler format, channel converter input format. */
    ma_uint64 tempBufferMidCap;
    ma_uint8  pTempBufferOut[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];  /* In channel converter output format. */
    ma_uint64 tempBufferOutCap;

    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pConverter->resampler.config.format   == pConverter->channelConverter.format);
    MA_ASSERT(pConverter->resampler.config.channels == pConverter->channelConverter.channelsOut);
    MA_ASSERT(pConverter->resampler.config.channels <  pConverter->channelConverter.channelsIn);

    frameCountIn = 0;
    if (pFrameCountIn != NULL) {
        frameCountIn = *pFrameCountIn;
    }

    frameCountOut = 0;
    if (pFrameCountOut != NULL) {
        frameCountOut = *pFrameCountOut;
    }

    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    tempBufferInCap  = sizeof(pTempBufferIn)  / ma_get_bytes_per_frame(pConverter->channelConverter.format, pConverter->channelConverter.channelsIn);
    tempBufferMidCap = sizeof(pTempBufferIn)  / ma_get_bytes_per_frame(pConverter->channelConverter.format, pConverter->channelConverter.channelsOut);
    tempBufferOutCap = sizeof(pTempBufferOut) / ma_get_bytes_per_frame(pConverter->resampler.config.format, pConverter->resampler.config.channels);

    while (framesProcessedOut < frameCountOut) {
        ma_uint64 frameCountInThisIteration;
        ma_uint64 frameCountOutThisIteration;
        const void* pRunningFramesIn = NULL;
        void* pRunningFramesOut = NULL;
        const void* pChannelsBufferIn;
        void* pResampleBufferOut;

        if (pFramesIn != NULL) {
            pRunningFramesIn  = ma_offset_ptr(pFramesIn,  framesProcessedIn  * ma_get_bytes_per_frame(pConverter->config.formatIn, pConverter->config.channelsIn));
        }
        if (pFramesOut != NULL) {
            pRunningFramesOut = ma_offset_ptr(pFramesOut, framesProcessedOut * ma_get_bytes_per_frame(pConverter->config.formatOut, pConverter->config.channelsOut));
        }

        /* Run input data through the channel converter and output it to the temporary buffer. */
        frameCountInThisIteration = (frameCountIn - framesProcessedIn);

        if (pConverter->hasPreFormatConversion) {
            if (frameCountInThisIteration > tempBufferInCap) {
                frameCountInThisIteration = tempBufferInCap;
            }

            if (pRunningFramesIn != NULL) {
                ma_convert_pcm_frames_format(pTempBufferIn, pConverter->channelConverter.format, pRunningFramesIn, pConverter->config.formatIn, frameCountInThisIteration, pConverter->config.channelsIn, pConverter->config.ditherMode);
                pChannelsBufferIn = pTempBufferIn;
            } else {
                pChannelsBufferIn = NULL;
            }
        } else {
            pChannelsBufferIn = pRunningFramesIn;
        }

        /*
        We can't convert more frames than will fit in the output buffer. We shouldn't actually need to do this check because the channel count is always reduced
        in this case which means we should always have capacity, but I'm leaving it here just for safety for future maintenance.
        */
        if (frameCountInThisIteration > tempBufferMidCap) {
            frameCountInThisIteration = tempBufferMidCap;
        }

        /*
        Make sure we don't read any more input frames than we need to fill the output frame count. If we do this we will end up in a situation where we lose some
        input samples and will end up glitching.
        */
        frameCountOutThisIteration = (frameCountOut - framesProcessedOut);
        if (frameCountOutThisIteration > tempBufferMidCap) {
            frameCountOutThisIteration = tempBufferMidCap;
        }

        if (pConverter->hasPostFormatConversion) {
            ma_uint64 requiredInputFrameCount;

            if (frameCountOutThisIteration > tempBufferOutCap) {
                frameCountOutThisIteration = tempBufferOutCap;
            }

            requiredInputFrameCount = ma_resampler_get_required_input_frame_count(&pConverter->resampler, frameCountOutThisIteration);
            if (frameCountInThisIteration > requiredInputFrameCount) {
                frameCountInThisIteration = requiredInputFrameCount;
            }
        }

        result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pTempBufferMid, pChannelsBufferIn, frameCountInThisIteration);
        if (result != MA_SUCCESS) {
            return result;
        }


        /* At this point we have converted the channels to the output channel count which we now need to resample. */
        if (pConverter->hasPostFormatConversion) {
            pResampleBufferOut = pTempBufferOut;
        } else {
            pResampleBufferOut = pRunningFramesOut;
        }

        result = ma_resampler_process_pcm_frames(&pConverter->resampler, pTempBufferMid, &frameCountInThisIteration, pResampleBufferOut, &frameCountOutThisIteration);
        if (result != MA_SUCCESS) {
            return result;
        }

        /* Finally we can do the post format conversion. */
        if (pConverter->hasPostFormatConversion) {
            if (pRunningFramesOut != NULL) {
                ma_convert_pcm_frames_format(pRunningFramesOut, pConverter->config.formatOut, pResampleBufferOut, pConverter->resampler.config.format, frameCountOutThisIteration, pConverter->config.channelsOut, pConverter->config.ditherMode);
            }
        }

        framesProcessedIn  += frameCountInThisIteration;
        framesProcessedOut += frameCountOutThisIteration;

        MA_ASSERT(framesProcessedIn  <= frameCountIn);
        MA_ASSERT(framesProcessedOut <= frameCountOut);

        if (frameCountOutThisIteration == 0) {
            break;  /* Consumed all of our input data. */
        }
    }

    if (pFrameCountIn != NULL) {
        *pFrameCountIn = framesProcessedIn;
    }
    if (pFrameCountOut != NULL) {
        *pFrameCountOut = framesProcessedOut;
    }
    
    return MA_SUCCESS;
}

MA_API ma_result ma_data_converter_process_pcm_frames(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    if (pConverter == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pConverter->isPassthrough) {
        return ma_data_converter_process_pcm_frames__passthrough(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    }

    /*
    Here is where the real work is done. Getting here means we're not using a passthrough and we need to move the data through each of the relevant stages. The order
    of our stages depends on the input and output channel count. If the input channels is less than the output channels we want to do sample rate conversion first so
    that it has less work (resampling is the most expensive part of format conversion).
    */
    if (pConverter->config.channelsIn < pConverter->config.channelsOut) {
        /* Do resampling first, if necessary. */
        MA_ASSERT(pConverter->hasChannelConverter == MA_TRUE);

        if (pConverter->hasResampler) {
            /* Resampling first. */
            return ma_data_converter_process_pcm_frames__resampling_first(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
        } else {
            /* Resampling not required. */
            return ma_data_converter_process_pcm_frames__channels_only(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
        }
    } else {
        /* Do channel conversion first, if necessary. */
        if (pConverter->hasChannelConverter) {
            if (pConverter->hasResampler) {
                /* Channel routing first. */
                return ma_data_converter_process_pcm_frames__channels_first(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
            } else {
                /* Resampling not required. */
                return ma_data_converter_process_pcm_frames__channels_only(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
            }
        } else {
            /* Channel routing not required. */
            if (pConverter->hasResampler) {
                /* Resampling only. */
                return ma_data_converter_process_pcm_frames__resample_only(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
            } else {
                /* No channel routing nor resampling required. Just format conversion. */
                return ma_data_converter_process_pcm_frames__format_only(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
            }
        }
    }
}

MA_API ma_result ma_data_converter_set_rate(ma_data_converter* pConverter, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut)
{
    if (pConverter == NULL) {
        return MA_INVALID_ARGS;
    }

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

        return MA_INVALID_ARGS;
    }

    if (pConverter->hasResampler == MA_FALSE) {
        return MA_INVALID_OPERATION;    /* Dynamic resampling not enabled. */
    }

    return ma_resampler_set_rate_ratio(&pConverter->resampler, ratioInOut);
}

MA_API ma_uint64 ma_data_converter_get_required_input_frame_count(ma_data_converter* pConverter, ma_uint64 outputFrameCount)
{
    if (pConverter == NULL) {
        return 0;
    }

    if (pConverter->hasResampler) {
        return ma_resampler_get_required_input_frame_count(&pConverter->resampler, outputFrameCount);
    } else {
        return outputFrameCount;    /* 1:1 */
    }
}

MA_API ma_uint64 ma_data_converter_get_expected_output_frame_count(ma_data_converter* pConverter, ma_uint64 inputFrameCount)
{
    if (pConverter == NULL) {
        return 0;
    }

    if (pConverter->hasResampler) {
        return ma_resampler_get_expected_output_frame_count(&pConverter->resampler, inputFrameCount);
    } else {
        return inputFrameCount;     /* 1:1 */
    }
}

MA_API ma_uint64 ma_data_converter_get_input_latency(ma_data_converter* pConverter)
{
    if (pConverter == NULL) {
        return 0;
    }

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

    return MA_FALSE;
}



/**************************************************************************************************************************************************************

Conversion Helpers

**************************************************************************************************************************************************************/
MA_API ma_uint64 ma_convert_frames(void* pOut, ma_uint64 frameCountOut, ma_format formatOut, ma_uint32 channelsOut, ma_uint32 sampleRateOut, const void* pIn, ma_uint64 frameCountIn, ma_format formatIn, ma_uint32 channelsIn, ma_uint32 sampleRateIn)
{
    ma_data_converter_config config;

    config = ma_data_converter_config_init(formatIn, formatOut, channelsIn, channelsOut, sampleRateIn, sampleRateOut);
    ma_get_standard_channel_map(ma_standard_channel_map_default, channelsOut, config.channelMapOut);
    ma_get_standard_channel_map(ma_standard_channel_map_default, channelsIn,  config.channelMapIn);
    config.resampling.linear.lpfOrder = ma_min(MA_DEFAULT_RESAMPLER_LPF_ORDER, MA_MAX_FILTER_ORDER);

    return ma_convert_frames_ex(pOut, frameCountOut, pIn, frameCountIn, &config);
}

MA_API ma_uint64 ma_convert_frames_ex(void* pOut, ma_uint64 frameCountOut, const void* pIn, ma_uint64 frameCountIn, const ma_data_converter_config* pConfig)
{
    ma_result result;
    ma_data_converter converter;

    if (frameCountIn == 0 || pConfig == NULL) {
        return 0;
    }

    result = ma_data_converter_init(pConfig, &converter);
    if (result != MA_SUCCESS) {
        return 0;   /* Failed to initialize the data converter. */
    }

    if (pOut == NULL) {
        frameCountOut = ma_data_converter_get_expected_output_frame_count(&converter, frameCountIn);
    } else {
        result = ma_data_converter_process_pcm_frames(&converter, pIn, &frameCountIn, pOut, &frameCountOut);
        if (result != MA_SUCCESS) {
            frameCountOut = 0;
        }
    }

    ma_data_converter_uninit(&converter);
    return frameCountOut;
}


/**************************************************************************************************************************************************************

Ring Buffer

**************************************************************************************************************************************************************/
static MA_INLINE ma_uint32 ma_rb__extract_offset_in_bytes(ma_uint32 encodedOffset)
{

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

    }

    return ma_offset_ptr(pBuffer, ma_rb_get_subbuffer_offset(pRB, subbufferIndex));
}


static MA_INLINE ma_uint32 ma_pcm_rb_get_bpf(ma_pcm_rb* pRB)
{
    MA_ASSERT(pRB != NULL);

    return ma_get_bytes_per_frame(pRB->format, pRB->channels);
}

MA_API ma_result ma_pcm_rb_init_ex(ma_format format, ma_uint32 channels, ma_uint32 subbufferSizeInFrames, ma_uint32 subbufferCount, ma_uint32 subbufferStrideInFrames, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallba...
{
    ma_uint32 bpf;
    ma_result result;

    if (pRB == NULL) {
        return MA_INVALID_ARGS;
    }

    MA_ZERO_OBJECT(pRB);

    bpf = ma_get_bytes_per_frame(format, channels);
    if (bpf == 0) {
        return MA_INVALID_ARGS;
    }

    result = ma_rb_init_ex(subbufferSizeInFrames*bpf, subbufferCount, subbufferStrideInFrames*bpf, pOptionalPreallocatedBuffer, pAllocationCallbacks, &pRB->rb);
    if (result != MA_SUCCESS) {
        return result;
    }

    pRB->format   = format;

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

        2,  /* s16 */
        3,  /* s24 */
        4,  /* s32 */
        4,  /* f32 */
    };
    return sizes[format];
}



MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead, ma_bool32 loop)
{
    ma_data_source_callbacks* pCallbacks = (ma_data_source_callbacks*)pDataSource;
    if (pCallbacks == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pCallbacks->onRead == NULL) {
        return MA_NOT_IMPLEMENTED;
    }

    /* A very small optimization for the non looping case. */
    if (loop == MA_FALSE) {
        return pCallbacks->onRead(pDataSource, pFramesOut, frameCount, pFramesRead);
    } else {
        ma_format format;
        ma_uint32 channels;
        ma_uint32 sampleRate;
        if (ma_data_source_get_data_format(pDataSource, &format, &channels, &sampleRate) != MA_SUCCESS) {
            return pCallbacks->onRead(pDataSource, pFramesOut, frameCount, pFramesRead); /* We don't have a way to retrieve the data format which means we don't know how to offset the output buffer. Just read as much as we can. */
        } else {
            ma_result result = MA_SUCCESS;
            ma_uint64 totalFramesProcessed;
            void* pRunningFramesOut = pFramesOut;

            totalFramesProcessed = 0;
            while (totalFramesProcessed < frameCount) {
                ma_uint64 framesProcessed;
                ma_uint64 framesRemaining = frameCount - totalFramesProcessed;

                result = pCallbacks->onRead(pDataSource, pRunningFramesOut, framesRemaining, &framesProcessed);
                totalFramesProcessed += framesProcessed;

                /*
                If we encounted an error from the read callback, make sure it's propagated to the caller. The caller may need to know whether or not MA_BUSY is returned which is
                not necessarily considered an error. 
                */
                if (result != MA_SUCCESS && result != MA_AT_END) {
                    break;
                }

                /*
                We can determine if we've reached the end by checking the return value of the onRead() callback. If it's less than what we requested it means
                we've reached the end. To loop back to the start, all we need to do is seek back to the first frame.
                */
                if (framesProcessed < framesRemaining || result == MA_AT_END) {
                    if (ma_data_source_seek_to_pcm_frame(pDataSource, 0) != MA_SUCCESS) {
                        break;
                    }
                }

                if (pRunningFramesOut != NULL) {
                    pRunningFramesOut = ma_offset_ptr(pRunningFramesOut, framesProcessed * ma_get_bytes_per_frame(format, channels));
                }
            }

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

            return result;
        }
    }
}

MA_API ma_result ma_data_source_seek_pcm_frames(ma_data_source* pDataSource, ma_uint64 frameCount, ma_uint64* pFramesSeeked, ma_bool32 loop)
{
    return ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount, pFramesSeeked, loop);
}

MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    ma_data_source_callbacks* pCallbacks = (ma_data_source_callbacks*)pDataSource;
    if (pCallbacks == NULL || pCallbacks->onSeek == NULL) {
        return MA_INVALID_ARGS;
    }

    return pCallbacks->onSeek(pDataSource, frameIndex);
}

MA_API ma_result ma_data_source_map(ma_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount)
{
    ma_data_source_callbacks* pCallbacks = (ma_data_source_callbacks*)pDataSource;
    if (pCallbacks == NULL || pCallbacks->onMap == NULL) {
        return MA_INVALID_ARGS;
    }

    return pCallbacks->onMap(pDataSource, ppFramesOut, pFrameCount);
}

MA_API ma_result ma_data_source_unmap(ma_data_source* pDataSource, ma_uint64 frameCount)
{
    ma_data_source_callbacks* pCallbacks = (ma_data_source_callbacks*)pDataSource;
    if (pCallbacks == NULL || pCallbacks->onUnmap == NULL) {
        return MA_INVALID_ARGS;
    }

    return pCallbacks->onUnmap(pDataSource, frameCount);
}

MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate)
{
    ma_result result;
    ma_format format;
    ma_uint32 channels;
    ma_uint32 sampleRate;
    ma_data_source_callbacks* pCallbacks = (ma_data_source_callbacks*)pDataSource;

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

    if (pChannels != NULL) {
        *pChannels = channels;
    }
    if (pSampleRate != NULL) {
        *pSampleRate = sampleRate;
    }

    return MA_SUCCESS;
}

MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor)
{
    ma_data_source_callbacks* pCallbacks = (ma_data_source_callbacks*)pDataSource;

    if (pCursor == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = 0;

    if (pCallbacks == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pCallbacks->onGetCursor == NULL) {
        return MA_NOT_IMPLEMENTED;
    }

    return pCallbacks->onGetCursor(pDataSource, pCursor);
}

MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLength)
{
    ma_data_source_callbacks* pCallbacks = (ma_data_source_callbacks*)pDataSource;

    if (pLength == NULL) {
        return MA_INVALID_ARGS;
    }

    *pLength = 0;

    if (pCallbacks == NULL) {

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

    config.format = format;
    config.channels = channels;
    config.sizeInFrames = sizeInFrames;
    config.pData = pData;
    ma_allocation_callbacks_init_copy(&config.allocationCallbacks, pAllocationCallbacks);

    return config;
}


static ma_result ma_audio_buffer__data_source_on_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_uint64 framesRead = ma_audio_buffer_read_pcm_frames((ma_audio_buffer*)pDataSource, pFramesOut, frameCount, MA_FALSE);

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

    if (framesRead < frameCount) {
        return MA_AT_END;
    }

    return MA_SUCCESS;
}

static ma_result ma_audio_buffer__data_source_on_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    return ma_audio_buffer_seek_to_pcm_frame((ma_audio_buffer*)pDataSource, frameIndex);
}

static ma_result ma_audio_buffer__data_source_on_map(ma_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount)
{
    return ma_audio_buffer_map((ma_audio_buffer*)pDataSource, ppFramesOut, pFrameCount);
}

static ma_result ma_audio_buffer__data_source_on_unmap(ma_data_source* pDataSource, ma_uint64 frameCount)
{
    return ma_audio_buffer_unmap((ma_audio_buffer*)pDataSource, frameCount);
}

static ma_result ma_audio_buffer__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate)
{
    ma_audio_buffer* pAudioBuffer = (ma_audio_buffer*)pDataSource;

    *pFormat     = pAudioBuffer->format;
    *pChannels   = pAudioBuffer->channels;
    *pSampleRate = 0;   /* There is no notion of a sample rate with audio buffers. */

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

        return MA_INVALID_ARGS;
    }

    MA_ZERO_MEMORY(pAudioBuffer, sizeof(*pAudioBuffer) - sizeof(pAudioBuffer->_pExtraData));   /* Safety. Don't overwrite the extra data. */

    if (pConfig == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pConfig->sizeInFrames == 0) {
        return MA_INVALID_ARGS; /* Not allowing buffer sizes of 0 frames. */
    }

    pAudioBuffer->ds.onRead          = ma_audio_buffer__data_source_on_read;
    pAudioBuffer->ds.onSeek          = ma_audio_buffer__data_source_on_seek;
    pAudioBuffer->ds.onMap           = ma_audio_buffer__data_source_on_map;
    pAudioBuffer->ds.onUnmap         = ma_audio_buffer__data_source_on_unmap;
    pAudioBuffer->ds.onGetDataFormat = ma_audio_buffer__data_source_on_get_data_format;
    pAudioBuffer->ds.onGetCursor     = ma_audio_buffer__data_source_on_get_cursor;
    pAudioBuffer->ds.onGetLength     = ma_audio_buffer__data_source_on_get_length;
    pAudioBuffer->format             = pConfig->format;
    pAudioBuffer->channels           = pConfig->channels;
    pAudioBuffer->cursor             = 0;
    pAudioBuffer->sizeInFrames       = pConfig->sizeInFrames;
    pAudioBuffer->pData              = NULL;  /* Set properly later. */
    ma_allocation_callbacks_init_copy(&pAudioBuffer->allocationCallbacks, &pConfig->allocationCallbacks);

    if (doCopy) {
        ma_uint64 allocationSizeInBytes;
        void* pData;

        allocationSizeInBytes = pAudioBuffer->sizeInFrames * ma_get_bytes_per_frame(pAudioBuffer->format, pAudioBuffer->channels);
        if (allocationSizeInBytes > MA_SIZE_MAX) {
            return MA_OUT_OF_MEMORY;    /* Too big. */
        }

        pData = ma__malloc_from_callbacks((size_t)allocationSizeInBytes, &pAudioBuffer->allocationCallbacks);   /* Safe cast to size_t. */
        if (pData == NULL) {
            return MA_OUT_OF_MEMORY;
        }

        if (pConfig->pData != NULL) {
            ma_copy_pcm_frames(pData, pConfig->pData, pAudioBuffer->sizeInFrames, pAudioBuffer->format, pAudioBuffer->channels);
        } else {
            ma_silence_pcm_frames(pData, pAudioBuffer->sizeInFrames, pAudioBuffer->format, pAudioBuffer->channels);
        }

        pAudioBuffer->pData    = pData;
        pAudioBuffer->ownsData = MA_TRUE;
    } else {
        pAudioBuffer->pData    = pConfig->pData;
        pAudioBuffer->ownsData = MA_FALSE;
    }

    return MA_SUCCESS;

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


    *ppAudioBuffer = NULL;  /* Safety. */

    if (pConfig == NULL) {
        return MA_INVALID_ARGS;
    }

    innerConfig = *pConfig;
    ma_allocation_callbacks_init_copy(&innerConfig.allocationCallbacks, &pConfig->allocationCallbacks);

    allocationSizeInBytes = sizeof(*pAudioBuffer) - sizeof(pAudioBuffer->_pExtraData) + (pConfig->sizeInFrames * ma_get_bytes_per_frame(pConfig->format, pConfig->channels));
    if (allocationSizeInBytes > MA_SIZE_MAX) {
        return MA_OUT_OF_MEMORY;    /* Too big. */
    }

    pAudioBuffer = (ma_audio_buffer*)ma__malloc_from_callbacks((size_t)allocationSizeInBytes, &innerConfig.allocationCallbacks);  /* Safe cast to size_t. */
    if (pAudioBuffer == NULL) {
        return MA_OUT_OF_MEMORY;
    }

    if (pConfig->pData != NULL) {
        ma_copy_pcm_frames(&pAudioBuffer->_pExtraData[0], pConfig->pData, pConfig->sizeInFrames, pConfig->format, pConfig->channels);
    } else {
        ma_silence_pcm_frames(&pAudioBuffer->_pExtraData[0], pConfig->sizeInFrames, pConfig->format, pConfig->channels);
    }

    innerConfig.pData = &pAudioBuffer->_pExtraData[0];

    result = ma_audio_buffer_init_ex(&innerConfig, MA_FALSE, pAudioBuffer);
    if (result != MA_SUCCESS) {
        ma__free_from_callbacks(pAudioBuffer, &innerConfig.allocationCallbacks);
        return result;
    }

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

MA_API void ma_audio_buffer_uninit(ma_audio_buffer* pAudioBuffer)
{
    ma_audio_buffer_uninit_ex(pAudioBuffer, MA_FALSE);
}

MA_API void ma_audio_buffer_uninit_and_free(ma_audio_buffer* pAudioBuffer)
{
    ma_audio_buffer_uninit_ex(pAudioBuffer, MA_TRUE);
}

MA_API ma_uint64 ma_audio_buffer_read_pcm_frames(ma_audio_buffer* pAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop)
{
    ma_uint64 totalFramesRead = 0;
    
    if (pAudioBuffer == NULL) {
        return 0;
    }

    if (frameCount == 0) {
        return 0;
    }

    while (totalFramesRead < frameCount) {
        ma_uint64 framesAvailable = pAudioBuffer->sizeInFrames - pAudioBuffer->cursor;
        ma_uint64 framesRemaining = frameCount - totalFramesRead;
        ma_uint64 framesToRead;

        framesToRead = framesRemaining;
        if (framesToRead > framesAvailable) {
            framesToRead = framesAvailable;
        }

        if (pFramesOut != NULL) {
            ma_copy_pcm_frames(pFramesOut, ma_offset_ptr(pAudioBuffer->pData, pAudioBuffer->cursor * ma_get_bytes_per_frame(pAudioBuffer->format, pAudioBuffer->channels)), frameCount, pAudioBuffer->format, pAudioBuffer->channels);
        }

        totalFramesRead += framesToRead;

        pAudioBuffer->cursor += framesToRead;
        if (pAudioBuffer->cursor == pAudioBuffer->sizeInFrames) {
            if (loop) {
                pAudioBuffer->cursor = 0;
            } else {
                break;  /* We've reached the end and we're not looping. Done. */
            }
        }

        MA_ASSERT(pAudioBuffer->cursor < pAudioBuffer->sizeInFrames);
    }

    return totalFramesRead;
}

MA_API ma_result ma_audio_buffer_seek_to_pcm_frame(ma_audio_buffer* pAudioBuffer, ma_uint64 frameIndex)
{
    if (pAudioBuffer == NULL) {
        return MA_INVALID_ARGS;
    }

    if (frameIndex > pAudioBuffer->sizeInFrames) {
        return MA_INVALID_ARGS;
    }

    pAudioBuffer->cursor = (size_t)frameIndex;

    return MA_SUCCESS;
}

MA_API ma_result ma_audio_buffer_map(ma_audio_buffer* pAudioBuffer, void** ppFramesOut, ma_uint64* pFrameCount)
{
    ma_uint64 framesAvailable;
    ma_uint64 frameCount = 0;

    if (ppFramesOut != NULL) {
        *ppFramesOut = NULL;    /* Safety. */
    }

    if (pFrameCount != NULL) {
        frameCount = *pFrameCount;
        *pFrameCount = 0;       /* Safety. */
    }

    if (pAudioBuffer == NULL || ppFramesOut == NULL || pFrameCount == NULL) {
        return MA_INVALID_ARGS;
    }

    framesAvailable = pAudioBuffer->sizeInFrames - pAudioBuffer->cursor;
    if (frameCount > framesAvailable) {
        frameCount = framesAvailable;
    }

    *ppFramesOut = ma_offset_ptr(pAudioBuffer->pData, pAudioBuffer->cursor * ma_get_bytes_per_frame(pAudioBuffer->format, pAudioBuffer->channels));
    *pFrameCount = frameCount;

    return MA_SUCCESS;
}

MA_API ma_result ma_audio_buffer_unmap(ma_audio_buffer* pAudioBuffer, ma_uint64 frameCount)
{
    ma_uint64 framesAvailable;

    if (pAudioBuffer == NULL) {
        return MA_INVALID_ARGS;
    }

    framesAvailable = pAudioBuffer->sizeInFrames - pAudioBuffer->cursor;
    if (frameCount > framesAvailable) {
        return MA_INVALID_ARGS;   /* The frame count was too big. This should never happen in an unmapping. Need to make sure the caller is aware of this. */
    }

    pAudioBuffer->cursor += frameCount;

    if (pAudioBuffer->cursor == pAudioBuffer->sizeInFrames) {
        return MA_AT_END;   /* Successful. Need to tell the caller that the end has been reached so that it can loop if desired. */
    } else {
        return MA_SUCCESS;
    }
}

MA_API ma_result ma_audio_buffer_at_end(ma_audio_buffer* pAudioBuffer)
{
    if (pAudioBuffer == NULL) {
        return MA_FALSE;
    }

    return pAudioBuffer->cursor == pAudioBuffer->sizeInFrames;
}

MA_API ma_result ma_audio_buffer_get_available_frames(ma_audio_buffer* pAudioBuffer, ma_uint64* pAvailableFrames)
{
    if (pAvailableFrames == NULL) {
        return MA_INVALID_ARGS;
    }

    *pAvailableFrames = 0;

    if (pAudioBuffer == NULL) {
        return MA_INVALID_ARGS;
    }

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

        drwav_int32  predictor[2];
        drwav_int32  stepIndex[2];
        drwav_int32  cachedFrames[16];
        drwav_uint32 cachedFrameCount;
    } ima;
} drwav;
DRWAV_API drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_ex(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, drwav_chunk_proc onChunk, void* pReadSeekUserData, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_write_sequential(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_write_sequential_pcm_frames(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_uint64 drwav_target_write_size_bytes(const drwav_data_format* pFormat, drwav_uint64 totalSampleCount);
DRWAV_API drwav_result drwav_uninit(drwav* pWav);
DRWAV_API size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_le(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
DRWAV_API drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64 targetFrameIndex);
DRWAV_API size_t drwav_write_raw(drwav* pWav, size_t bytesToWrite, const void* pData);
DRWAV_API drwav_uint64 drwav_write_pcm_frames(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
DRWAV_API drwav_uint64 drwav_write_pcm_frames_le(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
DRWAV_API drwav_uint64 drwav_write_pcm_frames_be(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
#ifndef DR_WAV_NO_CONVERSION_API
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16le(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16be(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut);
DRWAV_API void drwav_u8_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s24_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s32_to_s16(drwav_int16* pOut, const drwav_int32* pIn, size_t sampleCount);
DRWAV_API void drwav_f32_to_s16(drwav_int16* pOut, const float* pIn, size_t sampleCount);
DRWAV_API void drwav_f64_to_s16(drwav_int16* pOut, const double* pIn, size_t sampleCount);
DRWAV_API void drwav_alaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_mulaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32le(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32be(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
DRWAV_API void drwav_u8_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s16_to_f32(float* pOut, const drwav_int16* pIn, size_t sampleCount);
DRWAV_API void drwav_s24_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s32_to_f32(float* pOut, const drwav_int32* pIn, size_t sampleCount);
DRWAV_API void drwav_f64_to_f32(float* pOut, const double* pIn, size_t sampleCount);
DRWAV_API void drwav_alaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_mulaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32le(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32be(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut);
DRWAV_API void drwav_u8_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s16_to_s32(drwav_int32* pOut, const drwav_int16* pIn, size_t sampleCount);
DRWAV_API void drwav_s24_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_f32_to_s32(drwav_int32* pOut, const float* pIn, size_t sampleCount);
DRWAV_API void drwav_f64_to_s32(drwav_int32* pOut, const double* pIn, size_t sampleCount);
DRWAV_API void drwav_alaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_mulaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
#endif
#ifndef DR_WAV_NO_STDIO
DRWAV_API drwav_bool32 drwav_init_file(drwav* pWav, const char* filename, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_ex(drwav* pWav, const char* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_w(drwav* pWav, const wchar_t* filename, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_ex_w(drwav* pWav, const wchar_t* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_sequential(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
#endif
DRWAV_API drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, size_t dataSize, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_ex(drwav* pWav, const void* data, size_t dataSize, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential_pcm_frames(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
#ifndef DR_WAV_NO_CONVERSION_API
DRWAV_API drwav_int16* drwav_open_and_read_pcm_frames_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAl...
DRWAV_API float* drwav_open_and_read_pcm_frames_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocati...
DRWAV_API drwav_int32* drwav_open_and_read_pcm_frames_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAl...
#ifndef DR_WAV_NO_STDIO
DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
#endif
DRWAV_API drwav_int16* drwav_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API float* drwav_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int32* drwav_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
#endif
DRWAV_API void drwav_free(void* p, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_uint16 drwav_bytes_to_u16(const drwav_uint8* data);
DRWAV_API drwav_int16 drwav_bytes_to_s16(const drwav_uint8* data);
DRWAV_API drwav_uint32 drwav_bytes_to_u32(const drwav_uint8* data);
DRWAV_API drwav_int32 drwav_bytes_to_s32(const drwav_uint8* data);
DRWAV_API drwav_uint64 drwav_bytes_to_u64(const drwav_uint8* data);
DRWAV_API drwav_int64 drwav_bytes_to_s64(const drwav_uint8* data);
DRWAV_API drwav_bool32 drwav_guid_equal(const drwav_uint8 a[16], const drwav_uint8 b[16]);
DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b);

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

    drflac_uint32 nextL2Line;
    drflac_uint32 consumedBits;
    drflac_cache_t cacheL2[DR_FLAC_BUFFER_SIZE/sizeof(drflac_cache_t)];
    drflac_cache_t cache;
    drflac_uint16 crc16;
    drflac_cache_t crc16Cache;
    drflac_uint32 crc16CacheIgnoredBytes;
} drflac_bs;
typedef struct
{
    drflac_uint8 subframeType;
    drflac_uint8 wastedBitsPerSample;
    drflac_uint8 lpcOrder;
    drflac_int32* pSamplesS32;
} drflac_subframe;
typedef struct
{
    drflac_uint64 pcmFrameNumber;
    drflac_uint32 flacFrameNumber;
    drflac_uint32 sampleRate;
    drflac_uint16 blockSizeInPCMFrames;
    drflac_uint8 channelAssignment;
    drflac_uint8 bitsPerSample;
    drflac_uint8 crc8;
} drflac_frame_header;
typedef struct
{
    drflac_frame_header header;
    drflac_uint32 pcmFramesRemaining;
    drflac_subframe subframes[8];
} drflac_frame;
typedef struct
{
    drflac_meta_proc onMeta;
    void* pUserDataMD;
    drflac_allocation_callbacks allocationCallbacks;
    drflac_uint32 sampleRate;
    drflac_uint8 channels;
    drflac_uint8 bitsPerSample;
    drflac_uint16 maxBlockSizeInPCMFrames;
    drflac_uint64 totalPCMFrameCount;
    drflac_container container;
    drflac_uint32 seekpointCount;
    drflac_frame currentFLACFrame;
    drflac_uint64 currentPCMFrame;
    drflac_uint64 firstFLACFramePosInBytes;
    drflac__memory_stream memoryStream;
    drflac_int32* pDecodedSamples;
    drflac_seekpoint* pSeekpoints;
    void* _oggbs;
    drflac_bool32 _noSeekTableSeek    : 1;
    drflac_bool32 _noBinarySearchSeek : 1;
    drflac_bool32 _noBruteForceSeek   : 1;
    drflac_bs bs;
    drflac_uint8 pExtraData[1];
} drflac;
DRFLAC_API drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API void drflac_close(drflac* pFlac);
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut);
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut);
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut);
DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex);
#ifndef DR_FLAC_NO_STDIO
DRFLAC_API drflac* drflac_open_file(const char* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_file_with_metadata(const char* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_file_with_metadata_w(const wchar_t* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
#endif
DRFLAC_API drflac* drflac_open_memory(const void* pData, size_t dataSize, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_memory_with_metadata(const void* pData, size_t dataSize, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pA...
DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pA...
DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocati...
#ifndef DR_FLAC_NO_STDIO
DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
#endif
DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API void drflac_free(void* p, const drflac_allocation_callbacks* pAllocationCallbacks);
typedef struct
{
    drflac_uint32 countRemaining;
    const char* pRunningData;
} drflac_vorbis_comment_iterator;
DRFLAC_API void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments);
DRFLAC_API const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut);
typedef struct
{

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

    #else
        #define DRMP3_INLINE inline __attribute__((always_inline))
    #endif
#else
    #define DRMP3_INLINE
#endif
DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision);
DRMP3_API const char* drmp3_version_string(void);
typedef struct
{
    int frame_bytes, channels, hz, layer, bitrate_kbps;
} drmp3dec_frame_info;
typedef struct
{
    float mdct_overlap[2][9*32], qmf_state[15*2*32];
    int reserv, free_format_bytes;
    drmp3_uint8 header[4], reserv_buf[511];
} drmp3dec;
DRMP3_API void drmp3dec_init(drmp3dec *dec);
DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info);
DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples);
#ifndef DRMP3_DEFAULT_CHANNELS
#define DRMP3_DEFAULT_CHANNELS      2
#endif
#ifndef DRMP3_DEFAULT_SAMPLE_RATE
#define DRMP3_DEFAULT_SAMPLE_RATE   44100
#endif
typedef enum
{
    drmp3_seek_origin_start,

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

    void  (* onFree)(void* p, void* pUserData);
} drmp3_allocation_callbacks;
typedef struct
{
    drmp3_uint32 channels;
    drmp3_uint32 sampleRate;
} drmp3_config;
typedef struct
{
    drmp3dec decoder;
    drmp3dec_frame_info frameInfo;
    drmp3_uint32 channels;
    drmp3_uint32 sampleRate;
    drmp3_read_proc onRead;
    drmp3_seek_proc onSeek;
    void* pUserData;
    drmp3_allocation_callbacks allocationCallbacks;
    drmp3_uint32 mp3FrameChannels;
    drmp3_uint32 mp3FrameSampleRate;
    drmp3_uint32 pcmFramesConsumedInMP3Frame;
    drmp3_uint32 pcmFramesRemainingInMP3Frame;

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

        size_t currentReadPos;
    } memory;
} drmp3;
DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks);
#ifndef DR_MP3_NO_STDIO
DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
#endif
DRMP3_API void drmp3_uninit(drmp3* pMP3);
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut);
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut);
DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex);
DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3);
DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3);
DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount);
DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints);
DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints);
DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
#ifndef DR_MP3_NO_STDIO
DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
#endif
DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks);
#ifdef __cplusplus
}
#endif
#endif
/* dr_mp3_h end */
#endif  /* MA_NO_MP3 */

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

}

static drwav_bool32 ma_decoder_internal_on_seek__wav(void* pUserData, int offset, drwav_seek_origin origin)
{
    ma_decoder* pDecoder = (ma_decoder*)pUserData;
    MA_ASSERT(pDecoder != NULL);

    return ma_decoder_seek_bytes(pDecoder, offset, (origin == drwav_seek_origin_start) ? ma_seek_origin_start : ma_seek_origin_current);
}

static ma_uint64 ma_decoder_internal_on_read_pcm_frames__wav(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount)
{
    drwav* pWav;

    MA_ASSERT(pDecoder   != NULL);
    MA_ASSERT(pFramesOut != NULL);

    pWav = (drwav*)pDecoder->pInternalDecoder;
    MA_ASSERT(pWav != NULL);

    switch (pDecoder->internalFormat) {
        case ma_format_s16: return drwav_read_pcm_frames_s16(pWav, frameCount, (drwav_int16*)pFramesOut);
        case ma_format_s32: return drwav_read_pcm_frames_s32(pWav, frameCount, (drwav_int32*)pFramesOut);
        case ma_format_f32: return drwav_read_pcm_frames_f32(pWav, frameCount,       (float*)pFramesOut);
        default: break;
    }

    /* Should never get here. If we do, it means the internal format was not set correctly at initialization time. */
    MA_ASSERT(MA_FALSE);
    return 0;
}

static ma_result ma_decoder_internal_on_seek_to_pcm_frame__wav(ma_decoder* pDecoder, ma_uint64 frameIndex)
{
    drwav* pWav;
    drwav_bool32 result;

    pWav = (drwav*)pDecoder->pInternalDecoder;
    MA_ASSERT(pWav != NULL);

    result = drwav_seek_to_pcm_frame(pWav, frameIndex);
    if (result) {
        return MA_SUCCESS;
    } else {
        return MA_ERROR;
    }
}

static ma_result ma_decoder_internal_on_uninit__wav(ma_decoder* pDecoder)
{
    drwav_uninit((drwav*)pDecoder->pInternalDecoder);
    ma__free_from_callbacks(pDecoder->pInternalDecoder, &pDecoder->allocationCallbacks);
    return MA_SUCCESS;
}

static ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__wav(ma_decoder* pDecoder)
{
    return ((drwav*)pDecoder->pInternalDecoder)->totalPCMFrameCount;
}

static ma_result ma_decoder_init_wav__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
    drwav* pWav;
    drwav_allocation_callbacks allocationCallbacks;

    MA_ASSERT(pConfig != NULL);

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

    allocationCallbacks.onRealloc = pDecoder->allocationCallbacks.onRealloc;
    allocationCallbacks.onFree    = pDecoder->allocationCallbacks.onFree;

    /* Try opening the decoder first. */
    if (!drwav_init(pWav, ma_decoder_internal_on_read__wav, ma_decoder_internal_on_seek__wav, pDecoder, &allocationCallbacks)) {
        ma__free_from_callbacks(pWav, &pDecoder->allocationCallbacks);
        return MA_ERROR;
    }

    /* If we get here it means we successfully initialized the WAV decoder. We can now initialize the rest of the ma_decoder. */
    pDecoder->onReadPCMFrames        = ma_decoder_internal_on_read_pcm_frames__wav;
    pDecoder->onSeekToPCMFrame       = ma_decoder_internal_on_seek_to_pcm_frame__wav;
    pDecoder->onUninit               = ma_decoder_internal_on_uninit__wav;
    pDecoder->onGetLengthInPCMFrames = ma_decoder_internal_on_get_length_in_pcm_frames__wav;
    pDecoder->pInternalDecoder       = pWav;

    /* Try to be as optimal as possible for the internal format. If miniaudio does not support a format we will fall back to f32. */
    pDecoder->internalFormat = ma_format_unknown;
    switch (pWav->translatedFormatTag) {
        case DR_WAVE_FORMAT_PCM:
        {
            if (pWav->bitsPerSample == 8) {
                pDecoder->internalFormat = ma_format_s16;
            } else if (pWav->bitsPerSample == 16) {

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

}

static drflac_bool32 ma_decoder_internal_on_seek__flac(void* pUserData, int offset, drflac_seek_origin origin)
{
    ma_decoder* pDecoder = (ma_decoder*)pUserData;
    MA_ASSERT(pDecoder != NULL);

    return ma_decoder_seek_bytes(pDecoder, offset, (origin == drflac_seek_origin_start) ? ma_seek_origin_start : ma_seek_origin_current);
}

static ma_uint64 ma_decoder_internal_on_read_pcm_frames__flac(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount)
{
    drflac* pFlac;

    MA_ASSERT(pDecoder   != NULL);
    MA_ASSERT(pFramesOut != NULL);

    pFlac = (drflac*)pDecoder->pInternalDecoder;
    MA_ASSERT(pFlac != NULL);

    switch (pDecoder->internalFormat) {
        case ma_format_s16: return drflac_read_pcm_frames_s16(pFlac, frameCount, (drflac_int16*)pFramesOut);
        case ma_format_s32: return drflac_read_pcm_frames_s32(pFlac, frameCount, (drflac_int32*)pFramesOut);
        case ma_format_f32: return drflac_read_pcm_frames_f32(pFlac, frameCount,        (float*)pFramesOut);
        default: break;
    }

    /* Should never get here. If we do, it means the internal format was not set correctly at initialization time. */
    MA_ASSERT(MA_FALSE);
    return 0;
}

static ma_result ma_decoder_internal_on_seek_to_pcm_frame__flac(ma_decoder* pDecoder, ma_uint64 frameIndex)
{
    drflac* pFlac;
    drflac_bool32 result;

    pFlac = (drflac*)pDecoder->pInternalDecoder;
    MA_ASSERT(pFlac != NULL);

    result = drflac_seek_to_pcm_frame(pFlac, frameIndex);
    if (result) {
        return MA_SUCCESS;
    } else {
        return MA_ERROR;
    }
}

static ma_result ma_decoder_internal_on_uninit__flac(ma_decoder* pDecoder)
{
    drflac_close((drflac*)pDecoder->pInternalDecoder);
    return MA_SUCCESS;
}

static ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__flac(ma_decoder* pDecoder)
{
    return ((drflac*)pDecoder->pInternalDecoder)->totalPCMFrameCount;
}

static ma_result ma_decoder_init_flac__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
    drflac* pFlac;
    drflac_allocation_callbacks allocationCallbacks;

    MA_ASSERT(pConfig  != NULL);

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

    allocationCallbacks.onRealloc = pDecoder->allocationCallbacks.onRealloc;
    allocationCallbacks.onFree    = pDecoder->allocationCallbacks.onFree;

    /* Try opening the decoder first. */
    pFlac = drflac_open(ma_decoder_internal_on_read__flac, ma_decoder_internal_on_seek__flac, pDecoder, &allocationCallbacks);
    if (pFlac == NULL) {
        return MA_ERROR;
    }

    /* If we get here it means we successfully initialized the FLAC decoder. We can now initialize the rest of the ma_decoder. */
    pDecoder->onReadPCMFrames        = ma_decoder_internal_on_read_pcm_frames__flac;
    pDecoder->onSeekToPCMFrame       = ma_decoder_internal_on_seek_to_pcm_frame__flac;
    pDecoder->onUninit               = ma_decoder_internal_on_uninit__flac;
    pDecoder->onGetLengthInPCMFrames = ma_decoder_internal_on_get_length_in_pcm_frames__flac;
    pDecoder->pInternalDecoder       = pFlac;

    /*
    dr_flac supports reading as s32, s16 and f32. Try to do a one-to-one mapping if possible, but fall back to s32 if not. s32 is the "native" FLAC format
    since it's the only one that's truly lossless. If the internal bits per sample is <= 16 we will decode to ma_format_s16 to keep it more efficient.
    */
    if (pConfig->format == ma_format_unknown) {
        if (pFlac->bitsPerSample <= 16) {
            pDecoder->internalFormat = ma_format_s16;
        } else {

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

}

static drmp3_bool32 ma_decoder_internal_on_seek__mp3(void* pUserData, int offset, drmp3_seek_origin origin)
{
    ma_decoder* pDecoder = (ma_decoder*)pUserData;
    MA_ASSERT(pDecoder != NULL);

    return ma_decoder_seek_bytes(pDecoder, offset, (origin == drmp3_seek_origin_start) ? ma_seek_origin_start : ma_seek_origin_current);
}

static ma_uint64 ma_decoder_internal_on_read_pcm_frames__mp3(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount)
{
    drmp3* pMP3;

    MA_ASSERT(pDecoder   != NULL);
    MA_ASSERT(pFramesOut != NULL);

    pMP3 = (drmp3*)pDecoder->pInternalDecoder;
    MA_ASSERT(pMP3 != NULL);

#if defined(DR_MP3_FLOAT_OUTPUT)
    MA_ASSERT(pDecoder->internalFormat == ma_format_f32);
    return drmp3_read_pcm_frames_f32(pMP3, frameCount, (float*)pFramesOut);
#else
    MA_ASSERT(pDecoder->internalFormat == ma_format_s16);
    return drmp3_read_pcm_frames_s16(pMP3, frameCount, (drmp3_int16*)pFramesOut);
#endif
}

static ma_result ma_decoder_internal_on_seek_to_pcm_frame__mp3(ma_decoder* pDecoder, ma_uint64 frameIndex)
{
    drmp3* pMP3;
    drmp3_bool32 result;

    pMP3 = (drmp3*)pDecoder->pInternalDecoder;
    MA_ASSERT(pMP3 != NULL);

    result = drmp3_seek_to_pcm_frame(pMP3, frameIndex);
    if (result) {
        return MA_SUCCESS;
    } else {
        return MA_ERROR;
    }
}

static ma_result ma_decoder_internal_on_uninit__mp3(ma_decoder* pDecoder)
{
    drmp3_uninit((drmp3*)pDecoder->pInternalDecoder);
    ma__free_from_callbacks(pDecoder->pInternalDecoder, &pDecoder->allocationCallbacks);
    return MA_SUCCESS;
}

static ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__mp3(ma_decoder* pDecoder)
{
    return drmp3_get_pcm_frame_count((drmp3*)pDecoder->pInternalDecoder);
}

static ma_result ma_decoder_init_mp3__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
    drmp3* pMP3;
    drmp3_allocation_callbacks allocationCallbacks;

    MA_ASSERT(pConfig != NULL);
    MA_ASSERT(pDecoder != NULL);

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

    /*
    Try opening the decoder first. We always use whatever dr_mp3 reports for channel count and sample rate. The format is determined by
    the presence of DR_MP3_FLOAT_OUTPUT.
    */
    if (!drmp3_init(pMP3, ma_decoder_internal_on_read__mp3, ma_decoder_internal_on_seek__mp3, pDecoder, &allocationCallbacks)) {
        ma__free_from_callbacks(pMP3, &pDecoder->allocationCallbacks);
        return MA_ERROR;
    }

    /* If we get here it means we successfully initialized the MP3 decoder. We can now initialize the rest of the ma_decoder. */
    pDecoder->onReadPCMFrames        = ma_decoder_internal_on_read_pcm_frames__mp3;
    pDecoder->onSeekToPCMFrame       = ma_decoder_internal_on_seek_to_pcm_frame__mp3;
    pDecoder->onUninit               = ma_decoder_internal_on_uninit__mp3;
    pDecoder->onGetLengthInPCMFrames = ma_decoder_internal_on_get_length_in_pcm_frames__mp3;
    pDecoder->pInternalDecoder       = pMP3;

    /* Internal format. */
#if defined(DR_MP3_FLOAT_OUTPUT)
    pDecoder->internalFormat     = ma_format_f32;
#else
    pDecoder->internalFormat     = ma_format_s16;
#endif
    pDecoder->internalChannels   = pMP3->channels;
    pDecoder->internalSampleRate = pMP3->sampleRate;

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


/* The size in bytes of each chunk of data to read from the Vorbis stream. */
#define MA_VORBIS_DATA_CHUNK_SIZE  4096

typedef struct
{
    stb_vorbis* pInternalVorbis;
    ma_uint8* pData;
    size_t dataSize;
    size_t dataCapacity;
    ma_uint32 framesConsumed;  /* The number of frames consumed in ppPacketData. */
    ma_uint32 framesRemaining; /* The number of frames remaining in ppPacketData. */
    float** ppPacketData;
} ma_vorbis_decoder;

static ma_uint64 ma_vorbis_decoder_read_pcm_frames(ma_vorbis_decoder* pVorbis, ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount)
{
    float* pFramesOutF;
    ma_uint64 totalFramesRead;

    MA_ASSERT(pVorbis  != NULL);
    MA_ASSERT(pDecoder != NULL);

    pFramesOutF = (float*)pFramesOut;

    totalFramesRead = 0;
    while (frameCount > 0) {
        /* Read from the in-memory buffer first. */
        ma_uint32 framesToReadFromCache = (ma_uint32)ma_min(pVorbis->framesRemaining, frameCount);  /* Safe cast because pVorbis->framesRemaining is 32-bit. */

        if (pFramesOut != NULL) {
            ma_uint64 iFrame;
            for (iFrame = 0; iFrame < framesToReadFromCache; iFrame += 1) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < pDecoder->internalChannels; ++iChannel) {
                    pFramesOutF[iChannel] = pVorbis->ppPacketData[iChannel][pVorbis->framesConsumed+iFrame];   
                }
                pFramesOutF += pDecoder->internalChannels;
            }
        }

        pVorbis->framesConsumed  += framesToReadFromCache;
        pVorbis->framesRemaining -= framesToReadFromCache;
        frameCount               -= framesToReadFromCache;
        totalFramesRead          += framesToReadFromCache;

        if (frameCount == 0) {
            break;
        }

        MA_ASSERT(pVorbis->framesRemaining == 0);

        /* We've run out of cached frames, so decode the next packet and continue iteration. */
        do
        {
            int samplesRead;
            int consumedDataSize;

            if (pVorbis->dataSize > INT_MAX) {
                break;  /* Too big. */
            }

            samplesRead = 0;
            consumedDataSize = stb_vorbis_decode_frame_pushdata(pVorbis->pInternalVorbis, pVorbis->pData, (int)pVorbis->dataSize, NULL, (float***)&pVorbis->ppPacketData, &samplesRead);
            if (consumedDataSize != 0) {
                size_t leftoverDataSize = (pVorbis->dataSize - (size_t)consumedDataSize);
                size_t i;
                for (i = 0; i < leftoverDataSize; ++i) {
                    pVorbis->pData[i] = pVorbis->pData[i + consumedDataSize];
                }

                pVorbis->dataSize = leftoverDataSize;
                pVorbis->framesConsumed = 0;
                pVorbis->framesRemaining = samplesRead;
                break;
            } else {
                /* Need more data. If there's any room in the existing buffer allocation fill that first. Otherwise expand. */
                size_t bytesRead;
                if (pVorbis->dataCapacity == pVorbis->dataSize) {
                    /* No room. Expand. */
                    size_t oldCap = pVorbis->dataCapacity;
                    size_t newCap = pVorbis->dataCapacity + MA_VORBIS_DATA_CHUNK_SIZE;
                    ma_uint8* pNewData;

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

                }

                pVorbis->dataSize += bytesRead;
            }
        } while (MA_TRUE);
    }

    return totalFramesRead;
}

static ma_result ma_vorbis_decoder_seek_to_pcm_frame(ma_vorbis_decoder* pVorbis, ma_decoder* pDecoder, ma_uint64 frameIndex)
{
    float buffer[4096];

    MA_ASSERT(pVorbis != NULL);
    MA_ASSERT(pDecoder != NULL);

    /*
    This is terribly inefficient because stb_vorbis does not have a good seeking solution with it's push API. Currently this just performs
    a full decode right from the start of the stream. Later on I'll need to write a layer that goes through all of the Ogg pages until we
    find the one containing the sample we need. Then we know exactly where to seek for stb_vorbis.

    TODO: Use seeking logic documented for stb_vorbis_flush_pushdata().
    */
    if (!ma_decoder_seek_bytes(pDecoder, 0, ma_seek_origin_start)) {
        return MA_ERROR;
    }

    stb_vorbis_flush_pushdata(pVorbis->pInternalVorbis);
    pVorbis->framesConsumed  = 0;
    pVorbis->framesRemaining = 0;
    pVorbis->dataSize        = 0;

    while (frameIndex > 0) {
        ma_uint32 framesRead;
        ma_uint32 framesToRead = ma_countof(buffer)/pDecoder->internalChannels;
        if (framesToRead > frameIndex) {
            framesToRead = (ma_uint32)frameIndex;
        }

        framesRead = (ma_uint32)ma_vorbis_decoder_read_pcm_frames(pVorbis, pDecoder, buffer, framesToRead);
        if (framesRead == 0) {
            return MA_ERROR;
        }

        frameIndex -= framesRead;
    }

    return MA_SUCCESS;
}


static ma_result ma_decoder_internal_on_seek_to_pcm_frame__vorbis(ma_decoder* pDecoder, ma_uint64 frameIndex)
{
    ma_vorbis_decoder* pVorbis = (ma_vorbis_decoder*)pDecoder->pInternalDecoder;
    MA_ASSERT(pVorbis != NULL);

    return ma_vorbis_decoder_seek_to_pcm_frame(pVorbis, pDecoder, frameIndex);
}

static ma_result ma_decoder_internal_on_uninit__vorbis(ma_decoder* pDecoder)
{
    ma_vorbis_decoder* pVorbis = (ma_vorbis_decoder*)pDecoder->pInternalDecoder;
    MA_ASSERT(pVorbis != NULL);

    stb_vorbis_close(pVorbis->pInternalVorbis);
    ma__free_from_callbacks(pVorbis->pData, &pDecoder->allocationCallbacks);
    ma__free_from_callbacks(pVorbis,        &pDecoder->allocationCallbacks);

    return MA_SUCCESS;
}

static ma_uint64 ma_decoder_internal_on_read_pcm_frames__vorbis(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount)
{
    ma_vorbis_decoder* pVorbis;

    MA_ASSERT(pDecoder   != NULL);
    MA_ASSERT(pFramesOut != NULL);
    MA_ASSERT(pDecoder->internalFormat == ma_format_f32);

    pVorbis = (ma_vorbis_decoder*)pDecoder->pInternalDecoder;
    MA_ASSERT(pVorbis != NULL);

    return ma_vorbis_decoder_read_pcm_frames(pVorbis, pDecoder, pFramesOut, frameCount);
}

static ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__vorbis(ma_decoder* pDecoder)
{
    /* No good way to do this with Vorbis. */
    (void)pDecoder;
    return 0;
}

static ma_result ma_decoder_init_vorbis__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
    stb_vorbis* pInternalVorbis = NULL;
    size_t dataSize = 0;

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

    /* If we get here it means we successfully opened the Vorbis decoder. */
    vorbisInfo = stb_vorbis_get_info(pInternalVorbis);

    /* Don't allow more than MA_MAX_CHANNELS channels. */
    if (vorbisInfo.channels > MA_MAX_CHANNELS) {
        stb_vorbis_close(pInternalVorbis);
        ma__free_from_callbacks(pData, &pDecoder->allocationCallbacks);
        return MA_ERROR;   /* Too many channels. */
    }

    vorbisDataSize = sizeof(ma_vorbis_decoder) + sizeof(float)*vorbisInfo.max_frame_size;
    pVorbis = (ma_vorbis_decoder*)ma__malloc_from_callbacks(vorbisDataSize, &pDecoder->allocationCallbacks);
    if (pVorbis == NULL) {
        stb_vorbis_close(pInternalVorbis);
        ma__free_from_callbacks(pData, &pDecoder->allocationCallbacks);
        return MA_OUT_OF_MEMORY;
    }

    MA_ZERO_MEMORY(pVorbis, vorbisDataSize);
    pVorbis->pInternalVorbis = pInternalVorbis;
    pVorbis->pData = pData;
    pVorbis->dataSize = dataSize;
    pVorbis->dataCapacity = dataCapacity;

    pDecoder->onReadPCMFrames        = ma_decoder_internal_on_read_pcm_frames__vorbis;
    pDecoder->onSeekToPCMFrame       = ma_decoder_internal_on_seek_to_pcm_frame__vorbis;
    pDecoder->onUninit               = ma_decoder_internal_on_uninit__vorbis;
    pDecoder->onGetLengthInPCMFrames = ma_decoder_internal_on_get_length_in_pcm_frames__vorbis;
    pDecoder->pInternalDecoder       = pVorbis;

    /* The internal format is always f32. */
    pDecoder->internalFormat     = ma_format_f32;
    pDecoder->internalChannels   = vorbisInfo.channels;
    pDecoder->internalSampleRate = vorbisInfo.sample_rate;
    ma_get_standard_channel_map(ma_standard_channel_map_vorbis, pDecoder->internalChannels, pDecoder->internalChannelMap);

    return MA_SUCCESS;
}
#endif  /* STB_VORBIS_INCLUDE_STB_VORBIS_H */

/* Raw */
static ma_uint64 ma_decoder_internal_on_read_pcm_frames__raw(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint32 bpf;
    ma_uint64 totalFramesRead;
    void* pRunningFramesOut;

    MA_ASSERT(pDecoder != NULL);

    /* For raw decoding we just read directly from the decoder's callbacks. */
    bpf = ma_get_bytes_per_frame(pDecoder->internalFormat, pDecoder->internalChannels);

    totalFramesRead   = 0;
    pRunningFramesOut = pFramesOut;

    while (totalFramesRead < frameCount) {
        ma_uint64 framesReadThisIteration;
        ma_uint64 framesToReadThisIteration = (frameCount - totalFramesRead);
        if (framesToReadThisIteration > 0x7FFFFFFF/bpf) {
            framesToReadThisIteration = 0x7FFFFFFF/bpf;
        }

        if (pFramesOut != NULL) {
            framesReadThisIteration = ma_decoder_read_bytes(pDecoder, pRunningFramesOut, (size_t)framesToReadThisIteration * bpf) / bpf;    /* Safe cast to size_t. */
            pRunningFramesOut = ma_offset_ptr(pRunningFramesOut, framesReadThisIteration * bpf);
        } else {
            /* We'll first try seeking. If this fails it means the end was reached and we'll to do a read-and-discard slow path to get the exact amount. */
            if (ma_decoder_seek_bytes(pDecoder, (int)framesToReadThisIteration, ma_seek_origin_current)) {
                framesReadThisIteration = framesToReadThisIteration;
            } else {
                /* Slow path. Need to fall back to a read-and-discard. This is required so we can get the exact number of remaining. */
                ma_uint8 buffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                ma_uint32 bufferCap = sizeof(buffer) / bpf;

                framesReadThisIteration = 0;
                while (framesReadThisIteration < framesToReadThisIteration) {
                    ma_uint64 framesReadNow;
                    ma_uint64 framesToReadNow = framesToReadThisIteration - framesReadThisIteration;
                    if (framesToReadNow > bufferCap) {
                        framesToReadNow = bufferCap;
                    }

                    framesReadNow = ma_decoder_read_bytes(pDecoder, buffer, (size_t)(framesToReadNow * bpf)) / bpf; /* Safe cast. */
                    framesReadThisIteration += framesReadNow;

                    if (framesReadNow < framesToReadNow) {
                        break;  /* The end has been reached. */
                    }
                }
            }
        }

        totalFramesRead += framesReadThisIteration;

        if (framesReadThisIteration < framesToReadThisIteration) {
            break;  /* Done. */
        }
    }

    return totalFramesRead;
}

static ma_result ma_decoder_internal_on_seek_to_pcm_frame__raw(ma_decoder* pDecoder, ma_uint64 frameIndex)
{
    ma_bool32 result = MA_FALSE;
    ma_uint64 totalBytesToSeek;

    MA_ASSERT(pDecoder != NULL);

    if (pDecoder->onSeek == NULL) {
        return MA_ERROR;
    }

    /* The callback uses a 32 bit integer whereas we use a 64 bit unsigned integer. We just need to continuously seek until we're at the correct position. */
    totalBytesToSeek = frameIndex * ma_get_bytes_per_frame(pDecoder->internalFormat, pDecoder->internalChannels);
    if (totalBytesToSeek < 0x7FFFFFFF) {
        /* Simple case. */
        result = ma_decoder_seek_bytes(pDecoder, (int)(frameIndex * ma_get_bytes_per_frame(pDecoder->internalFormat, pDecoder->internalChannels)), ma_seek_origin_start);
    } else {
        /* Complex case. Start by doing a seek relative to the start. Then keep looping using offset seeking. */
        result = ma_decoder_seek_bytes(pDecoder, 0x7FFFFFFF, ma_seek_origin_start);
        if (result == MA_TRUE) {
            totalBytesToSeek -= 0x7FFFFFFF;

            while (totalBytesToSeek > 0) {
                ma_uint64 bytesToSeekThisIteration = totalBytesToSeek;
                if (bytesToSeekThisIteration > 0x7FFFFFFF) {
                    bytesToSeekThisIteration = 0x7FFFFFFF;

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

        return MA_ERROR;
    }
}

static ma_result ma_decoder_internal_on_uninit__raw(ma_decoder* pDecoder)
{
    (void)pDecoder;
    return MA_SUCCESS;
}

static ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__raw(ma_decoder* pDecoder)
{
    (void)pDecoder;
    return 0;
}

static ma_result ma_decoder_init_raw__internal(const ma_decoder_config* pConfigIn, const ma_decoder_config* pConfigOut, ma_decoder* pDecoder)
{
    MA_ASSERT(pConfigIn != NULL);
    MA_ASSERT(pConfigOut != NULL);
    MA_ASSERT(pDecoder != NULL);

    pDecoder->onReadPCMFrames        = ma_decoder_internal_on_read_pcm_frames__raw;
    pDecoder->onSeekToPCMFrame       = ma_decoder_internal_on_seek_to_pcm_frame__raw;
    pDecoder->onUninit               = ma_decoder_internal_on_uninit__raw;
    pDecoder->onGetLengthInPCMFrames = ma_decoder_internal_on_get_length_in_pcm_frames__raw;

    /* Internal format. */
    pDecoder->internalFormat     = pConfigIn->format;
    pDecoder->internalChannels   = pConfigIn->channels;
    pDecoder->internalSampleRate = pConfigIn->sampleRate;
    ma_channel_map_copy(pDecoder->internalChannelMap, pConfigIn->channelMap, pConfigIn->channels);

    return MA_SUCCESS;
}

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

    MA_ASSERT(pDecoder != NULL);

    if (pConfig != NULL) {
        return ma_allocation_callbacks_init_copy(&pDecoder->allocationCallbacks, &pConfig->allocationCallbacks);
    } else {
        pDecoder->allocationCallbacks = ma_allocation_callbacks_init_default();
        return MA_SUCCESS;
    }
}

static ma_result ma_decoder__data_source_on_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_uint64 framesRead = ma_decoder_read_pcm_frames((ma_decoder*)pDataSource, pFramesOut, frameCount);

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

    if (framesRead < frameCount) {
        return MA_AT_END;
    }

    return MA_SUCCESS;
}

static ma_result ma_decoder__data_source_on_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    return ma_decoder_seek_to_pcm_frame((ma_decoder*)pDataSource, frameIndex);
}

static ma_result ma_decoder__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate)
{
    ma_decoder* pDecoder = (ma_decoder*)pDataSource;

    *pFormat     = pDecoder->outputFormat;
    *pChannels   = pDecoder->outputChannels;
    *pSampleRate = pDecoder->outputSampleRate;

    return MA_SUCCESS;
}

static ma_result ma_decoder__data_source_on_get_cursor(ma_data_source* pDataSource, ma_uint64* pLength)
{
    ma_decoder* pDecoder = (ma_decoder*)pDataSource;

    return ma_decoder_get_cursor_in_pcm_frames(pDecoder, pLength);
}

static ma_result ma_decoder__data_source_on_get_length(ma_data_source* pDataSource, ma_uint64* pLength)
{
    ma_decoder* pDecoder = (ma_decoder*)pDataSource;

    *pLength = ma_decoder_get_length_in_pcm_frames(pDecoder);
    if (*pLength == 0) {
        return MA_NOT_IMPLEMENTED;
    }

    return MA_SUCCESS;
}

static ma_result ma_decoder__preinit(ma_decoder_read_proc onRead, ma_decoder_seek_proc onSeek, void* pUserData, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
    ma_result result;

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

        } else {
            ma_vfs_close(pDecoder->backend.vfs.pVFS, pDecoder->backend.vfs.file);
        }
    }

    ma_data_converter_uninit(&pDecoder->converter);

    return MA_SUCCESS;
}

MA_API ma_result ma_decoder_get_cursor_in_pcm_frames(ma_decoder* pDecoder, ma_uint64* pCursor)
{
    if (pCursor == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = 0;

    if (pDecoder == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = pDecoder->readPointerInPCMFrames;

    return MA_SUCCESS;
}

MA_API ma_uint64 ma_decoder_get_length_in_pcm_frames(ma_decoder* pDecoder)
{
    if (pDecoder == NULL) {
        return 0;
    }

    if (pDecoder->onGetLengthInPCMFrames) {
        ma_uint64 nativeLengthInPCMFrames = pDecoder->onGetLengthInPCMFrames(pDecoder);
        if (pDecoder->internalSampleRate == pDecoder->outputSampleRate) {
            return nativeLengthInPCMFrames;
        } else {
            return ma_calculate_frame_count_after_resampling(pDecoder->outputSampleRate, pDecoder->internalSampleRate, nativeLengthInPCMFrames);
        }
    }

    return 0;
}

MA_API ma_uint64 ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount)
{
    ma_result result;
    ma_uint64 totalFramesReadOut;
    ma_uint64 totalFramesReadIn;
    void* pRunningFramesOut;
    
    if (pDecoder == NULL) {
        return 0;
    }

    if (pDecoder->onReadPCMFrames == NULL) {
        return 0;
    }

    /* Fast path. */
    if (pDecoder->converter.isPassthrough) {
        totalFramesReadOut = pDecoder->onReadPCMFrames(pDecoder, pFramesOut, frameCount);
    } else {
        /*
        Getting here means we need to do data conversion. If we're seeking forward and are _not_ doing resampling we can run this in a fast path. If we're doing resampling we
        need to run through each sample because we need to ensure it's internal cache is updated.
        */
        if (pFramesOut == NULL && pDecoder->converter.hasResampler == MA_FALSE) {
            totalFramesReadOut = pDecoder->onReadPCMFrames(pDecoder, NULL, frameCount);   /* All decoder backends must support passing in NULL for the output buffer. */
        } else {
            /* Slow path. Need to run everything through the data converter. */
            totalFramesReadOut = 0;
            totalFramesReadIn  = 0;
            pRunningFramesOut  = pFramesOut;
    
            while (totalFramesReadOut < frameCount) {
                ma_uint8 pIntermediaryBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];  /* In internal format. */
                ma_uint64 intermediaryBufferCap = sizeof(pIntermediaryBuffer) / ma_get_bytes_per_frame(pDecoder->internalFormat, pDecoder->internalChannels);
                ma_uint64 framesToReadThisIterationIn;
                ma_uint64 framesReadThisIterationIn;
                ma_uint64 framesToReadThisIterationOut;
                ma_uint64 framesReadThisIterationOut;
                ma_uint64 requiredInputFrameCount;

                framesToReadThisIterationOut = (frameCount - totalFramesReadOut);
                framesToReadThisIterationIn = framesToReadThisIterationOut;
                if (framesToReadThisIterationIn > intermediaryBufferCap) {
                    framesToReadThisIterationIn = intermediaryBufferCap;
                }

                requiredInputFrameCount = ma_data_converter_get_required_input_frame_count(&pDecoder->converter, framesToReadThisIterationOut);
                if (framesToReadThisIterationIn > requiredInputFrameCount) {
                    framesToReadThisIterationIn = requiredInputFrameCount;
                }

                if (requiredInputFrameCount > 0) {
                    framesReadThisIterationIn = pDecoder->onReadPCMFrames(pDecoder, pIntermediaryBuffer, framesToReadThisIterationIn);
                    totalFramesReadIn += framesReadThisIterationIn;
                }

                /*
                At this point we have our decoded data in input format and now we need to convert to output format. Note that even if we didn't read any
                input frames, we still want to try processing frames because there may some output frames generated from cached input data.
                */
                framesReadThisIterationOut = framesToReadThisIterationOut;
                result = ma_data_converter_process_pcm_frames(&pDecoder->converter, pIntermediaryBuffer, &framesReadThisIterationIn, pRunningFramesOut, &framesReadThisIterationOut);
                if (result != MA_SUCCESS) {
                    break;
                }

                totalFramesReadOut += framesReadThisIterationOut;

                if (pRunningFramesOut != NULL) {
                    pRunningFramesOut = ma_offset_ptr(pRunningFramesOut, framesReadThisIterationOut * ma_get_bytes_per_frame(pDecoder->outputFormat, pDecoder->outputChannels));
                }

                if (framesReadThisIterationIn == 0 && framesReadThisIterationOut == 0) {
                    break;  /* We're done. */
                }
            }
        }
    }

    pDecoder->readPointerInPCMFrames += totalFramesReadOut;

    return totalFramesReadOut;
}

MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 frameIndex)
{
    if (pDecoder == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pDecoder->onSeekToPCMFrame) {
        ma_result result;
        ma_uint64 internalFrameIndex;
        if (pDecoder->internalSampleRate == pDecoder->outputSampleRate) {
            internalFrameIndex = frameIndex;
        } else {
            internalFrameIndex = ma_calculate_frame_count_after_resampling(pDecoder->internalSampleRate, pDecoder->outputSampleRate, frameIndex);
        }

        result = pDecoder->onSeekToPCMFrame(pDecoder, internalFrameIndex);
        if (result == MA_SUCCESS) {
            pDecoder->readPointerInPCMFrames = frameIndex;
        }

        return result;
    }

    /* Should never get here, but if we do it means onSeekToPCMFrame was not set by the backend. */
    return MA_INVALID_ARGS;
}

MA_API ma_result ma_decoder_get_available_frames(ma_decoder* pDecoder, ma_uint64* pAvailableFrames)
{
    ma_uint64 totalFrameCount;

    if (pAvailableFrames == NULL) {
        return MA_INVALID_ARGS;
    }

    *pAvailableFrames = 0;

    if (pDecoder == NULL) {
        return MA_INVALID_ARGS;
    }

    totalFrameCount = ma_decoder_get_length_in_pcm_frames(pDecoder);
    if (totalFrameCount == 0) {
        return MA_NOT_IMPLEMENTED;
    }

    if (totalFrameCount <= pDecoder->readPointerInPCMFrames) {
        *pAvailableFrames = 0;
    } else {
        *pAvailableFrames = totalFrameCount - pDecoder->readPointerInPCMFrames;
    }

    return MA_SUCCESS;   /* No frames available. */
}


static ma_result ma_decoder__full_decode_and_uninit(ma_decoder* pDecoder, ma_decoder_config* pConfigOut, ma_uint64* pFrameCountOut, void** ppPCMFramesOut)
{
    ma_uint64 totalFrameCount;
    ma_uint64 bpf;
    ma_uint64 dataCapInFrames;
    void* pPCMFramesOut;

    MA_ASSERT(pDecoder != NULL);
    
    totalFrameCount = 0;
    bpf = ma_get_bytes_per_frame(pDecoder->outputFormat, pDecoder->outputChannels);

    /* The frame count is unknown until we try reading. Thus, we just run in a loop. */
    dataCapInFrames = 0;
    pPCMFramesOut = NULL;
    for (;;) {
        ma_uint64 frameCountToTryReading;
        ma_uint64 framesJustRead;

        /* Make room if there's not enough. */
        if (totalFrameCount == dataCapInFrames) {
            void* pNewPCMFramesOut;
            ma_uint64 oldDataCapInFrames = dataCapInFrames;
            ma_uint64 newDataCapInFrames = dataCapInFrames*2;
            if (newDataCapInFrames == 0) {
                newDataCapInFrames = 4096;
            }

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

            pNewPCMFramesOut = (void*)ma__realloc_from_callbacks(pPCMFramesOut, (size_t)(newDataCapInFrames * bpf), (size_t)(oldDataCapInFrames * bpf), &pDecoder->allocationCallbacks);
            if (pNewPCMFramesOut == NULL) {
                ma__free_from_callbacks(pPCMFramesOut, &pDecoder->allocationCallbacks);
                return MA_OUT_OF_MEMORY;
            }

            dataCapInFrames = newDataCapInFrames;
            pPCMFramesOut = pNewPCMFramesOut;
        }

        frameCountToTryReading = dataCapInFrames - totalFrameCount;
        MA_ASSERT(frameCountToTryReading > 0);

        framesJustRead = ma_decoder_read_pcm_frames(pDecoder, (ma_uint8*)pPCMFramesOut + (totalFrameCount * bpf), frameCountToTryReading);
        totalFrameCount += framesJustRead;

        if (framesJustRead < frameCountToTryReading) {
            break;
        }
    }

    
    if (pConfigOut != NULL) {
        pConfigOut->format = pDecoder->outputFormat;
        pConfigOut->channels = pDecoder->outputChannels;
        pConfigOut->sampleRate = pDecoder->outputSampleRate;
        ma_channel_map_copy(pConfigOut->channelMap, pDecoder->outputChannelMap, pDecoder->outputChannels);

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


    MA_ASSERT(pEncoder != NULL);

    pWav = (drwav*)pEncoder->pInternalEncoder;
    MA_ASSERT(pWav != NULL);

    drwav_uninit(pWav);
    ma__free_from_callbacks(pWav, &pEncoder->config.allocationCallbacks);
}

static ma_uint64 ma_encoder__on_write_pcm_frames_wav(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount)
{
    drwav* pWav;

    MA_ASSERT(pEncoder != NULL);

    pWav = (drwav*)pEncoder->pInternalEncoder;
    MA_ASSERT(pWav != NULL);

    return drwav_write_pcm_frames(pWav, frameCount, pFramesIn);
}
#endif

MA_API ma_encoder_config ma_encoder_config_init(ma_resource_format resourceFormat, ma_format format, ma_uint32 channels, ma_uint32 sampleRate)
{
    ma_encoder_config config;

    MA_ZERO_OBJECT(&config);
    config.resourceFormat = resourceFormat;
    config.format = format;

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

    pEncoder->onSeek    = onSeek;
    pEncoder->pUserData = pUserData;

    switch (pEncoder->config.resourceFormat)
    {
        case ma_resource_format_wav:
        {
        #if defined(MA_HAS_WAV)
            pEncoder->onInit           = ma_encoder__on_init_wav;
            pEncoder->onUninit         = ma_encoder__on_uninit_wav;
            pEncoder->onWritePCMFrames = ma_encoder__on_write_pcm_frames_wav;
        #else
            result = MA_NO_BACKEND;
        #endif
        } break;

        default:
        {
            result = MA_INVALID_ARGS;
        } break;
    }

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

        pEncoder->onUninit(pEncoder);
    }

    /* If we have a file handle, close it. */
    if (pEncoder->onWrite == ma_encoder__on_write_stdio) {
        fclose((FILE*)pEncoder->pFile);
    }
}


MA_API ma_uint64 ma_encoder_write_pcm_frames(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pEncoder == NULL || pFramesIn == NULL) {
        return 0;
    }

    return pEncoder->onWritePCMFrames(pEncoder, pFramesIn, frameCount);
}
#endif  /* MA_NO_ENCODING */



/**************************************************************************************************************************************************************

Generation

**************************************************************************************************************************************************************/

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

    config.format     = format;
    config.channels   = channels;
    config.sampleRate = sampleRate;
    config.type       = type;
    config.amplitude  = amplitude;
    config.frequency  = frequency;

    return config;
}

static ma_result ma_waveform__data_source_on_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_uint64 framesRead = ma_waveform_read_pcm_frames((ma_waveform*)pDataSource, pFramesOut, frameCount);

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

    if (framesRead < frameCount) {
        return MA_AT_END;
    }

    return MA_SUCCESS;
}

static ma_result ma_waveform__data_source_on_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    return ma_waveform_seek_to_pcm_frame((ma_waveform*)pDataSource, frameIndex);
}

static ma_result ma_waveform__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate)
{
    ma_waveform* pWaveform = (ma_waveform*)pDataSource;

    *pFormat     = pWaveform->config.format;
    *pChannels   = pWaveform->config.channels;
    *pSampleRate = pWaveform->config.sampleRate;

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

    r = 2 * (f - 0.5);

    return (float)(r * amplitude);
}

static ma_int16 ma_waveform_sawtooth_s16(double time, double frequency, double amplitude)
{
    return ma_pcm_sample_f32_to_s16(ma_waveform_sawtooth_f32(time, frequency, amplitude));
}

static void ma_waveform_read_pcm_frames__sine(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint64 iChannel;
    ma_uint32 bps = ma_get_bytes_per_sample(pWaveform->config.format);
    ma_uint32 bpf = bps * pWaveform->config.channels;

    MA_ASSERT(pWaveform  != NULL);
    MA_ASSERT(pFramesOut != NULL);

    if (pWaveform->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_sine_f32(pWaveform->time, pWaveform->config.frequency, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutF32[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else if (pWaveform->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            ma_int16 s = ma_waveform_sine_s16(pWaveform->time, pWaveform->config.frequency, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutS16[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else {
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_sine_f32(pWaveform->time, pWaveform->config.frequency, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pWaveform->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
            }
        }
    }
}

static void ma_waveform_read_pcm_frames__square(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint64 iChannel;
    ma_uint32 bps = ma_get_bytes_per_sample(pWaveform->config.format);
    ma_uint32 bpf = bps * pWaveform->config.channels;

    MA_ASSERT(pWaveform  != NULL);
    MA_ASSERT(pFramesOut != NULL);

    if (pWaveform->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_square_f32(pWaveform->time, pWaveform->config.frequency, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutF32[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else if (pWaveform->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            ma_int16 s = ma_waveform_square_s16(pWaveform->time, pWaveform->config.frequency, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutS16[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else {
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_square_f32(pWaveform->time, pWaveform->config.frequency, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pWaveform->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
            }
        }
    }
}

static void ma_waveform_read_pcm_frames__triangle(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint64 iChannel;
    ma_uint32 bps = ma_get_bytes_per_sample(pWaveform->config.format);
    ma_uint32 bpf = bps * pWaveform->config.channels;

    MA_ASSERT(pWaveform  != NULL);
    MA_ASSERT(pFramesOut != NULL);

    if (pWaveform->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_triangle_f32(pWaveform->time, pWaveform->config.frequency, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutF32[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else if (pWaveform->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            ma_int16 s = ma_waveform_triangle_s16(pWaveform->time, pWaveform->config.frequency, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutS16[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else {
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_triangle_f32(pWaveform->time, pWaveform->config.frequency, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pWaveform->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
            }
        }
    }
}

static void ma_waveform_read_pcm_frames__sawtooth(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint64 iChannel;
    ma_uint32 bps = ma_get_bytes_per_sample(pWaveform->config.format);
    ma_uint32 bpf = bps * pWaveform->config.channels;

    MA_ASSERT(pWaveform  != NULL);
    MA_ASSERT(pFramesOut != NULL);

    if (pWaveform->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_sawtooth_f32(pWaveform->time, pWaveform->config.frequency, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutF32[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else if (pWaveform->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            ma_int16 s = ma_waveform_sawtooth_s16(pWaveform->time, pWaveform->config.frequency, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutS16[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else {
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_sawtooth_f32(pWaveform->time, pWaveform->config.frequency, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pWaveform->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
            }
        }
    }
}

MA_API ma_uint64 ma_waveform_read_pcm_frames(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount)
{
    if (pWaveform == NULL) {
        return 0;
    }

    if (pFramesOut != NULL) {
        switch (pWaveform->config.type)
        {
            case ma_waveform_type_sine:
            {
                ma_waveform_read_pcm_frames__sine(pWaveform, pFramesOut, frameCount);
            } break;

            case ma_waveform_type_square:
            {
                ma_waveform_read_pcm_frames__square(pWaveform, pFramesOut, frameCount);
            } break;

            case ma_waveform_type_triangle:
            {
                ma_waveform_read_pcm_frames__triangle(pWaveform, pFramesOut, frameCount);
            } break;

            case ma_waveform_type_sawtooth:
            {
                ma_waveform_read_pcm_frames__sawtooth(pWaveform, pFramesOut, frameCount);
            } break;

            default: return 0;
        }
    } else {
        pWaveform->time += pWaveform->advance * (ma_int64)frameCount; /* Cast to int64 required for VC6. Won't affect anything in practice. */
    }

    return frameCount;
}

MA_API ma_result ma_waveform_seek_to_pcm_frame(ma_waveform* pWaveform, ma_uint64 frameIndex)
{
    if (pWaveform == NULL) {
        return MA_INVALID_ARGS;
    }

    pWaveform->time = pWaveform->advance * (ma_int64)frameIndex;    /* Casting for VC6. Won't be an issue in practice. */

    return MA_SUCCESS;
}


MA_API ma_noise_config ma_noise_config_init(ma_format format, ma_uint32 channels, ma_noise_type type, ma_int32 seed, double amplitude)
{
    ma_noise_config config;
    MA_ZERO_OBJECT(&config);

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

    config.amplitude = amplitude;

    if (config.seed == 0) {
        config.seed = MA_DEFAULT_LCG_SEED;
    }

    return config;
}


static ma_result ma_noise__data_source_on_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_uint64 framesRead = ma_noise_read_pcm_frames((ma_noise*)pDataSource, pFramesOut, frameCount);
    
    if (pFramesRead != NULL) {
        *pFramesRead = framesRead;
    }

    if (framesRead < frameCount) {
        return MA_AT_END;
    }

    return MA_SUCCESS;
}

static ma_result ma_noise__data_source_on_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    /* No-op. Just pretend to be successful. */
    (void)pDataSource;
    (void)frameIndex;
    return MA_SUCCESS;
}

static ma_result ma_noise__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate)
{
    ma_noise* pNoise = (ma_noise*)pDataSource;

    *pFormat     = pNoise->config.format;
    *pChannels   = pNoise->config.channels;
    *pSampleRate = 0;   /* There is no notion of sample rate with noise generation. */

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

static MA_INLINE float ma_noise_f32_white(ma_noise* pNoise)
{
    return (float)(ma_lcg_rand_f64(&pNoise->lcg) * pNoise->config.amplitude);
}

static MA_INLINE ma_int16 ma_noise_s16_white(ma_noise* pNoise)
{
    return ma_pcm_sample_f32_to_s16(ma_noise_f32_white(pNoise));
}

static MA_INLINE ma_uint64 ma_noise_read_pcm_frames__white(ma_noise* pNoise, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint32 iChannel;

    if (pNoise->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                float s = ma_noise_f32_white(pNoise);
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    pFramesOutF32[iFrame*pNoise->config.channels + iChannel] = s;
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    pFramesOutF32[iFrame*pNoise->config.channels + iChannel] = ma_noise_f32_white(pNoise);
                }
            }
        }
    } else if (pNoise->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                ma_int16 s = ma_noise_s16_white(pNoise);
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    pFramesOutS16[iFrame*pNoise->config.channels + iChannel] = s;
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    pFramesOutS16[iFrame*pNoise->config.channels + iChannel] = ma_noise_s16_white(pNoise);
                }
            }
        }
    } else {
        ma_uint32 bps = ma_get_bytes_per_sample(pNoise->config.format);
        ma_uint32 bpf = bps * pNoise->config.channels;
        
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                float s = ma_noise_f32_white(pNoise);
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pNoise->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    float s = ma_noise_f32_white(pNoise);
                    ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pNoise->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
                }
            }
        }
    }

    return frameCount;
}


static MA_INLINE unsigned int ma_tzcnt32(unsigned int x)
{
    unsigned int n;

    /* Special case for odd numbers since they should happen about half the time. */
    if (x & 0x1)  {
        return 0;

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

    result /= 10;

    return (float)(result * pNoise->config.amplitude);
}

static MA_INLINE ma_int16 ma_noise_s16_pink(ma_noise* pNoise, ma_uint32 iChannel)
{
    return ma_pcm_sample_f32_to_s16(ma_noise_f32_pink(pNoise, iChannel));
}

static MA_INLINE ma_uint64 ma_noise_read_pcm_frames__pink(ma_noise* pNoise, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint32 iChannel;

    if (pNoise->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                float s = ma_noise_f32_pink(pNoise, 0);
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    pFramesOutF32[iFrame*pNoise->config.channels + iChannel] = s;
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    pFramesOutF32[iFrame*pNoise->config.channels + iChannel] = ma_noise_f32_pink(pNoise, iChannel);
                }
            }
        }
    } else if (pNoise->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                ma_int16 s = ma_noise_s16_pink(pNoise, 0);
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    pFramesOutS16[iFrame*pNoise->config.channels + iChannel] = s;
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    pFramesOutS16[iFrame*pNoise->config.channels + iChannel] = ma_noise_s16_pink(pNoise, iChannel);
                }
            }
        }
    } else {
        ma_uint32 bps = ma_get_bytes_per_sample(pNoise->config.format);
        ma_uint32 bpf = bps * pNoise->config.channels;
        
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                float s = ma_noise_f32_pink(pNoise, 0);
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pNoise->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    float s = ma_noise_f32_pink(pNoise, iChannel);
                    ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pNoise->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
                }
            }
        }
    }

    return frameCount;
}


static MA_INLINE float ma_noise_f32_brownian(ma_noise* pNoise, ma_uint32 iChannel)
{
    double result;
    
    result = (ma_lcg_rand_f64(&pNoise->lcg) + pNoise->state.brownian.accumulation[iChannel]);
    result /= 1.005; /* Don't escape the -1..1 range on average. */

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

    result /= 20;

    return (float)(result * pNoise->config.amplitude);
}

static MA_INLINE ma_int16 ma_noise_s16_brownian(ma_noise* pNoise, ma_uint32 iChannel)
{
    return ma_pcm_sample_f32_to_s16(ma_noise_f32_brownian(pNoise, iChannel));
}

static MA_INLINE ma_uint64 ma_noise_read_pcm_frames__brownian(ma_noise* pNoise, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint32 iChannel;

    if (pNoise->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                float s = ma_noise_f32_brownian(pNoise, 0);
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    pFramesOutF32[iFrame*pNoise->config.channels + iChannel] = s;
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    pFramesOutF32[iFrame*pNoise->config.channels + iChannel] = ma_noise_f32_brownian(pNoise, iChannel);
                }
            }
        }
    } else if (pNoise->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                ma_int16 s = ma_noise_s16_brownian(pNoise, 0);
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    pFramesOutS16[iFrame*pNoise->config.channels + iChannel] = s;
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    pFramesOutS16[iFrame*pNoise->config.channels + iChannel] = ma_noise_s16_brownian(pNoise, iChannel);
                }
            }
        }
    } else {
        ma_uint32 bps = ma_get_bytes_per_sample(pNoise->config.format);
        ma_uint32 bpf = bps * pNoise->config.channels;
        
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                float s = ma_noise_f32_brownian(pNoise, 0);
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pNoise->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < pNoise->config.channels; iChannel += 1) {
                    float s = ma_noise_f32_brownian(pNoise, iChannel);
                    ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pNoise->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
                }
            }
        }
    }

    return frameCount;
}

MA_API ma_uint64 ma_noise_read_pcm_frames(ma_noise* pNoise, void* pFramesOut, ma_uint64 frameCount)
{
    if (pNoise == NULL) {
        return 0;
    }

    /* The output buffer is allowed to be NULL. Since we aren't tracking cursors or anything we can just do nothing and pretend to be successful. */
    if (pFramesOut == NULL) {
        return frameCount;
    }

    if (pNoise->config.type == ma_noise_type_white) {
        return ma_noise_read_pcm_frames__white(pNoise, pFramesOut, frameCount);
    }

    if (pNoise->config.type == ma_noise_type_pink) {
        return ma_noise_read_pcm_frames__pink(pNoise, pFramesOut, frameCount);
    }

    if (pNoise->config.type == ma_noise_type_brownian) {
        return ma_noise_read_pcm_frames__brownian(pNoise, pFramesOut, frameCount);
    }

    /* Should never get here. */
    MA_ASSERT(MA_FALSE);
    return 0;
}
#endif /* MA_NO_GENERATION */



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

        formatTag == DR_WAVE_FORMAT_DVI_ADPCM;
}
static unsigned int drwav__chunk_padding_size_riff(drwav_uint64 chunkSize)
{
    return (unsigned int)(chunkSize % 2);
}
static unsigned int drwav__chunk_padding_size_w64(drwav_uint64 chunkSize)
{
    return (unsigned int)(chunkSize % 8);
}
static drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut);
static drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut);
static drwav_bool32 drwav_init_write__internal(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount);
static drwav_result drwav__read_chunk_header(drwav_read_proc onRead, void* pUserData, drwav_container container, drwav_uint64* pRunningBytesReadOut, drwav_chunk_header* pHeaderOut)
{
    if (container == drwav_container_riff || container == drwav_container_rf64) {
        drwav_uint8 sizeInBytes[4];
        if (onRead(pUserData, pHeaderOut->id.fourcc, 4) != 4) {
            return DRWAV_AT_END;
        }
        if (onRead(pUserData, sizeInBytes, 4) != 4) {
            return DRWAV_INVALID_FILE;

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

        return DRWAV_FALSE;
    }
    if (origin == drwav_seek_origin_start) {
        *pCursor = offset;
    } else {
        *pCursor += offset;
    }
    return DRWAV_TRUE;
}
#endif
static drwav_uint32 drwav_get_bytes_per_pcm_frame(drwav* pWav)
{
    if ((pWav->bitsPerSample & 0x7) == 0) {
        return (pWav->bitsPerSample * pWav->fmt.channels) >> 3;
    } else {
        return pWav->fmt.blockAlign;
    }
}
DRWAV_API drwav_uint16 drwav_fmt_get_format(const drwav_fmt* pFMT)
{
    if (pFMT == NULL) {

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

    pWav->fmt                 = fmt;
    pWav->sampleRate          = fmt.sampleRate;
    pWav->channels            = fmt.channels;
    pWav->bitsPerSample       = fmt.bitsPerSample;
    pWav->bytesRemaining      = dataChunkSize;
    pWav->translatedFormatTag = translatedFormatTag;
    pWav->dataChunkDataSize   = dataChunkSize;
    if (sampleCountFromFactChunk != 0) {
        pWav->totalPCMFrameCount = sampleCountFromFactChunk;
    } else {
        pWav->totalPCMFrameCount = dataChunkSize / drwav_get_bytes_per_pcm_frame(pWav);
        if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
            drwav_uint64 totalBlockHeaderSizeInBytes;
            drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
            if ((blockCount * fmt.blockAlign) < dataChunkSize) {
                blockCount += 1;
            }
            totalBlockHeaderSizeInBytes = blockCount * (6*fmt.channels);
            pWav->totalPCMFrameCount = ((dataChunkSize - totalBlockHeaderSizeInBytes) * 2) / fmt.channels;
        }
        if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {

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

    }
    return drwav_init_write__internal(pWav, pFormat, 0);
}
DRWAV_API drwav_bool32 drwav_init_write_sequential(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    if (!drwav_preinit_write(pWav, pFormat, DRWAV_TRUE, onWrite, NULL, pUserData, pAllocationCallbacks)) {
        return DRWAV_FALSE;
    }
    return drwav_init_write__internal(pWav, pFormat, totalSampleCount);
}
DRWAV_API drwav_bool32 drwav_init_write_sequential_pcm_frames(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    if (pFormat == NULL) {
        return DRWAV_FALSE;
    }
    return drwav_init_write_sequential(pWav, pFormat, totalPCMFrameCount*pFormat->channels, onWrite, pUserData, pAllocationCallbacks);
}
DRWAV_API drwav_uint64 drwav_target_write_size_bytes(const drwav_data_format* pFormat, drwav_uint64 totalSampleCount)
{
    drwav_uint64 targetDataSizeBytes = (drwav_uint64)((drwav_int64)totalSampleCount * pFormat->channels * pFormat->bitsPerSample/8.0);
    drwav_uint64 riffChunkSizeBytes;

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

    return drwav_init_file_write__internal_FILE(pWav, pFile, pFormat, totalSampleCount, isSequential, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    return drwav_init_file_write__internal(pWav, filename, pFormat, 0, DRWAV_FALSE, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_file_write_sequential(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    return drwav_init_file_write__internal(pWav, filename, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    if (pFormat == NULL) {
        return DRWAV_FALSE;
    }
    return drwav_init_file_write_sequential(pWav, filename, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_file_write_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    return drwav_init_file_write_w__internal(pWav, filename, pFormat, 0, DRWAV_FALSE, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    return drwav_init_file_write_w__internal(pWav, filename, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    if (pFormat == NULL) {
        return DRWAV_FALSE;
    }
    return drwav_init_file_write_sequential_w(pWav, filename, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
}
#endif
static size_t drwav__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead)
{
    drwav* pWav = (drwav*)pUserData;

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

    return drwav_init_write__internal(pWav, pFormat, totalSampleCount);
}
DRWAV_API drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    return drwav_init_memory_write__internal(pWav, ppData, pDataSize, pFormat, 0, DRWAV_FALSE, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    return drwav_init_memory_write__internal(pWav, ppData, pDataSize, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential_pcm_frames(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    if (pFormat == NULL) {
        return DRWAV_FALSE;
    }
    return drwav_init_memory_write_sequential(pWav, ppData, pDataSize, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
}
DRWAV_API drwav_result drwav_uninit(drwav* pWav)
{
    drwav_result result = DRWAV_SUCCESS;
    if (pWav == NULL) {

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

            bytesSeeked = pWav->onRead(pWav->pUserData, buffer, bytesToSeek);
            bytesRead += bytesSeeked;
            if (bytesSeeked < bytesToSeek) {
                break;
            }
        }
    }
    pWav->bytesRemaining -= bytesRead;
    return bytesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_le(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut)
{
    drwav_uint32 bytesPerFrame;
    if (pWav == NULL || framesToRead == 0) {
        return 0;
    }
    if (drwav__is_compressed_format_tag(pWav->translatedFormatTag)) {
        return 0;
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    if (framesToRead * bytesPerFrame > DRWAV_SIZE_MAX) {
        framesToRead = DRWAV_SIZE_MAX / bytesPerFrame;
    }
    return drwav_read_raw(pWav, (size_t)(framesToRead * bytesPerFrame), pBufferOut) / bytesPerFrame;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL) {
        drwav__bswap_samples(pBufferOut, framesRead*pWav->channels, drwav_get_bytes_per_pcm_frame(pWav)/pWav->channels, pWav->translatedFormatTag);
    }
    return framesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut)
{
    if (drwav__is_little_endian()) {
        return drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut);
    } else {
        return drwav_read_pcm_frames_be(pWav, framesToRead, pBufferOut);
    }
}
DRWAV_API drwav_bool32 drwav_seek_to_first_pcm_frame(drwav* pWav)
{
    if (pWav->onWrite != NULL) {
        return DRWAV_FALSE;
    }
    if (!pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos, drwav_seek_origin_start)) {
        return DRWAV_FALSE;
    }
    if (drwav__is_compressed_format_tag(pWav->translatedFormatTag)) {
        pWav->compressed.iCurrentPCMFrame = 0;
        if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
            DRWAV_ZERO_OBJECT(&pWav->msadpcm);
        } else if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
            DRWAV_ZERO_OBJECT(&pWav->ima);
        } else {
            DRWAV_ASSERT(DRWAV_FALSE);
        }
    }
    pWav->bytesRemaining = pWav->dataChunkDataSize;
    return DRWAV_TRUE;
}
DRWAV_API drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64 targetFrameIndex)
{
    if (pWav == NULL || pWav->onSeek == NULL) {
        return DRWAV_FALSE;
    }
    if (pWav->onWrite != NULL) {
        return DRWAV_FALSE;
    }
    if (pWav->totalPCMFrameCount == 0) {
        return DRWAV_TRUE;
    }
    if (targetFrameIndex >= pWav->totalPCMFrameCount) {
        targetFrameIndex  = pWav->totalPCMFrameCount - 1;
    }
    if (drwav__is_compressed_format_tag(pWav->translatedFormatTag)) {
        if (targetFrameIndex < pWav->compressed.iCurrentPCMFrame) {
            if (!drwav_seek_to_first_pcm_frame(pWav)) {
                return DRWAV_FALSE;
            }
        }
        if (targetFrameIndex > pWav->compressed.iCurrentPCMFrame) {
            drwav_uint64 offsetInFrames = targetFrameIndex - pWav->compressed.iCurrentPCMFrame;
            drwav_int16 devnull[2048];
            while (offsetInFrames > 0) {
                drwav_uint64 framesRead = 0;
                drwav_uint64 framesToRead = offsetInFrames;
                if (framesToRead > drwav_countof(devnull)/pWav->channels) {
                    framesToRead = drwav_countof(devnull)/pWav->channels;
                }
                if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
                    framesRead = drwav_read_pcm_frames_s16__msadpcm(pWav, framesToRead, devnull);
                } else if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
                    framesRead = drwav_read_pcm_frames_s16__ima(pWav, framesToRead, devnull);
                } else {
                    DRWAV_ASSERT(DRWAV_FALSE);
                }
                if (framesRead != framesToRead) {
                    return DRWAV_FALSE;
                }
                offsetInFrames -= framesRead;
            }
        }
    } else {
        drwav_uint64 totalSizeInBytes;
        drwav_uint64 currentBytePos;
        drwav_uint64 targetBytePos;
        drwav_uint64 offset;
        totalSizeInBytes = pWav->totalPCMFrameCount * drwav_get_bytes_per_pcm_frame(pWav);
        DRWAV_ASSERT(totalSizeInBytes >= pWav->bytesRemaining);
        currentBytePos = totalSizeInBytes - pWav->bytesRemaining;
        targetBytePos  = targetFrameIndex * drwav_get_bytes_per_pcm_frame(pWav);
        if (currentBytePos < targetBytePos) {
            offset = (targetBytePos - currentBytePos);
        } else {
            if (!drwav_seek_to_first_pcm_frame(pWav)) {
                return DRWAV_FALSE;
            }
            offset = targetBytePos;
        }
        while (offset > 0) {
            int offset32 = ((offset > INT_MAX) ? INT_MAX : (int)offset);
            if (!pWav->onSeek(pWav->pUserData, offset32, drwav_seek_origin_current)) {
                return DRWAV_FALSE;
            }
            pWav->bytesRemaining -= offset32;

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

DRWAV_API size_t drwav_write_raw(drwav* pWav, size_t bytesToWrite, const void* pData)
{
    size_t bytesWritten;
    if (pWav == NULL || bytesToWrite == 0 || pData == NULL) {
        return 0;
    }
    bytesWritten = pWav->onWrite(pWav->pUserData, pData, bytesToWrite);
    pWav->dataChunkDataSize += bytesWritten;
    return bytesWritten;
}
DRWAV_API drwav_uint64 drwav_write_pcm_frames_le(drwav* pWav, drwav_uint64 framesToWrite, const void* pData)
{
    drwav_uint64 bytesToWrite;
    drwav_uint64 bytesWritten;
    const drwav_uint8* pRunningData;
    if (pWav == NULL || framesToWrite == 0 || pData == NULL) {
        return 0;
    }
    bytesToWrite = ((framesToWrite * pWav->channels * pWav->bitsPerSample) / 8);
    if (bytesToWrite > DRWAV_SIZE_MAX) {
        return 0;
    }
    bytesWritten = 0;
    pRunningData = (const drwav_uint8*)pData;
    while (bytesToWrite > 0) {
        size_t bytesJustWritten;
        drwav_uint64 bytesToWriteThisIteration;
        bytesToWriteThisIteration = bytesToWrite;
        DRWAV_ASSERT(bytesToWriteThisIteration <= DRWAV_SIZE_MAX);
        bytesJustWritten = drwav_write_raw(pWav, (size_t)bytesToWriteThisIteration, pRunningData);
        if (bytesJustWritten == 0) {
            break;
        }
        bytesToWrite -= bytesJustWritten;
        bytesWritten += bytesJustWritten;
        pRunningData += bytesJustWritten;
    }
    return (bytesWritten * 8) / pWav->bitsPerSample / pWav->channels;
}
DRWAV_API drwav_uint64 drwav_write_pcm_frames_be(drwav* pWav, drwav_uint64 framesToWrite, const void* pData)
{
    drwav_uint64 bytesToWrite;
    drwav_uint64 bytesWritten;
    drwav_uint32 bytesPerSample;
    const drwav_uint8* pRunningData;
    if (pWav == NULL || framesToWrite == 0 || pData == NULL) {
        return 0;
    }
    bytesToWrite = ((framesToWrite * pWav->channels * pWav->bitsPerSample) / 8);
    if (bytesToWrite > DRWAV_SIZE_MAX) {
        return 0;
    }
    bytesWritten = 0;
    pRunningData = (const drwav_uint8*)pData;
    bytesPerSample = drwav_get_bytes_per_pcm_frame(pWav) / pWav->channels;
    while (bytesToWrite > 0) {
        drwav_uint8 temp[4096];
        drwav_uint32 sampleCount;
        size_t bytesJustWritten;
        drwav_uint64 bytesToWriteThisIteration;
        bytesToWriteThisIteration = bytesToWrite;
        DRWAV_ASSERT(bytesToWriteThisIteration <= DRWAV_SIZE_MAX);
        sampleCount = sizeof(temp)/bytesPerSample;
        if (bytesToWriteThisIteration > ((drwav_uint64)sampleCount)*bytesPerSample) {
            bytesToWriteThisIteration = ((drwav_uint64)sampleCount)*bytesPerSample;

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

        bytesJustWritten = drwav_write_raw(pWav, (size_t)bytesToWriteThisIteration, temp);
        if (bytesJustWritten == 0) {
            break;
        }
        bytesToWrite -= bytesJustWritten;
        bytesWritten += bytesJustWritten;
        pRunningData += bytesJustWritten;
    }
    return (bytesWritten * 8) / pWav->bitsPerSample / pWav->channels;
}
DRWAV_API drwav_uint64 drwav_write_pcm_frames(drwav* pWav, drwav_uint64 framesToWrite, const void* pData)
{
    if (drwav__is_little_endian()) {
        return drwav_write_pcm_frames_le(pWav, framesToWrite, pData);
    } else {
        return drwav_write_pcm_frames_be(pWav, framesToWrite, pData);
    }
}
static drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 totalFramesRead = 0;
    DRWAV_ASSERT(pWav != NULL);
    DRWAV_ASSERT(framesToRead > 0);
    while (framesToRead > 0 && pWav->compressed.iCurrentPCMFrame < pWav->totalPCMFrameCount) {
        if (pWav->msadpcm.cachedFrameCount == 0 && pWav->msadpcm.bytesRemainingInBlock == 0) {
            if (pWav->channels == 1) {
                drwav_uint8 header[7];
                if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
                    return totalFramesRead;
                }
                pWav->msadpcm.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
                pWav->msadpcm.predictor[0]     = header[0];
                pWav->msadpcm.delta[0]         = drwav__bytes_to_s16(header + 1);
                pWav->msadpcm.prevFrames[0][1] = (drwav_int32)drwav__bytes_to_s16(header + 3);

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

                pWav->msadpcm.prevFrames[1][1] = (drwav_int32)drwav__bytes_to_s16(header + 8);
                pWav->msadpcm.prevFrames[0][0] = (drwav_int32)drwav__bytes_to_s16(header + 10);
                pWav->msadpcm.prevFrames[1][0] = (drwav_int32)drwav__bytes_to_s16(header + 12);
                pWav->msadpcm.cachedFrames[0] = pWav->msadpcm.prevFrames[0][0];
                pWav->msadpcm.cachedFrames[1] = pWav->msadpcm.prevFrames[1][0];
                pWav->msadpcm.cachedFrames[2] = pWav->msadpcm.prevFrames[0][1];
                pWav->msadpcm.cachedFrames[3] = pWav->msadpcm.prevFrames[1][1];
                pWav->msadpcm.cachedFrameCount = 2;
            }
        }
        while (framesToRead > 0 && pWav->msadpcm.cachedFrameCount > 0 && pWav->compressed.iCurrentPCMFrame < pWav->totalPCMFrameCount) {
            if (pBufferOut != NULL) {
                drwav_uint32 iSample = 0;
                for (iSample = 0; iSample < pWav->channels; iSample += 1) {
                    pBufferOut[iSample] = (drwav_int16)pWav->msadpcm.cachedFrames[(drwav_countof(pWav->msadpcm.cachedFrames) - (pWav->msadpcm.cachedFrameCount*pWav->channels)) + iSample];
                }
                pBufferOut += pWav->channels;
            }
            framesToRead    -= 1;
            totalFramesRead += 1;
            pWav->compressed.iCurrentPCMFrame += 1;
            pWav->msadpcm.cachedFrameCount -= 1;
        }
        if (framesToRead == 0) {
            return totalFramesRead;
        }
        if (pWav->msadpcm.cachedFrameCount == 0) {
            if (pWav->msadpcm.bytesRemainingInBlock == 0) {
                continue;
            } else {
                static drwav_int32 adaptationTable[] = {
                    230, 230, 230, 230, 307, 409, 512, 614,
                    768, 614, 512, 409, 307, 230, 230, 230
                };

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

                    pWav->msadpcm.prevFrames[1][1] = newSample1;
                    pWav->msadpcm.cachedFrames[2] = newSample0;
                    pWav->msadpcm.cachedFrames[3] = newSample1;
                    pWav->msadpcm.cachedFrameCount = 1;
                }
            }
        }
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 totalFramesRead = 0;
    drwav_uint32 iChannel;
    static drwav_int32 indexTable[16] = {
        -1, -1, -1, -1, 2, 4, 6, 8,
        -1, -1, -1, -1, 2, 4, 6, 8
    };
    static drwav_int32 stepTable[89] = {
        7,     8,     9,     10,    11,    12,    13,    14,    16,    17,
        19,    21,    23,    25,    28,    31,    34,    37,    41,    45,
        50,    55,    60,    66,    73,    80,    88,    97,    107,   118,
        130,   143,   157,   173,   190,   209,   230,   253,   279,   307,
        337,   371,   408,   449,   494,   544,   598,   658,   724,   796,
        876,   963,   1060,  1166,  1282,  1411,  1552,  1707,  1878,  2066,
        2272,  2499,  2749,  3024,  3327,  3660,  4026,  4428,  4871,  5358,
        5894,  6484,  7132,  7845,  8630,  9493,  10442, 11487, 12635, 13899,
        15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
    };
    DRWAV_ASSERT(pWav != NULL);
    DRWAV_ASSERT(framesToRead > 0);
    while (framesToRead > 0 && pWav->compressed.iCurrentPCMFrame < pWav->totalPCMFrameCount) {
        if (pWav->ima.cachedFrameCount == 0 && pWav->ima.bytesRemainingInBlock == 0) {
            if (pWav->channels == 1) {
                drwav_uint8 header[4];
                if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
                    return totalFramesRead;
                }
                pWav->ima.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
                if (header[2] >= drwav_countof(stepTable)) {
                    pWav->onSeek(pWav->pUserData, pWav->ima.bytesRemainingInBlock, drwav_seek_origin_current);
                    pWav->ima.bytesRemainingInBlock = 0;

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

                }
                pWav->ima.predictor[0] = drwav__bytes_to_s16(header + 0);
                pWav->ima.stepIndex[0] = header[2];
                pWav->ima.predictor[1] = drwav__bytes_to_s16(header + 4);
                pWav->ima.stepIndex[1] = header[6];
                pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 2] = pWav->ima.predictor[0];
                pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[1];
                pWav->ima.cachedFrameCount = 1;
            }
        }
        while (framesToRead > 0 && pWav->ima.cachedFrameCount > 0 && pWav->compressed.iCurrentPCMFrame < pWav->totalPCMFrameCount) {
            if (pBufferOut != NULL) {
                drwav_uint32 iSample;
                for (iSample = 0; iSample < pWav->channels; iSample += 1) {
                    pBufferOut[iSample] = (drwav_int16)pWav->ima.cachedFrames[(drwav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + iSample];
                }
                pBufferOut += pWav->channels;
            }
            framesToRead    -= 1;
            totalFramesRead += 1;
            pWav->compressed.iCurrentPCMFrame += 1;
            pWav->ima.cachedFrameCount -= 1;
        }
        if (framesToRead == 0) {
            return totalFramesRead;
        }
        if (pWav->ima.cachedFrameCount == 0) {
            if (pWav->ima.bytesRemainingInBlock == 0) {
                continue;
            } else {
                pWav->ima.cachedFrameCount = 8;
                for (iChannel = 0; iChannel < pWav->channels; ++iChannel) {
                    drwav_uint32 iByte;
                    drwav_uint8 nibbles[4];

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

        drwav_f32_to_s16(pOut, (const float*)pIn, totalSampleCount);
        return;
    } else if (bytesPerSample == 8) {
        drwav_f64_to_s16(pOut, (const double*)pIn, totalSampleCount);
        return;
    } else {
        DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
        return;
    }
}
static drwav_uint64 drwav_read_pcm_frames_s16__pcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint32 bytesPerFrame;
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096];
    if ((pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 16) || pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
        if (framesRead == 0) {
            break;
        }
        drwav__pcm_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_s16__ieee(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096];
    drwav_uint32 bytesPerFrame;
    if (pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, NULL);
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
        if (framesRead == 0) {
            break;
        }
        drwav__ieee_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_s16__alaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096];
    drwav_uint32 bytesPerFrame;
    if (pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, NULL);
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
        if (framesRead == 0) {
            break;
        }
        drwav_alaw_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_s16__mulaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096];
    drwav_uint32 bytesPerFrame;
    if (pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, NULL);
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
        if (framesRead == 0) {
            break;
        }
        drwav_mulaw_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    if (pWav == NULL || framesToRead == 0) {
        return 0;
    }
    if (pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, NULL);
    }
    if (framesToRead * pWav->channels * sizeof(drwav_int16) > DRWAV_SIZE_MAX) {
        framesToRead = DRWAV_SIZE_MAX / sizeof(drwav_int16) / pWav->channels;
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
        return drwav_read_pcm_frames_s16__pcm(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
        return drwav_read_pcm_frames_s16__ieee(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
        return drwav_read_pcm_frames_s16__alaw(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
        return drwav_read_pcm_frames_s16__mulaw(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
        return drwav_read_pcm_frames_s16__msadpcm(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
        return drwav_read_pcm_frames_s16__ima(pWav, framesToRead, pBufferOut);
    }
    return 0;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16le(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_FALSE) {
        drwav__bswap_samples_s16(pBufferOut, framesRead*pWav->channels);
    }
    return framesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16be(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_TRUE) {
        drwav__bswap_samples_s16(pBufferOut, framesRead*pWav->channels);
    }
    return framesRead;
}
DRWAV_API void drwav_u8_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
{
    int r;
    size_t i;
    for (i = 0; i < sampleCount; ++i) {
        int x = pIn[i];
        r = x << 8;
        r = r - 32768;
        pOut[i] = (short)r;

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

        }
        return;
    } else if (bytesPerSample == 8) {
        drwav_f64_to_f32(pOut, (const double*)pIn, sampleCount);
        return;
    } else {
        DRWAV_ZERO_MEMORY(pOut, sampleCount * sizeof(*pOut));
        return;
    }
}
static drwav_uint64 drwav_read_pcm_frames_f32__pcm(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096];
    drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
        if (framesRead == 0) {
            break;
        }
        drwav__pcm_to_f32(pBufferOut, sampleData, (size_t)framesRead*pWav->channels, bytesPerFrame/pWav->channels);
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_f32__msadpcm(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 totalFramesRead = 0;
    drwav_int16 samples16[2048];
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
        if (framesRead == 0) {
            break;
        }
        drwav_s16_to_f32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_f32__ima(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 totalFramesRead = 0;
    drwav_int16 samples16[2048];
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
        if (framesRead == 0) {
            break;
        }
        drwav_s16_to_f32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_f32__ieee(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096];
    drwav_uint32 bytesPerFrame;
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT && pWav->bitsPerSample == 32) {
        return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
        if (framesRead == 0) {
            break;
        }
        drwav__ieee_to_f32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_f32__alaw(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096];
    drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
        if (framesRead == 0) {
            break;
        }
        drwav_alaw_to_f32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_f32__mulaw(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096];
    drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
        if (framesRead == 0) {
            break;
        }
        drwav_mulaw_to_f32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    if (pWav == NULL || framesToRead == 0) {
        return 0;
    }
    if (pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, NULL);
    }
    if (framesToRead * pWav->channels * sizeof(float) > DRWAV_SIZE_MAX) {
        framesToRead = DRWAV_SIZE_MAX / sizeof(float) / pWav->channels;
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
        return drwav_read_pcm_frames_f32__pcm(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
        return drwav_read_pcm_frames_f32__msadpcm(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
        return drwav_read_pcm_frames_f32__ieee(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
        return drwav_read_pcm_frames_f32__alaw(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
        return drwav_read_pcm_frames_f32__mulaw(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
        return drwav_read_pcm_frames_f32__ima(pWav, framesToRead, pBufferOut);
    }
    return 0;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32le(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_f32(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_FALSE) {
        drwav__bswap_samples_f32(pBufferOut, framesRead*pWav->channels);
    }
    return framesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32be(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_f32(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_TRUE) {
        drwav__bswap_samples_f32(pBufferOut, framesRead*pWav->channels);
    }
    return framesRead;
}
DRWAV_API void drwav_u8_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
{
    size_t i;
    if (pOut == NULL || pIn == NULL) {
        return;
    }
#ifdef DR_WAV_LIBSNDFILE_COMPAT
    for (i = 0; i < sampleCount; ++i) {
        *pOut++ = (pIn[i] / 256.0f) * 2 - 1;

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

        drwav_f32_to_s32(pOut, (const float*)pIn, totalSampleCount);
        return;
    } else if (bytesPerSample == 8) {
        drwav_f64_to_s32(pOut, (const double*)pIn, totalSampleCount);
        return;
    } else {
        DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
        return;
    }
}
static drwav_uint64 drwav_read_pcm_frames_s32__pcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096];
    drwav_uint32 bytesPerFrame;
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 32) {
        return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
        if (framesRead == 0) {
            break;
        }
        drwav__pcm_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_s32__msadpcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 totalFramesRead = 0;
    drwav_int16 samples16[2048];
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
        if (framesRead == 0) {
            break;
        }
        drwav_s16_to_s32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_s32__ima(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 totalFramesRead = 0;
    drwav_int16 samples16[2048];
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
        if (framesRead == 0) {
            break;
        }
        drwav_s16_to_s32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_s32__ieee(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096];
    drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
        if (framesRead == 0) {
            break;
        }
        drwav__ieee_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_s32__alaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096];
    drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
        if (framesRead == 0) {
            break;
        }
        drwav_alaw_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
static drwav_uint64 drwav_read_pcm_frames_s32__mulaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096];
    drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
        if (framesRead == 0) {
            break;
        }
        drwav_mulaw_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    if (pWav == NULL || framesToRead == 0) {
        return 0;
    }
    if (pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, NULL);
    }
    if (framesToRead * pWav->channels * sizeof(drwav_int32) > DRWAV_SIZE_MAX) {
        framesToRead = DRWAV_SIZE_MAX / sizeof(drwav_int32) / pWav->channels;
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
        return drwav_read_pcm_frames_s32__pcm(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
        return drwav_read_pcm_frames_s32__msadpcm(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
        return drwav_read_pcm_frames_s32__ieee(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
        return drwav_read_pcm_frames_s32__alaw(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
        return drwav_read_pcm_frames_s32__mulaw(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
        return drwav_read_pcm_frames_s32__ima(pWav, framesToRead, pBufferOut);
    }
    return 0;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32le(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_s32(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_FALSE) {
        drwav__bswap_samples_s32(pBufferOut, framesRead*pWav->channels);
    }
    return framesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32be(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_s32(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_TRUE) {
        drwav__bswap_samples_s32(pBufferOut, framesRead*pWav->channels);
    }
    return framesRead;
}
DRWAV_API void drwav_u8_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
{
    size_t i;
    if (pOut == NULL || pIn == NULL) {
        return;
    }
    for (i = 0; i < sampleCount; ++i) {
        *pOut++ = ((int)pIn[i] - 128) << 24;
    }

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

DRWAV_API void drwav_mulaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
{
    size_t i;
    if (pOut == NULL || pIn == NULL) {
        return;
    }
    for (i= 0; i < sampleCount; ++i) {
        *pOut++ = ((drwav_int32)drwav__mulaw_to_s16(pIn[i])) << 16;
    }
}
static drwav_int16* drwav__read_pcm_frames_and_close_s16(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
{
    drwav_uint64 sampleDataSize;
    drwav_int16* pSampleData;
    drwav_uint64 framesRead;
    DRWAV_ASSERT(pWav != NULL);
    sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(drwav_int16);
    if (sampleDataSize > DRWAV_SIZE_MAX) {
        drwav_uninit(pWav);
        return NULL;
    }
    pSampleData = (drwav_int16*)drwav__malloc_from_callbacks((size_t)sampleDataSize, &pWav->allocationCallbacks);
    if (pSampleData == NULL) {
        drwav_uninit(pWav);
        return NULL;
    }
    framesRead = drwav_read_pcm_frames_s16(pWav, (size_t)pWav->totalPCMFrameCount, pSampleData);
    if (framesRead != pWav->totalPCMFrameCount) {
        drwav__free_from_callbacks(pSampleData, &pWav->allocationCallbacks);
        drwav_uninit(pWav);
        return NULL;
    }
    drwav_uninit(pWav);
    if (sampleRate) {
        *sampleRate = pWav->sampleRate;
    }
    if (channels) {
        *channels = pWav->channels;
    }
    if (totalFrameCount) {
        *totalFrameCount = pWav->totalPCMFrameCount;
    }
    return pSampleData;
}
static float* drwav__read_pcm_frames_and_close_f32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
{
    drwav_uint64 sampleDataSize;
    float* pSampleData;
    drwav_uint64 framesRead;
    DRWAV_ASSERT(pWav != NULL);
    sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(float);
    if (sampleDataSize > DRWAV_SIZE_MAX) {
        drwav_uninit(pWav);
        return NULL;
    }
    pSampleData = (float*)drwav__malloc_from_callbacks((size_t)sampleDataSize, &pWav->allocationCallbacks);
    if (pSampleData == NULL) {
        drwav_uninit(pWav);
        return NULL;
    }
    framesRead = drwav_read_pcm_frames_f32(pWav, (size_t)pWav->totalPCMFrameCount, pSampleData);
    if (framesRead != pWav->totalPCMFrameCount) {
        drwav__free_from_callbacks(pSampleData, &pWav->allocationCallbacks);
        drwav_uninit(pWav);
        return NULL;
    }
    drwav_uninit(pWav);
    if (sampleRate) {
        *sampleRate = pWav->sampleRate;
    }
    if (channels) {
        *channels = pWav->channels;
    }
    if (totalFrameCount) {
        *totalFrameCount = pWav->totalPCMFrameCount;
    }
    return pSampleData;
}
static drwav_int32* drwav__read_pcm_frames_and_close_s32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
{
    drwav_uint64 sampleDataSize;
    drwav_int32* pSampleData;
    drwav_uint64 framesRead;
    DRWAV_ASSERT(pWav != NULL);
    sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(drwav_int32);
    if (sampleDataSize > DRWAV_SIZE_MAX) {
        drwav_uninit(pWav);
        return NULL;
    }
    pSampleData = (drwav_int32*)drwav__malloc_from_callbacks((size_t)sampleDataSize, &pWav->allocationCallbacks);
    if (pSampleData == NULL) {
        drwav_uninit(pWav);
        return NULL;
    }
    framesRead = drwav_read_pcm_frames_s32(pWav, (size_t)pWav->totalPCMFrameCount, pSampleData);
    if (framesRead != pWav->totalPCMFrameCount) {
        drwav__free_from_callbacks(pSampleData, &pWav->allocationCallbacks);
        drwav_uninit(pWav);
        return NULL;
    }
    drwav_uninit(pWav);
    if (sampleRate) {
        *sampleRate = pWav->sampleRate;
    }
    if (channels) {
        *channels = pWav->channels;
    }
    if (totalFrameCount) {
        *totalFrameCount = pWav->totalPCMFrameCount;
    }
    return pSampleData;
}
DRWAV_API drwav_int16* drwav_open_and_read_pcm_frames_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAl...
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API float* drwav_open_and_read_pcm_frames_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocati...
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API drwav_int32* drwav_open_and_read_pcm_frames_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAl...
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
#ifndef DR_WAV_NO_STDIO
DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_file(&wav, filename, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_file(&wav, filename, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_file(&wav, filename, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_file_w(&wav, filename, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_file_w(&wav, filename, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_file_w(&wav, filename, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
#endif
DRWAV_API drwav_int16* drwav_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_memory(&wav, data, dataSize, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API float* drwav_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_memory(&wav, data, dataSize, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API drwav_int32* drwav_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_memory(&wav, data, dataSize, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
#endif
DRWAV_API void drwav_free(void* p, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    if (pAllocationCallbacks != NULL) {
        drwav__free_from_callbacks(p, pAllocationCallbacks);
    } else {
        drwav__free_default(p, NULL);
    }
}

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

            }
        }
        if (partitionsRemaining == 1) {
            break;
        }
        partitionsRemaining -= 1;
        samplesInPartition = blockSize / (1 << partitionOrder);
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__decode_samples__constant(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
{
    drflac_uint32 i;
    drflac_int32 sample;
    if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
        return DRFLAC_FALSE;
    }
    for (i = 0; i < blockSize; ++i) {
        pDecodedSamples[i] = sample;
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
{
    drflac_uint32 i;
    for (i = 0; i < blockSize; ++i) {
        drflac_int32 sample;
        if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
            return DRFLAC_FALSE;
        }
        pDecodedSamples[i] = sample;
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__decode_samples__fixed(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
{
    drflac_uint32 i;
    static drflac_int32 lpcCoefficientsTable[5][4] = {
        {0,  0, 0,  0},
        {1,  0, 0,  0},
        {2, -1, 0,  0},
        {3, -3, 1,  0},
        {4, -6, 4, -1}
    };
    for (i = 0; i < lpcOrder; ++i) {
        drflac_int32 sample;
        if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
            return DRFLAC_FALSE;
        }
        pDecodedSamples[i] = sample;
    }
    if (!drflac__decode_samples_with_residual(bs, subframeBitsPerSample, blockSize, lpcOrder, 0, lpcCoefficientsTable[lpcOrder], pDecodedSamples)) {
        return DRFLAC_FALSE;
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__decode_samples__lpc(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
{
    drflac_uint8 i;
    drflac_uint8 lpcPrecision;
    drflac_int8 lpcShift;
    drflac_int32 coefficients[32];

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

    for (i = 0; i < lpcOrder; ++i) {
        if (!drflac__read_int32(bs, lpcPrecision, coefficients + i)) {
            return DRFLAC_FALSE;
        }
    }
    if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, lpcShift, coefficients, pDecodedSamples)) {
        return DRFLAC_FALSE;
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__read_next_flac_frame_header(drflac_bs* bs, drflac_uint8 streaminfoBitsPerSample, drflac_frame_header* header)
{
    const drflac_uint32 sampleRateTable[12]  = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
    const drflac_uint8 bitsPerSampleTable[8] = {0, 8, 12, (drflac_uint8)-1, 16, 20, 24, (drflac_uint8)-1};
    DRFLAC_ASSERT(bs != NULL);
    DRFLAC_ASSERT(header != NULL);
    for (;;) {
        drflac_uint8 crc8 = 0xCE;
        drflac_uint8 reserved = 0;
        drflac_uint8 blockingStrategy = 0;
        drflac_uint8 blockSize = 0;

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

            return DRFLAC_FALSE;
        }
#ifndef DR_FLAC_NO_CRC
        if (header->crc8 != crc8) {
            continue;
        }
#endif
        return DRFLAC_TRUE;
    }
}
static drflac_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe)
{
    drflac_uint8 header;
    int type;
    if (!drflac__read_uint8(bs, 8, &header)) {
        return DRFLAC_FALSE;
    }
    if ((header & 0x80) != 0) {
        return DRFLAC_FALSE;
    }
    type = (header & 0x7E) >> 1;
    if (type == 0) {
        pSubframe->subframeType = DRFLAC_SUBFRAME_CONSTANT;
    } else if (type == 1) {
        pSubframe->subframeType = DRFLAC_SUBFRAME_VERBATIM;
    } else {
        if ((type & 0x20) != 0) {
            pSubframe->subframeType = DRFLAC_SUBFRAME_LPC;
            pSubframe->lpcOrder = (drflac_uint8)(type & 0x1F) + 1;
        } else if ((type & 0x08) != 0) {
            pSubframe->subframeType = DRFLAC_SUBFRAME_FIXED;
            pSubframe->lpcOrder = (drflac_uint8)(type & 0x07);
            if (pSubframe->lpcOrder > 4) {
                pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED;
                pSubframe->lpcOrder = 0;
            }
        } else {
            pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED;
        }
    }
    if (pSubframe->subframeType == DRFLAC_SUBFRAME_RESERVED) {
        return DRFLAC_FALSE;
    }
    pSubframe->wastedBitsPerSample = 0;
    if ((header & 0x01) == 1) {
        unsigned int wastedBitsPerSample;
        if (!drflac__seek_past_next_set_bit(bs, &wastedBitsPerSample)) {
            return DRFLAC_FALSE;
        }
        pSubframe->wastedBitsPerSample = (drflac_uint8)wastedBitsPerSample + 1;
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, drflac_int32* pDecodedSamplesOut)
{
    drflac_subframe* pSubframe;
    drflac_uint32 subframeBitsPerSample;
    DRFLAC_ASSERT(bs != NULL);
    DRFLAC_ASSERT(frame != NULL);
    pSubframe = frame->subframes + subframeIndex;
    if (!drflac__read_subframe_header(bs, pSubframe)) {
        return DRFLAC_FALSE;
    }
    subframeBitsPerSample = frame->header.bitsPerSample;
    if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
        subframeBitsPerSample += 1;
    } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
        subframeBitsPerSample += 1;
    }
    if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
        return DRFLAC_FALSE;
    }
    subframeBitsPerSample -= pSubframe->wastedBitsPerSample;
    pSubframe->pSamplesS32 = pDecodedSamplesOut;
    switch (pSubframe->subframeType)
    {
        case DRFLAC_SUBFRAME_CONSTANT:
        {
            drflac__decode_samples__constant(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
        } break;
        case DRFLAC_SUBFRAME_VERBATIM:
        {
            drflac__decode_samples__verbatim(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
        } break;
        case DRFLAC_SUBFRAME_FIXED:
        {
            drflac__decode_samples__fixed(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
        } break;
        case DRFLAC_SUBFRAME_LPC:
        {
            drflac__decode_samples__lpc(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
        } break;
        default: return DRFLAC_FALSE;
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex)
{
    drflac_subframe* pSubframe;
    drflac_uint32 subframeBitsPerSample;
    DRFLAC_ASSERT(bs != NULL);
    DRFLAC_ASSERT(frame != NULL);
    pSubframe = frame->subframes + subframeIndex;
    if (!drflac__read_subframe_header(bs, pSubframe)) {
        return DRFLAC_FALSE;
    }
    subframeBitsPerSample = frame->header.bitsPerSample;
    if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
        subframeBitsPerSample += 1;
    } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
        subframeBitsPerSample += 1;
    }
    if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
        return DRFLAC_FALSE;
    }
    subframeBitsPerSample -= pSubframe->wastedBitsPerSample;
    pSubframe->pSamplesS32 = NULL;
    switch (pSubframe->subframeType)
    {
        case DRFLAC_SUBFRAME_CONSTANT:
        {
            if (!drflac__seek_bits(bs, subframeBitsPerSample)) {
                return DRFLAC_FALSE;
            }
        } break;
        case DRFLAC_SUBFRAME_VERBATIM:
        {
            unsigned int bitsToSeek = frame->header.blockSizeInPCMFrames * subframeBitsPerSample;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }
        } break;
        case DRFLAC_SUBFRAME_FIXED:
        {
            unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }
            if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
                return DRFLAC_FALSE;
            }
        } break;
        case DRFLAC_SUBFRAME_LPC:
        {
            drflac_uint8 lpcPrecision;
            unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }
            if (!drflac__read_uint8(bs, 4, &lpcPrecision)) {
                return DRFLAC_FALSE;
            }
            if (lpcPrecision == 15) {
                return DRFLAC_FALSE;
            }
            lpcPrecision += 1;
            bitsToSeek = (pSubframe->lpcOrder * lpcPrecision) + 5;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }
            if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
                return DRFLAC_FALSE;
            }
        } break;
        default: return DRFLAC_FALSE;
    }
    return DRFLAC_TRUE;
}
static DRFLAC_INLINE drflac_uint8 drflac__get_channel_count_from_channel_assignment(drflac_int8 channelAssignment)
{
    drflac_uint8 lookup[] = {1, 2, 3, 4, 5, 6, 7, 8, 2, 2, 2};
    DRFLAC_ASSERT(channelAssignment <= 10);
    return lookup[channelAssignment];
}
static drflac_result drflac__decode_flac_frame(drflac* pFlac)
{
    int channelCount;
    int i;
    drflac_uint8 paddingSizeInBits;
    drflac_uint16 desiredCRC16;
#ifndef DR_FLAC_NO_CRC
    drflac_uint16 actualCRC16;
#endif
    DRFLAC_ZERO_MEMORY(pFlac->currentFLACFrame.subframes, sizeof(pFlac->currentFLACFrame.subframes));
    if (pFlac->currentFLACFrame.header.blockSizeInPCMFrames > pFlac->maxBlockSizeInPCMFrames) {
        return DRFLAC_ERROR;
    }
    channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
    if (channelCount != (int)pFlac->channels) {
        return DRFLAC_ERROR;
    }
    for (i = 0; i < channelCount; ++i) {
        if (!drflac__decode_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i, pFlac->pDecodedSamples + (pFlac->currentFLACFrame.header.blockSizeInPCMFrames * i))) {
            return DRFLAC_ERROR;
        }
    }
    paddingSizeInBits = (drflac_uint8)(DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7);
    if (paddingSizeInBits > 0) {
        drflac_uint8 padding = 0;
        if (!drflac__read_uint8(&pFlac->bs, paddingSizeInBits, &padding)) {
            return DRFLAC_AT_END;
        }
    }

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

        return DRFLAC_AT_END;
    }
#ifndef DR_FLAC_NO_CRC
    if (actualCRC16 != desiredCRC16) {
        return DRFLAC_CRC_MISMATCH;
    }
#endif
    pFlac->currentFLACFrame.pcmFramesRemaining = pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
    return DRFLAC_SUCCESS;
}
static drflac_result drflac__seek_flac_frame(drflac* pFlac)
{
    int channelCount;
    int i;
    drflac_uint16 desiredCRC16;
#ifndef DR_FLAC_NO_CRC
    drflac_uint16 actualCRC16;
#endif
    channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
    for (i = 0; i < channelCount; ++i) {
        if (!drflac__seek_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i)) {
            return DRFLAC_ERROR;
        }
    }
    if (!drflac__seek_bits(&pFlac->bs, DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7)) {
        return DRFLAC_ERROR;
    }
#ifndef DR_FLAC_NO_CRC
    actualCRC16 = drflac__flush_crc16(&pFlac->bs);
#endif
    if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) {
        return DRFLAC_AT_END;
    }
#ifndef DR_FLAC_NO_CRC
    if (actualCRC16 != desiredCRC16) {
        return DRFLAC_CRC_MISMATCH;
    }
#endif
    return DRFLAC_SUCCESS;
}
static drflac_bool32 drflac__read_and_decode_next_flac_frame(drflac* pFlac)
{
    DRFLAC_ASSERT(pFlac != NULL);
    for (;;) {
        drflac_result result;
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
        result = drflac__decode_flac_frame(pFlac);
        if (result != DRFLAC_SUCCESS) {
            if (result == DRFLAC_CRC_MISMATCH) {
                continue;
            } else {
                return DRFLAC_FALSE;
            }
        }
        return DRFLAC_TRUE;
    }
}
static void drflac__get_pcm_frame_range_of_current_flac_frame(drflac* pFlac, drflac_uint64* pFirstPCMFrame, drflac_uint64* pLastPCMFrame)
{
    drflac_uint64 firstPCMFrame;
    drflac_uint64 lastPCMFrame;
    DRFLAC_ASSERT(pFlac != NULL);
    firstPCMFrame = pFlac->currentFLACFrame.header.pcmFrameNumber;
    if (firstPCMFrame == 0) {
        firstPCMFrame = ((drflac_uint64)pFlac->currentFLACFrame.header.flacFrameNumber) * pFlac->maxBlockSizeInPCMFrames;
    }
    lastPCMFrame = firstPCMFrame + pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
    if (lastPCMFrame > 0) {
        lastPCMFrame -= 1;
    }
    if (pFirstPCMFrame) {
        *pFirstPCMFrame = firstPCMFrame;
    }
    if (pLastPCMFrame) {
        *pLastPCMFrame = lastPCMFrame;
    }
}
static drflac_bool32 drflac__seek_to_first_frame(drflac* pFlac)
{
    drflac_bool32 result;
    DRFLAC_ASSERT(pFlac != NULL);
    result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes);
    DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
    pFlac->currentPCMFrame = 0;
    return result;
}
static DRFLAC_INLINE drflac_result drflac__seek_to_next_flac_frame(drflac* pFlac)
{
    DRFLAC_ASSERT(pFlac != NULL);
    return drflac__seek_flac_frame(pFlac);
}
static drflac_uint64 drflac__seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 pcmFramesToSeek)
{
    drflac_uint64 pcmFramesRead = 0;
    while (pcmFramesToSeek > 0) {
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;
            }
        } else {
            if (pFlac->currentFLACFrame.pcmFramesRemaining > pcmFramesToSeek) {
                pcmFramesRead   += pcmFramesToSeek;
                pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)pcmFramesToSeek;
                pcmFramesToSeek  = 0;
            } else {
                pcmFramesRead   += pFlac->currentFLACFrame.pcmFramesRemaining;
                pcmFramesToSeek -= pFlac->currentFLACFrame.pcmFramesRemaining;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
            }
        }
    }
    pFlac->currentPCMFrame += pcmFramesRead;
    return pcmFramesRead;
}
static drflac_bool32 drflac__seek_to_pcm_frame__brute_force(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_bool32 isMidFrame = DRFLAC_FALSE;
    drflac_uint64 runningPCMFrameCount;
    DRFLAC_ASSERT(pFlac != NULL);
    if (pcmFrameIndex >= pFlac->currentPCMFrame) {
        runningPCMFrameCount = pFlac->currentPCMFrame;
        if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                return DRFLAC_FALSE;
            }
        } else {
            isMidFrame = DRFLAC_TRUE;
        }
    } else {
        runningPCMFrameCount = 0;
        if (!drflac__seek_to_first_frame(pFlac)) {
            return DRFLAC_FALSE;
        }
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }
    for (;;) {
        drflac_uint64 pcmFrameCountInThisFLACFrame;
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
        drflac_uint64 lastPCMFrameInFLACFrame = 0;
        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
        pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
            drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;
            if (!isMidFrame) {
                drflac_result result = drflac__decode_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
            }
        } else {
            if (!isMidFrame) {
                drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
                isMidFrame = DRFLAC_FALSE;
            }
            if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
                return DRFLAC_TRUE;
            }
        }
    next_iteration:
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }
}
#if !defined(DR_FLAC_NO_CRC)
#define DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO 0.6f
static drflac_bool32 drflac__seek_to_approximate_flac_frame_to_byte(drflac* pFlac, drflac_uint64 targetByte, drflac_uint64 rangeLo, drflac_uint64 rangeHi, drflac_uint64* pLastSuccessfulSeekOffset)
{
    DRFLAC_ASSERT(pFlac != NULL);
    DRFLAC_ASSERT(pLastSuccessfulSeekOffset != NULL);
    DRFLAC_ASSERT(targetByte >= rangeLo);
    DRFLAC_ASSERT(targetByte <= rangeHi);
    *pLastSuccessfulSeekOffset = pFlac->firstFLACFramePosInBytes;
    for (;;) {
        if (!drflac__seek_to_byte(&pFlac->bs, targetByte)) {
            if (targetByte == 0) {
                drflac__seek_to_first_frame(pFlac);
                return DRFLAC_FALSE;
            }
            targetByte = rangeLo + ((rangeHi - rangeLo)/2);
            rangeHi = targetByte;
        } else {
            DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
#if 1
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                targetByte = rangeLo + ((rangeHi - rangeLo)/2);
                rangeHi = targetByte;
            } else {
                break;
            }
#else
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                targetByte = rangeLo + ((rangeHi - rangeLo)/2);
                rangeHi = targetByte;
            } else {
                break;
            }
#endif
        }
    }
    drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);
    DRFLAC_ASSERT(targetByte <= rangeHi);
    *pLastSuccessfulSeekOffset = targetByte;
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 offset)
{
#if 0
    if (drflac__decode_flac_frame(pFlac) != DRFLAC_SUCCESS) {
        if (drflac__read_and_decode_next_flac_frame(pFlac) == DRFLAC_FALSE) {
            return DRFLAC_FALSE;
        }
    }
#endif
    return drflac__seek_forward_by_pcm_frames(pFlac, offset) == offset;
}
static drflac_bool32 drflac__seek_to_pcm_frame__binary_search_internal(drflac* pFlac, drflac_uint64 pcmFrameIndex, drflac_uint64 byteRangeLo, drflac_uint64 byteRangeHi)
{
    drflac_uint64 targetByte;
    drflac_uint64 pcmRangeLo = pFlac->totalPCMFrameCount;
    drflac_uint64 pcmRangeHi = 0;
    drflac_uint64 lastSuccessfulSeekOffset = (drflac_uint64)-1;
    drflac_uint64 closestSeekOffsetBeforeTargetPCMFrame = byteRangeLo;
    drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
    targetByte = byteRangeLo + (drflac_uint64)(((drflac_int64)((pcmFrameIndex - pFlac->currentPCMFrame) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO);
    if (targetByte > byteRangeHi) {
        targetByte = byteRangeHi;
    }
    for (;;) {
        if (drflac__seek_to_approximate_flac_frame_to_byte(pFlac, targetByte, byteRangeLo, byteRangeHi, &lastSuccessfulSeekOffset)) {
            drflac_uint64 newPCMRangeLo;
            drflac_uint64 newPCMRangeHi;
            drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &newPCMRangeLo, &newPCMRangeHi);
            if (pcmRangeLo == newPCMRangeLo) {
                if (!drflac__seek_to_approximate_flac_frame_to_byte(pFlac, closestSeekOffsetBeforeTargetPCMFrame, closestSeekOffsetBeforeTargetPCMFrame, byteRangeHi, &lastSuccessfulSeekOffset)) {
                    break;
                }
                if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
                    return DRFLAC_TRUE;
                } else {
                    break;
                }
            }
            pcmRangeLo = newPCMRangeLo;
            pcmRangeHi = newPCMRangeHi;
            if (pcmRangeLo <= pcmFrameIndex && pcmRangeHi >= pcmFrameIndex) {
                if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame) ) {
                    return DRFLAC_TRUE;
                } else {
                    break;
                }
            } else {
                const float approxCompressionRatio = (drflac_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / ((drflac_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0f);
                if (pcmRangeLo > pcmFrameIndex) {
                    byteRangeHi = lastSuccessfulSeekOffset;
                    if (byteRangeLo > byteRangeHi) {
                        byteRangeLo = byteRangeHi;
                    }
                    targetByte = byteRangeLo + ((byteRangeHi - byteRangeLo) / 2);
                    if (targetByte < byteRangeLo) {
                        targetByte = byteRangeLo;
                    }
                } else  {
                    if ((pcmFrameIndex - pcmRangeLo) < seekForwardThreshold) {
                        if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
                            return DRFLAC_TRUE;
                        } else {
                            break;
                        }
                    } else {
                        byteRangeLo = lastSuccessfulSeekOffset;
                        if (byteRangeHi < byteRangeLo) {
                            byteRangeHi = byteRangeLo;
                        }
                        targetByte = lastSuccessfulSeekOffset + (drflac_uint64)(((drflac_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * approxCompressionRatio);

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

                        if (closestSeekOffsetBeforeTargetPCMFrame < lastSuccessfulSeekOffset) {
                            closestSeekOffsetBeforeTargetPCMFrame = lastSuccessfulSeekOffset;
                        }
                    }
                }
            }
        } else {
            break;
        }
    }
    drflac__seek_to_first_frame(pFlac);
    return DRFLAC_FALSE;
}
static drflac_bool32 drflac__seek_to_pcm_frame__binary_search(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_uint64 byteRangeLo;
    drflac_uint64 byteRangeHi;
    drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
    if (drflac__seek_to_first_frame(pFlac) == DRFLAC_FALSE) {
        return DRFLAC_FALSE;
    }
    if (pcmFrameIndex < seekForwardThreshold) {
        return drflac__seek_forward_by_pcm_frames(pFlac, pcmFrameIndex) == pcmFrameIndex;
    }
    byteRangeLo = pFlac->firstFLACFramePosInBytes;
    byteRangeHi = pFlac->firstFLACFramePosInBytes + (drflac_uint64)((drflac_int64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample)/8.0f);
    return drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi);
}
#endif
static drflac_bool32 drflac__seek_to_pcm_frame__seek_table(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_uint32 iClosestSeekpoint = 0;
    drflac_bool32 isMidFrame = DRFLAC_FALSE;
    drflac_uint64 runningPCMFrameCount;
    drflac_uint32 iSeekpoint;
    DRFLAC_ASSERT(pFlac != NULL);
    if (pFlac->pSeekpoints == NULL || pFlac->seekpointCount == 0) {
        return DRFLAC_FALSE;
    }
    for (iSeekpoint = 0; iSeekpoint < pFlac->seekpointCount; ++iSeekpoint) {

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

        if (iClosestSeekpoint < pFlac->seekpointCount-1) {
            drflac_uint32 iNextSeekpoint = iClosestSeekpoint + 1;
            if (pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset >= pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset || pFlac->pSeekpoints[iNextSeekpoint].pcmFrameCount == 0) {
                return DRFLAC_FALSE;
            }
            if (pFlac->pSeekpoints[iNextSeekpoint].firstPCMFrame != (((drflac_uint64)0xFFFFFFFF << 32) | 0xFFFFFFFF)) {
                byteRangeHi = pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset - 1;
            }
        }
        if (drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
            if (drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);
                if (drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi)) {
                    return DRFLAC_TRUE;
                }
            }
        }
    }
#endif
    if (pcmFrameIndex >= pFlac->currentPCMFrame && pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame <= pFlac->currentPCMFrame) {
        runningPCMFrameCount = pFlac->currentPCMFrame;
        if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                return DRFLAC_FALSE;
            }
        } else {
            isMidFrame = DRFLAC_TRUE;
        }
    } else {
        runningPCMFrameCount = pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame;
        if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
            return DRFLAC_FALSE;
        }
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }
    for (;;) {
        drflac_uint64 pcmFrameCountInThisFLACFrame;
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
        drflac_uint64 lastPCMFrameInFLACFrame = 0;
        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
        pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
            drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;
            if (!isMidFrame) {
                drflac_result result = drflac__decode_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
            }
        } else {
            if (!isMidFrame) {
                drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
                isMidFrame = DRFLAC_FALSE;
            }
            if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
                return DRFLAC_TRUE;
            }
        }
    next_iteration:
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }
}
#ifndef DR_FLAC_NO_OGG
typedef struct
{
    drflac_uint8 capturePattern[4];
    drflac_uint8 structureVersion;
    drflac_uint8 headerType;

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

    void* pUserDataMD;
    drflac_uint32 sampleRate;
    drflac_uint8  channels;
    drflac_uint8  bitsPerSample;
    drflac_uint64 totalPCMFrameCount;
    drflac_uint16 maxBlockSizeInPCMFrames;
    drflac_uint64 runningFilePos;
    drflac_bool32 hasStreamInfoBlock;
    drflac_bool32 hasMetadataBlocks;
    drflac_bs bs;
    drflac_frame_header firstFrameHeader;
#ifndef DR_FLAC_NO_OGG
    drflac_uint32 oggSerial;
    drflac_uint64 oggFirstBytePos;
    drflac_ogg_page_header oggBosHeader;
#endif
} drflac_init_info;
static DRFLAC_INLINE void drflac__decode_block_header(drflac_uint32 blockHeader, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize)
{
    blockHeader = drflac__be2host_32(blockHeader);
    *isLastBlock = (drflac_uint8)((blockHeader & 0x80000000UL) >> 31);

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

    *blockSize = 0;
    if (onRead(pUserData, &blockHeader, 4) != 4) {
        return DRFLAC_FALSE;
    }
    drflac__decode_block_header(blockHeader, isLastBlock, blockType, blockSize);
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo)
{
    drflac_uint32 blockSizes;
    drflac_uint64 frameSizes = 0;
    drflac_uint64 importantProps;
    drflac_uint8 md5[16];
    if (onRead(pUserData, &blockSizes, 4) != 4) {
        return DRFLAC_FALSE;
    }
    if (onRead(pUserData, &frameSizes, 6) != 6) {
        return DRFLAC_FALSE;
    }
    if (onRead(pUserData, &importantProps, 8) != 8) {
        return DRFLAC_FALSE;
    }
    if (onRead(pUserData, md5, sizeof(md5)) != sizeof(md5)) {
        return DRFLAC_FALSE;
    }
    blockSizes     = drflac__be2host_32(blockSizes);
    frameSizes     = drflac__be2host_64(frameSizes);
    importantProps = drflac__be2host_64(importantProps);
    pStreamInfo->minBlockSizeInPCMFrames = (drflac_uint16)((blockSizes & 0xFFFF0000) >> 16);
    pStreamInfo->maxBlockSizeInPCMFrames = (drflac_uint16) (blockSizes & 0x0000FFFF);
    pStreamInfo->minFrameSizeInPCMFrames = (drflac_uint32)((frameSizes     &  (((drflac_uint64)0x00FFFFFF << 16) << 24)) >> 40);
    pStreamInfo->maxFrameSizeInPCMFrames = (drflac_uint32)((frameSizes     &  (((drflac_uint64)0x00FFFFFF << 16) <<  0)) >> 16);
    pStreamInfo->sampleRate              = (drflac_uint32)((importantProps &  (((drflac_uint64)0x000FFFFF << 16) << 28)) >> 44);
    pStreamInfo->channels                = (drflac_uint8 )((importantProps &  (((drflac_uint64)0x0000000E << 16) << 24)) >> 41) + 1;
    pStreamInfo->bitsPerSample           = (drflac_uint8 )((importantProps &  (((drflac_uint64)0x0000001F << 16) << 20)) >> 36) + 1;
    pStreamInfo->totalPCMFrameCount      =                ((importantProps & ((((drflac_uint64)0x0000000F << 16) << 16) | 0xFFFFFFFF)));
    DRFLAC_COPY_MEMORY(pStreamInfo->md5, md5, sizeof(md5));
    return DRFLAC_TRUE;
}
static void* drflac__malloc_default(size_t sz, void* pUserData)
{
    (void)pUserData;

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

    pInit->container = drflac_container_native;
    if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
        return DRFLAC_FALSE;
    }
    if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) {
        if (!relaxed) {
            return DRFLAC_FALSE;
        } else {
            pInit->hasStreamInfoBlock = DRFLAC_FALSE;
            pInit->hasMetadataBlocks  = DRFLAC_FALSE;
            if (!drflac__read_next_flac_frame_header(&pInit->bs, 0, &pInit->firstFrameHeader)) {
                return DRFLAC_FALSE;
            }
            if (pInit->firstFrameHeader.bitsPerSample == 0) {
                return DRFLAC_FALSE;
            }
            pInit->sampleRate              = pInit->firstFrameHeader.sampleRate;
            pInit->channels                = drflac__get_channel_count_from_channel_assignment(pInit->firstFrameHeader.channelAssignment);
            pInit->bitsPerSample           = pInit->firstFrameHeader.bitsPerSample;
            pInit->maxBlockSizeInPCMFrames = 65535;
            return DRFLAC_TRUE;

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

                return DRFLAC_FALSE;
            }
            if ((oggbs->currentPageHeader.headerType & 0x01) == 0) {
                return DRFLAC_TRUE;
            }
        } else {
            return DRFLAC_TRUE;
        }
    }
}
static drflac_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs)
{
    return drflac_oggbs__seek_to_next_packet(oggbs);
}
#endif
static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytesToRead)
{
    drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
    drflac_uint8* pRunningBufferOut = (drflac_uint8*)bufferOut;
    size_t bytesRead = 0;
    DRFLAC_ASSERT(oggbs != NULL);

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

            bytesSeeked += (int)oggbs->bytesRemainingInPage;
            oggbs->bytesRemainingInPage = 0;
        }
        DRFLAC_ASSERT(bytesRemainingToSeek > 0);
        if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
            return DRFLAC_FALSE;
        }
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac_ogg__seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
    drflac_uint64 originalBytePos;
    drflac_uint64 runningGranulePosition;
    drflac_uint64 runningFrameBytePos;
    drflac_uint64 runningPCMFrameCount;
    DRFLAC_ASSERT(oggbs != NULL);
    originalBytePos = oggbs->currentBytePos;
    if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes)) {
        return DRFLAC_FALSE;

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

        return DRFLAC_FALSE;
    }
    if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
        return DRFLAC_FALSE;
    }
    runningPCMFrameCount = runningGranulePosition;
    for (;;) {
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
        drflac_uint64 lastPCMFrameInFLACFrame = 0;
        drflac_uint64 pcmFrameCountInThisFrame;
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
        pcmFrameCountInThisFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
        if (pcmFrameIndex == pFlac->totalPCMFrameCount && (runningPCMFrameCount + pcmFrameCountInThisFrame) == pFlac->totalPCMFrameCount) {
            drflac_result result = drflac__decode_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                pFlac->currentPCMFrame = pcmFrameIndex;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
                return DRFLAC_TRUE;
            } else {
                return DRFLAC_FALSE;
            }
        }
        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFrame)) {
            drflac_result result = drflac__decode_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                drflac_uint64 pcmFramesToDecode = (size_t)(pcmFrameIndex - runningPCMFrameCount);
                if (pcmFramesToDecode == 0) {
                    return DRFLAC_TRUE;
                }
                pFlac->currentPCMFrame = runningPCMFrameCount;
                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
            } else {
                if (result == DRFLAC_CRC_MISMATCH) {
                    continue;
                } else {
                    return DRFLAC_FALSE;
                }
            }
        } else {
            drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                runningPCMFrameCount += pcmFrameCountInThisFrame;
            } else {
                if (result == DRFLAC_CRC_MISMATCH) {
                    continue;
                } else {
                    return DRFLAC_FALSE;
                }
            }
        }

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

                }
            } else {
                pFlac->pSeekpoints = NULL;
                pFlac->seekpointCount = 0;
            }
        }
    }
    if (!init.hasStreamInfoBlock) {
        pFlac->currentFLACFrame.header = init.firstFrameHeader;
        for (;;) {
            drflac_result result = drflac__decode_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                break;
            } else {
                if (result == DRFLAC_CRC_MISMATCH) {
                    if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                        drflac__free_from_callbacks(pFlac, &allocationCallbacks);
                        return NULL;
                    }
                    continue;
                } else {
                    drflac__free_from_callbacks(pFlac, &allocationCallbacks);
                    return NULL;
                }
            }
        }

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

        DRFLAC_ASSERT(pFlac->bs.onRead == drflac__on_read_ogg);
        if (oggbs->onRead == drflac__on_read_stdio) {
            fclose((FILE*)oggbs->pUserData);
        }
    }
#endif
#endif
    drflac__free_from_callbacks(pFlac, &pFlac->allocationCallbacks);
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutpu...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
        drflac_uint32 right0 = left0 - side0;
        drflac_uint32 right1 = left1 - side1;

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

        drflac_uint32 right3 = left3 - side3;
        pOutputSamples[i*8+0] = (drflac_int32)left0;
        pOutputSamples[i*8+1] = (drflac_int32)right0;
        pOutputSamples[i*8+2] = (drflac_int32)left1;
        pOutputSamples[i*8+3] = (drflac_int32)right1;
        pOutputSamples[i*8+4] = (drflac_int32)left2;
        pOutputSamples[i*8+5] = (drflac_int32)right2;
        pOutputSamples[i*8+6] = (drflac_int32)left3;
        pOutputSamples[i*8+7] = (drflac_int32)right3;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i right = _mm_sub_epi32(left, side);
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t left;
        uint32x4_t side;
        uint32x4_t right;
        left  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        right = vsubq_u32(left, side);
        drflac__vst2q_u32((drflac_uint32*)pOutputSamples + i*8, vzipq_u32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutp...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputS...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
        drflac_uint32 left0 = right0 + side0;
        drflac_uint32 left1 = right1 + side1;

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

        drflac_uint32 left3 = right3 + side3;
        pOutputSamples[i*8+0] = (drflac_int32)left0;
        pOutputSamples[i*8+1] = (drflac_int32)right0;
        pOutputSamples[i*8+2] = (drflac_int32)left1;
        pOutputSamples[i*8+3] = (drflac_int32)right1;
        pOutputSamples[i*8+4] = (drflac_int32)left2;
        pOutputSamples[i*8+5] = (drflac_int32)right2;
        pOutputSamples[i*8+6] = (drflac_int32)left3;
        pOutputSamples[i*8+7] = (drflac_int32)right3;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    for (i = 0; i < frameCount4; ++i) {
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i left  = _mm_add_epi32(right, side);
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t side;
        uint32x4_t right;
        uint32x4_t left;
        side  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        right = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        left  = vaddq_u32(right, side);
        drflac__vst2q_u32((drflac_uint32*)pOutputSamples + i*8, vzipq_u32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutput...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
        mid = (mid << 1) | (side & 0x01);
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_int32 shift = unusedBitsPerSample;
    if (shift > 0) {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);
            temp0L = (mid0 + side0) << shift;
            temp1L = (mid1 + side1) << shift;
            temp2L = (mid2 + side2) << shift;
            temp3L = (mid3 + side3) << shift;
            temp0R = (mid0 - side0) << shift;
            temp1R = (mid1 - side1) << shift;

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

            pOutputSamples[i*8+0] = (drflac_int32)temp0L;
            pOutputSamples[i*8+1] = (drflac_int32)temp0R;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R;
        }
    } else {
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);
            temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
            temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
            temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
            temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);
            temp0R = (drflac_uint32)((drflac_int32)(mid0 - side0) >> 1);
            temp1R = (drflac_uint32)((drflac_int32)(mid1 - side1) >> 1);

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

            pOutputSamples[i*8+0] = (drflac_int32)temp0L;
            pOutputSamples[i*8+1] = (drflac_int32)temp0R;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R;
        }
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
        mid = (mid << 1) | (side & 0x01);
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_int32 shift = unusedBitsPerSample;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;
            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
            left  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
            right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int32)(mid + side) >> 1;
            pOutputSamples[i*2+1] = (drflac_int32)(mid - side) >> 1;
        }
    } else {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;
            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
            left  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
            right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
        }
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_int32 shift = unusedBitsPerSample;
    int32x4_t  wbpsShift0_4;
    int32x4_t  wbpsShift1_4;
    uint32x4_t one4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
    wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
    one4         = vdupq_n_u32(1);
    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;
            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, one4));
            left  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
            right = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);
            drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int32)(mid + side) >> 1;
            pOutputSamples[i*2+1] = (drflac_int32)(mid - side) >> 1;
        }
    } else {
        int32x4_t shift4;
        shift -= 1;
        shift4 = vdupq_n_s32(shift);
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;
            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, one4));
            left  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
            right = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));
            drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
        }
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int3...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample));
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample));
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* ...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
        pOutputSamples[i*8+0] = (drflac_int32)tempL0;
        pOutputSamples[i*8+1] = (drflac_int32)tempR0;
        pOutputSamples[i*8+2] = (drflac_int32)tempL1;
        pOutputSamples[i*8+3] = (drflac_int32)tempR1;
        pOutputSamples[i*8+4] = (drflac_int32)tempL2;
        pOutputSamples[i*8+5] = (drflac_int32)tempR2;
        pOutputSamples[i*8+6] = (drflac_int32)tempL3;
        pOutputSamples[i*8+7] = (drflac_int32)tempR3;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift4_0 = vdupq_n_s32(shift0);
    int32x4_t shift4_1 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        int32x4_t left;
        int32x4_t right;
        left  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift4_0));
        right = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift4_1));
        drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputS...
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut)
{
    drflac_uint64 framesRead;
    drflac_uint32 unusedBitsPerSample;
    if (pFlac == NULL || framesToRead == 0) {
        return 0;
    }
    if (pBufferOut == NULL) {
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
    }
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;
    framesRead = 0;
    while (framesToRead > 0) {
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;
            }
        } else {
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
            drflac_uint64 frameCountThisIteration = framesToRead;
            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
            }
            if (channelCount == 2) {
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
                switch (pFlac->currentFLACFrame.header.channelAssignment)
                {
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
                    {
                        drflac_read_pcm_frames_s32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
                    {
                        drflac_read_pcm_frames_s32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
                    {
                        drflac_read_pcm_frames_s32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
                    default:
                    {
                        drflac_read_pcm_frames_s32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                }
            } else {
                drflac_uint64 i;
                for (i = 0; i < frameCountThisIteration; ++i) {
                    unsigned int j;
                    for (j = 0; j < channelCount; ++j) {
                        pBufferOut[(i*channelCount)+j] = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
                    }
                }
            }
            framesRead                += frameCountThisIteration;
            pBufferOut                += frameCountThisIteration * channelCount;
            framesToRead              -= frameCountThisIteration;
            pFlac->currentPCMFrame    += frameCountThisIteration;
            pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
        }
    }
    return framesRead;
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutpu...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 right = left - side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
        drflac_uint32 right0 = left0 - side0;
        drflac_uint32 right1 = left1 - side1;

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

        right3 >>= 16;
        pOutputSamples[i*8+0] = (drflac_int16)left0;
        pOutputSamples[i*8+1] = (drflac_int16)right0;
        pOutputSamples[i*8+2] = (drflac_int16)left1;
        pOutputSamples[i*8+3] = (drflac_int16)right1;
        pOutputSamples[i*8+4] = (drflac_int16)left2;
        pOutputSamples[i*8+5] = (drflac_int16)right2;
        pOutputSamples[i*8+6] = (drflac_int16)left3;
        pOutputSamples[i*8+7] = (drflac_int16)right3;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i right = _mm_sub_epi32(left, side);
        left  = _mm_srai_epi32(left,  16);
        right = _mm_srai_epi32(right, 16);
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t left;
        uint32x4_t side;
        uint32x4_t right;
        left  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        right = vsubq_u32(left, side);
        left  = vshrq_n_u32(left,  16);
        right = vshrq_n_u32(right, 16);
        drflac__vst2q_u16((drflac_uint16*)pOutputSamples + i*8, vzip_u16(vmovn_u32(left), vmovn_u32(right)));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s16__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutp...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 left  = right + side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputS...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
        drflac_uint32 left0 = right0 + side0;
        drflac_uint32 left1 = right1 + side1;

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

        right3 >>= 16;
        pOutputSamples[i*8+0] = (drflac_int16)left0;
        pOutputSamples[i*8+1] = (drflac_int16)right0;
        pOutputSamples[i*8+2] = (drflac_int16)left1;
        pOutputSamples[i*8+3] = (drflac_int16)right1;
        pOutputSamples[i*8+4] = (drflac_int16)left2;
        pOutputSamples[i*8+5] = (drflac_int16)right2;
        pOutputSamples[i*8+6] = (drflac_int16)left3;
        pOutputSamples[i*8+7] = (drflac_int16)right3;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    for (i = 0; i < frameCount4; ++i) {
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i left  = _mm_add_epi32(right, side);
        left  = _mm_srai_epi32(left,  16);
        right = _mm_srai_epi32(right, 16);
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t side;
        uint32x4_t right;
        uint32x4_t left;
        side  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        right = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        left  = vaddq_u32(right, side);
        left  = vshrq_n_u32(left,  16);
        right = vshrq_n_u32(right, 16);
        drflac__vst2q_u16((drflac_uint16*)pOutputSamples + i*8, vzip_u16(vmovn_u32(left), vmovn_u32(right)));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s16__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutput...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        drflac_uint32 mid  = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
        mid = (mid << 1) | (side & 0x01);
        pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;
    if (shift > 0) {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);
            temp0L = (mid0 + side0) << shift;
            temp1L = (mid1 + side1) << shift;
            temp2L = (mid2 + side2) << shift;
            temp3L = (mid3 + side3) << shift;
            temp0R = (mid0 - side0) << shift;
            temp1R = (mid1 - side1) << shift;

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

            pOutputSamples[i*8+0] = (drflac_int16)temp0L;
            pOutputSamples[i*8+1] = (drflac_int16)temp0R;
            pOutputSamples[i*8+2] = (drflac_int16)temp1L;
            pOutputSamples[i*8+3] = (drflac_int16)temp1R;
            pOutputSamples[i*8+4] = (drflac_int16)temp2L;
            pOutputSamples[i*8+5] = (drflac_int16)temp2R;
            pOutputSamples[i*8+6] = (drflac_int16)temp3L;
            pOutputSamples[i*8+7] = (drflac_int16)temp3R;
        }
    } else {
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);
            temp0L = ((drflac_int32)(mid0 + side0) >> 1);
            temp1L = ((drflac_int32)(mid1 + side1) >> 1);
            temp2L = ((drflac_int32)(mid2 + side2) >> 1);
            temp3L = ((drflac_int32)(mid3 + side3) >> 1);
            temp0R = ((drflac_int32)(mid0 - side0) >> 1);
            temp1R = ((drflac_int32)(mid1 - side1) >> 1);

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

            pOutputSamples[i*8+0] = (drflac_int16)temp0L;
            pOutputSamples[i*8+1] = (drflac_int16)temp0R;
            pOutputSamples[i*8+2] = (drflac_int16)temp1L;
            pOutputSamples[i*8+3] = (drflac_int16)temp1R;
            pOutputSamples[i*8+4] = (drflac_int16)temp2L;
            pOutputSamples[i*8+5] = (drflac_int16)temp2R;
            pOutputSamples[i*8+6] = (drflac_int16)temp3L;
            pOutputSamples[i*8+7] = (drflac_int16)temp3R;
        }
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
        mid = (mid << 1) | (side & 0x01);
        pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;
            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
            left  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
            right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
            left  = _mm_srai_epi32(left,  16);
            right = _mm_srai_epi32(right, 16);
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
        }
    } else {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;
            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
            left  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
            right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
            left  = _mm_srai_epi32(left,  16);
            right = _mm_srai_epi32(right, 16);
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
        }
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;
    int32x4_t wbpsShift0_4;
    int32x4_t wbpsShift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
    wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;
            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
            left  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
            right = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);
            left  = vshrq_n_s32(left,  16);
            right = vshrq_n_s32(right, 16);
            drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
        }
    } else {
        int32x4_t shift4;
        shift -= 1;
        shift4 = vdupq_n_s32(shift);
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;
            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
            left  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
            right = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));
            left  = vshrq_n_s32(left,  16);
            right = vshrq_n_s32(right, 16);
            drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
        }
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s16__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int1...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) >> 16);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* ...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
        tempL0 >>= 16;
        tempL1 >>= 16;

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

        tempR3 >>= 16;
        pOutputSamples[i*8+0] = (drflac_int16)tempL0;
        pOutputSamples[i*8+1] = (drflac_int16)tempR0;
        pOutputSamples[i*8+2] = (drflac_int16)tempL1;
        pOutputSamples[i*8+3] = (drflac_int16)tempR1;
        pOutputSamples[i*8+4] = (drflac_int16)tempL2;
        pOutputSamples[i*8+5] = (drflac_int16)tempR2;
        pOutputSamples[i*8+6] = (drflac_int16)tempL3;
        pOutputSamples[i*8+7] = (drflac_int16)tempR3;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        left  = _mm_srai_epi32(left,  16);
        right = _mm_srai_epi32(right, 16);
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4 = vdupq_n_s32(shift0);
    int32x4_t shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        int32x4_t left;
        int32x4_t right;
        left  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4));
        right = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4));
        left  = vshrq_n_s32(left,  16);
        right = vshrq_n_s32(right, 16);
        drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputS...
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s16__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut)
{
    drflac_uint64 framesRead;
    drflac_uint32 unusedBitsPerSample;
    if (pFlac == NULL || framesToRead == 0) {
        return 0;
    }
    if (pBufferOut == NULL) {
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
    }
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;
    framesRead = 0;
    while (framesToRead > 0) {
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;
            }
        } else {
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
            drflac_uint64 frameCountThisIteration = framesToRead;
            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
            }
            if (channelCount == 2) {
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
                switch (pFlac->currentFLACFrame.header.channelAssignment)
                {
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
                    {
                        drflac_read_pcm_frames_s16__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
                    {
                        drflac_read_pcm_frames_s16__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
                    {
                        drflac_read_pcm_frames_s16__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
                    default:
                    {
                        drflac_read_pcm_frames_s16__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                }
            } else {
                drflac_uint64 i;
                for (i = 0; i < frameCountThisIteration; ++i) {
                    unsigned int j;
                    for (j = 0; j < channelCount; ++j) {
                        drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
                        pBufferOut[(i*channelCount)+j] = (drflac_int16)(sampleS32 >> 16);
                    }
                }
            }
            framesRead                += frameCountThisIteration;
            pBufferOut                += frameCountThisIteration * channelCount;
            framesToRead              -= frameCountThisIteration;
            pFlac->currentPCMFrame    += frameCountThisIteration;
            pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
        }
    }
    return framesRead;
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSample...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (float)((drflac_int32)left  / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    float factor = 1 / 2147483648.0;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
        drflac_uint32 right0 = left0 - side0;
        drflac_uint32 right1 = left1 - side1;

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

        drflac_uint32 right3 = left3 - side3;
        pOutputSamples[i*8+0] = (drflac_int32)left0  * factor;
        pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
        pOutputSamples[i*8+2] = (drflac_int32)left1  * factor;
        pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
        pOutputSamples[i*8+4] = (drflac_int32)left2  * factor;
        pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
        pOutputSamples[i*8+6] = (drflac_int32)left3  * factor;
        pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left  * factor;
        pOutputSamples[i*2+1] = (drflac_int32)right * factor;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    __m128 factor;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    factor = _mm_set1_ps(1.0f / 8388608.0f);
    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i right = _mm_sub_epi32(left, side);
        __m128 leftf  = _mm_mul_ps(_mm_cvtepi32_ps(left),  factor);
        __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);
        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    float32x4_t factor4;
    int32x4_t shift0_4;
    int32x4_t shift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    factor4  = vdupq_n_f32(1.0f / 8388608.0f);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t left;
        uint32x4_t side;
        uint32x4_t right;
        float32x4_t leftf;
        float32x4_t rightf;
        left   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        side   = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        right  = vsubq_u32(left, side);
        leftf  = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(left)),  factor4);
        rightf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(right)), factor4);
        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_f32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSampl...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (float)((drflac_int32)left  / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    float factor = 1 / 2147483648.0;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
        drflac_uint32 left0 = right0 + side0;
        drflac_uint32 left1 = right1 + side1;

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

        drflac_uint32 left3 = right3 + side3;
        pOutputSamples[i*8+0] = (drflac_int32)left0  * factor;
        pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
        pOutputSamples[i*8+2] = (drflac_int32)left1  * factor;
        pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
        pOutputSamples[i*8+4] = (drflac_int32)left2  * factor;
        pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
        pOutputSamples[i*8+6] = (drflac_int32)left3  * factor;
        pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left  * factor;
        pOutputSamples[i*2+1] = (drflac_int32)right * factor;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    __m128 factor;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    factor = _mm_set1_ps(1.0f / 8388608.0f);
    for (i = 0; i < frameCount4; ++i) {
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i left  = _mm_add_epi32(right, side);
        __m128 leftf  = _mm_mul_ps(_mm_cvtepi32_ps(left),  factor);
        __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);
        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    float32x4_t factor4;
    int32x4_t shift0_4;
    int32x4_t shift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    factor4  = vdupq_n_f32(1.0f / 8388608.0f);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t side;
        uint32x4_t right;
        uint32x4_t left;
        float32x4_t leftf;
        float32x4_t rightf;
        side   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        right  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        left   = vaddq_u32(right, side);
        leftf  = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(left)),  factor4);
        rightf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(right)), factor4);
        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_f32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        drflac_uint32 mid  = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
        mid = (mid << 1) | (side & 0x01);
        pOutputSamples[i*2+0] = (float)((((drflac_int32)(mid + side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((((drflac_int32)(mid - side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;
    float factor = 1 / 2147483648.0;
    if (shift > 0) {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);
            temp0L = (mid0 + side0) << shift;
            temp1L = (mid1 + side1) << shift;
            temp2L = (mid2 + side2) << shift;
            temp3L = (mid3 + side3) << shift;
            temp0R = (mid0 - side0) << shift;
            temp1R = (mid1 - side1) << shift;

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

            pOutputSamples[i*8+0] = (drflac_int32)temp0L * factor;
            pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
        }
    } else {
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);
            temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
            temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
            temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
            temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);
            temp0R = (drflac_uint32)((drflac_int32)(mid0 - side0) >> 1);
            temp1R = (drflac_uint32)((drflac_int32)(mid1 - side1) >> 1);

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

            pOutputSamples[i*8+0] = (drflac_int32)temp0L * factor;
            pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
        }
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
        mid = (mid << 1) | (side & 0x01);
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) * factor;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample - 8;
    float factor;
    __m128 factor128;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    factor = 1.0f / 8388608.0f;
    factor128 = _mm_set1_ps(factor);
    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i tempL;
            __m128i tempR;
            __m128  leftf;
            __m128  rightf;
            mid    = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
            mid    = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
            tempL  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
            tempR  = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
            leftf  = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
            rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);
            _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
            _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
            pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
        }
    } else {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i tempL;
            __m128i tempR;
            __m128 leftf;
            __m128 rightf;
            mid    = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
            mid    = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
            tempL  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
            tempR  = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
            leftf  = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
            rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);
            _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
            _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
        }
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample - 8;
    float factor;
    float32x4_t factor4;
    int32x4_t shift4;
    int32x4_t wbps0_4;
    int32x4_t wbps1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    factor  = 1.0f / 8388608.0f;
    factor4 = vdupq_n_f32(factor);
    wbps0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
    wbps1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            int32x4_t lefti;
            int32x4_t righti;
            float32x4_t leftf;
            float32x4_t rightf;
            uint32x4_t mid  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbps0_4);
            uint32x4_t side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbps1_4);
            mid    = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
            lefti  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
            righti = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);
            leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
            rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
            drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
            pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
        }
    } else {
        shift -= 1;
        shift4 = vdupq_n_s32(shift);
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t lefti;
            int32x4_t righti;
            float32x4_t leftf;
            float32x4_t rightf;
            mid    = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbps0_4);
            side   = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbps1_4);
            mid    = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
            lefti  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
            righti = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));
            leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
            rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
            drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
        }
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_f32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOut...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (float)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) / 2147483648.0);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutput...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    float factor = 1 / 2147483648.0;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
        pOutputSamples[i*8+0] = (drflac_int32)tempL0 * factor;
        pOutputSamples[i*8+1] = (drflac_int32)tempR0 * factor;
        pOutputSamples[i*8+2] = (drflac_int32)tempL1 * factor;
        pOutputSamples[i*8+3] = (drflac_int32)tempR1 * factor;
        pOutputSamples[i*8+4] = (drflac_int32)tempL2 * factor;
        pOutputSamples[i*8+5] = (drflac_int32)tempR2 * factor;
        pOutputSamples[i*8+6] = (drflac_int32)tempL3 * factor;
        pOutputSamples[i*8+7] = (drflac_int32)tempR3 * factor;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    float factor = 1.0f / 8388608.0f;
    __m128 factor128 = _mm_set1_ps(factor);
    for (i = 0; i < frameCount4; ++i) {
        __m128i lefti;
        __m128i righti;
        __m128 leftf;
        __m128 rightf;
        lefti  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        righti = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        leftf  = _mm_mul_ps(_mm_cvtepi32_ps(lefti),  factor128);
        rightf = _mm_mul_ps(_mm_cvtepi32_ps(righti), factor128);
        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    float factor = 1.0f / 8388608.0f;
    float32x4_t factor4 = vdupq_n_f32(factor);
    int32x4_t shift0_4  = vdupq_n_s32(shift0);
    int32x4_t shift1_4  = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        int32x4_t lefti;
        int32x4_t righti;
        float32x4_t leftf;
        float32x4_t rightf;
        lefti  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4));
        righti = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4));
        leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
        rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_f32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut)
{
    drflac_uint64 framesRead;
    drflac_uint32 unusedBitsPerSample;
    if (pFlac == NULL || framesToRead == 0) {
        return 0;
    }
    if (pBufferOut == NULL) {
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
    }
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;
    framesRead = 0;
    while (framesToRead > 0) {
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;
            }
        } else {
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
            drflac_uint64 frameCountThisIteration = framesToRead;
            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
            }
            if (channelCount == 2) {
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
                switch (pFlac->currentFLACFrame.header.channelAssignment)
                {
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
                    {
                        drflac_read_pcm_frames_f32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
                    {
                        drflac_read_pcm_frames_f32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
                    {
                        drflac_read_pcm_frames_f32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
                    default:
                    {
                        drflac_read_pcm_frames_f32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                }
            } else {
                drflac_uint64 i;
                for (i = 0; i < frameCountThisIteration; ++i) {
                    unsigned int j;
                    for (j = 0; j < channelCount; ++j) {
                        drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
                        pBufferOut[(i*channelCount)+j] = (float)(sampleS32 / 2147483648.0);
                    }
                }
            }
            framesRead                += frameCountThisIteration;
            pBufferOut                += frameCountThisIteration * channelCount;
            framesToRead              -= frameCountThisIteration;
            pFlac->currentPCMFrame    += frameCountThisIteration;
            pFlac->currentFLACFrame.pcmFramesRemaining -= (unsigned int)frameCountThisIteration;
        }
    }
    return framesRead;
}
DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    if (pFlac == NULL) {
        return DRFLAC_FALSE;
    }
    if (pFlac->currentPCMFrame == pcmFrameIndex) {
        return DRFLAC_TRUE;
    }
    if (pFlac->firstFLACFramePosInBytes == 0) {
        return DRFLAC_FALSE;
    }
    if (pcmFrameIndex == 0) {
        pFlac->currentPCMFrame = 0;
        return drflac__seek_to_first_frame(pFlac);
    } else {
        drflac_bool32 wasSuccessful = DRFLAC_FALSE;
        if (pcmFrameIndex > pFlac->totalPCMFrameCount) {
            pcmFrameIndex = pFlac->totalPCMFrameCount;
        }
        if (pcmFrameIndex > pFlac->currentPCMFrame) {
            drflac_uint32 offset = (drflac_uint32)(pcmFrameIndex - pFlac->currentPCMFrame);
            if (pFlac->currentFLACFrame.pcmFramesRemaining >  offset) {
                pFlac->currentFLACFrame.pcmFramesRemaining -= offset;
                pFlac->currentPCMFrame = pcmFrameIndex;

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

            drflac_uint32 currentFLACFramePCMFramesConsumed = currentFLACFramePCMFrameCount - pFlac->currentFLACFrame.pcmFramesRemaining;
            if (currentFLACFramePCMFramesConsumed > offsetAbs) {
                pFlac->currentFLACFrame.pcmFramesRemaining += offsetAbs;
                pFlac->currentPCMFrame = pcmFrameIndex;
                return DRFLAC_TRUE;
            }
        }
#ifndef DR_FLAC_NO_OGG
        if (pFlac->container == drflac_container_ogg)
        {
            wasSuccessful = drflac_ogg__seek_to_pcm_frame(pFlac, pcmFrameIndex);
        }
        else
#endif
        {
            if (!pFlac->_noSeekTableSeek) {
                wasSuccessful = drflac__seek_to_pcm_frame__seek_table(pFlac, pcmFrameIndex);
            }
#if !defined(DR_FLAC_NO_CRC)
            if (!wasSuccessful && !pFlac->_noBinarySearchSeek && pFlac->totalPCMFrameCount > 0) {
                wasSuccessful = drflac__seek_to_pcm_frame__binary_search(pFlac, pcmFrameIndex);
            }
#endif
            if (!wasSuccessful && !pFlac->_noBruteForceSeek) {
                wasSuccessful = drflac__seek_to_pcm_frame__brute_force(pFlac, pcmFrameIndex);
            }
        }
        pFlac->currentPCMFrame = pcmFrameIndex;
        return wasSuccessful;
    }
}
#if defined(SIZE_MAX)
    #define DRFLAC_SIZE_MAX  SIZE_MAX
#else
    #if defined(DRFLAC_64BIT)

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

    if (totalPCMFrameCount == 0) {                                                                                                                                  \
        type buffer[4096];                                                                                                                                          \
        drflac_uint64 pcmFramesRead;                                                                                                                                \
        size_t sampleDataBufferSize = sizeof(buffer);                                                                                                               \
                                                                                                                                                                    \
        pSampleData = (type*)drflac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks);                                                      \
        if (pSampleData == NULL) {                                                                                                                                  \
            goto on_error;                                                                                                                                          \
        }                                                                                                                                                           \
                                                                                                                                                                    \
        while ((pcmFramesRead = (drflac_uint64)drflac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) {          \
            if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) {                                                   \
                type* pNewSampleData;                                                                                                                               \
                size_t newSampleDataBufferSize;                                                                                                                     \
                                                                                                                                                                    \
                newSampleDataBufferSize = sampleDataBufferSize * 2;                                                                                                 \
                pNewSampleData = (type*)drflac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks);    \
                if (pNewSampleData == NULL) {                                                                                                                       \
                    drflac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks);                                                                          \
                    goto on_error;                                                                                                                                  \
                }                                                                                                                                                   \

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

        drflac_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type);                                                                                   \
        if (dataSize > DRFLAC_SIZE_MAX) {                                                                                                                           \
            goto on_error;                                                                                                        \
        }                                                                                                                                                           \
                                                                                                                                                                    \
        pSampleData = (type*)drflac__malloc_from_callbacks((size_t)dataSize, &pFlac->allocationCallbacks);               \
        if (pSampleData == NULL) {                                                                                                                                  \
            goto on_error;                                                                                                                                          \
        }                                                                                                                                                           \
                                                                                                                                                                    \
        totalPCMFrameCount = drflac_read_pcm_frames_##extension(pFlac, pFlac->totalPCMFrameCount, pSampleData);                                                     \
    }                                                                                                                                                               \
                                                                                                                                                                    \
    if (sampleRateOut) *sampleRateOut = pFlac->sampleRate;                                                                                                          \
    if (channelsOut) *channelsOut = pFlac->channels;                                                                                                                \
    if (totalPCMFrameCountOut) *totalPCMFrameCountOut = totalPCMFrameCount;                                                                                         \
                                                                                                                                                                    \
    drflac_close(pFlac);                                                                                                                                            \
    return pSampleData;                                                                                                                                             \
                                                                                                                                                                    \
on_error:                                                                                                                                                           \
    drflac_close(pFlac);                                                                                                                                            \
    return NULL;                                                                                                                                                    \
}
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s32, drflac_int32)
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s16, drflac_int16)
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(f32, float)
DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_call...
{
    drflac* pFlac;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalPCMFrameCountOut) {
        *totalPCMFrameCountOut = 0;
    }
    pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_s32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}
DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_call...
{
    drflac* pFlac;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalPCMFrameCountOut) {
        *totalPCMFrameCountOut = 0;
    }
    pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_s16(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}
DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* ...
{
    drflac* pFlac;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalPCMFrameCountOut) {
        *totalPCMFrameCountOut = 0;
    }
    pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_f32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}
#ifndef DR_FLAC_NO_STDIO
DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;
    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {
        *totalPCMFrameCount = 0;
    }
    pFlac = drflac_open_file(filename, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
}
DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;
    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {
        *totalPCMFrameCount = 0;
    }
    pFlac = drflac_open_file(filename, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
}
DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;
    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {
        *totalPCMFrameCount = 0;
    }
    pFlac = drflac_open_file(filename, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_f32(pFlac, channels, sampleRate, totalPCMFrameCount);
}
#endif
DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;
    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {
        *totalPCMFrameCount = 0;
    }
    pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
}
DRFLAC_API drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;
    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {
        *totalPCMFrameCount = 0;
    }
    pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
}
DRFLAC_API float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;
    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {
        *totalPCMFrameCount = 0;

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

        { { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,16,24,28,32,40,48,56,64,72,80,88,96,112,128 } },
        { { 0,16,20,24,28,32,40,48,56,64,80,96,112,128,160 }, { 0,16,24,28,32,40,48,56,64,80,96,112,128,160,192 }, { 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224 } },
    };
    return 2*halfrate[!!DRMP3_HDR_TEST_MPEG1(h)][DRMP3_HDR_GET_LAYER(h) - 1][DRMP3_HDR_GET_BITRATE(h)];
}
static unsigned drmp3_hdr_sample_rate_hz(const drmp3_uint8 *h)
{
    static const unsigned g_hz[3] = { 44100, 48000, 32000 };
    return g_hz[DRMP3_HDR_GET_SAMPLE_RATE(h)] >> (int)!DRMP3_HDR_TEST_MPEG1(h) >> (int)!DRMP3_HDR_TEST_NOT_MPEG25(h);
}
static unsigned drmp3_hdr_frame_samples(const drmp3_uint8 *h)
{
    return DRMP3_HDR_IS_LAYER_1(h) ? 384 : (1152 >> (int)DRMP3_HDR_IS_FRAME_576(h));
}
static int drmp3_hdr_frame_bytes(const drmp3_uint8 *h, int free_format_size)
{
    int frame_bytes = drmp3_hdr_frame_samples(h)*drmp3_hdr_bitrate_kbps(h)*125/drmp3_hdr_sample_rate_hz(h);
    if (DRMP3_HDR_IS_LAYER_1(h))
    {
        frame_bytes &= ~3;
    }
    return frame_bytes ? frame_bytes : free_format_size;
}
static int drmp3_hdr_padding(const drmp3_uint8 *h)
{
    return DRMP3_HDR_TEST_PADDING(h) ? (DRMP3_HDR_IS_LAYER_1(h) ? 4 : 1) : 0;
}
#ifndef DR_MP3_ONLY_MP3
static const drmp3_L12_subband_alloc *drmp3_L12_subband_alloc_table(const drmp3_uint8 *hdr, drmp3_L12_scale_info *sci)
{
    const drmp3_L12_subband_alloc *alloc;
    int mode = DRMP3_HDR_GET_STEREO_MODE(hdr);

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

        remains = DRMP3_MAX_BITRESERVOIR_BYTES;
    }
    if (remains > 0)
    {
        memmove(h->reserv_buf, s->maindata + pos, remains);
    }
    h->reserv = remains;
}
static int drmp3_L3_restore_reservoir(drmp3dec *h, drmp3_bs *bs, drmp3dec_scratch *s, int main_data_begin)
{
    int frame_bytes = (bs->limit - bs->pos)/8;
    int bytes_have = DRMP3_MIN(h->reserv, main_data_begin);
    memcpy(s->maindata, h->reserv_buf + DRMP3_MAX(0, h->reserv - main_data_begin), DRMP3_MIN(h->reserv, main_data_begin));
    memcpy(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes);
    drmp3_bs_init(&s->bs, s->maindata, bytes_have + frame_bytes);
    return h->reserv >= main_data_begin;
}
static void drmp3_L3_decode(drmp3dec *h, drmp3dec_scratch *s, drmp3_L3_gr_info *gr_info, int nch)
{
    int ch;
    for (ch = 0; ch < nch; ch++)
    {
        int layer3gr_limit = s->bs.pos + gr_info[ch].part_23_length;
        drmp3_L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch);
        drmp3_L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit);

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

        for (i = 0; i < 15*64; i += 2)
        {
            qmf_state[i] = lins[nbands*64 + i];
        }
    } else
#endif
    {
        memcpy(qmf_state, lins + nbands*64, sizeof(float)*15*64);
    }
}
static int drmp3d_match_frame(const drmp3_uint8 *hdr, int mp3_bytes, int frame_bytes)
{
    int i, nmatch;
    for (i = 0, nmatch = 0; nmatch < DRMP3_MAX_FRAME_SYNC_MATCHES; nmatch++)
    {
        i += drmp3_hdr_frame_bytes(hdr + i, frame_bytes) + drmp3_hdr_padding(hdr + i);
        if (i + DRMP3_HDR_SIZE > mp3_bytes)
            return nmatch > 0;
        if (!drmp3_hdr_compare(hdr, hdr + i))
            return 0;
    }
    return 1;
}
static int drmp3d_find_frame(const drmp3_uint8 *mp3, int mp3_bytes, int *free_format_bytes, int *ptr_frame_bytes)
{
    int i, k;
    for (i = 0; i < mp3_bytes - DRMP3_HDR_SIZE; i++, mp3++)
    {
        if (drmp3_hdr_valid(mp3))
        {
            int frame_bytes = drmp3_hdr_frame_bytes(mp3, *free_format_bytes);
            int frame_and_padding = frame_bytes + drmp3_hdr_padding(mp3);
            for (k = DRMP3_HDR_SIZE; !frame_bytes && k < DRMP3_MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - DRMP3_HDR_SIZE; k++)
            {
                if (drmp3_hdr_compare(mp3, mp3 + k))
                {
                    int fb = k - drmp3_hdr_padding(mp3);
                    int nextfb = fb + drmp3_hdr_padding(mp3 + k);
                    if (i + k + nextfb + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + k + nextfb))
                        continue;
                    frame_and_padding = k;
                    frame_bytes = fb;
                    *free_format_bytes = fb;
                }
            }
            if ((frame_bytes && i + frame_and_padding <= mp3_bytes &&
                drmp3d_match_frame(mp3, mp3_bytes - i, frame_bytes)) ||
                (!i && frame_and_padding == mp3_bytes))
            {
                *ptr_frame_bytes = frame_and_padding;
                return i;
            }
            *free_format_bytes = 0;
        }
    }
    *ptr_frame_bytes = 0;
    return mp3_bytes;
}
DRMP3_API void drmp3dec_init(drmp3dec *dec)
{
    dec->header[0] = 0;
}
DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info)
{
    int i = 0, igr, frame_size = 0, success = 1;
    const drmp3_uint8 *hdr;
    drmp3_bs bs_frame[1];
    drmp3dec_scratch scratch;
    if (mp3_bytes > 4 && dec->header[0] == 0xff && drmp3_hdr_compare(dec->header, mp3))
    {
        frame_size = drmp3_hdr_frame_bytes(mp3, dec->free_format_bytes) + drmp3_hdr_padding(mp3);
        if (frame_size != mp3_bytes && (frame_size + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + frame_size)))
        {
            frame_size = 0;
        }
    }
    if (!frame_size)
    {
        memset(dec, 0, sizeof(drmp3dec));
        i = drmp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size);
        if (!frame_size || i + frame_size > mp3_bytes)
        {
            info->frame_bytes = i;
            return 0;
        }
    }
    hdr = mp3 + i;
    memcpy(dec->header, hdr, DRMP3_HDR_SIZE);
    info->frame_bytes = i + frame_size;
    info->channels = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2;
    info->hz = drmp3_hdr_sample_rate_hz(hdr);
    info->layer = 4 - DRMP3_HDR_GET_LAYER(hdr);
    info->bitrate_kbps = drmp3_hdr_bitrate_kbps(hdr);
    drmp3_bs_init(bs_frame, hdr + DRMP3_HDR_SIZE, frame_size - DRMP3_HDR_SIZE);
    if (DRMP3_HDR_IS_CRC(hdr))
    {
        drmp3_bs_get_bits(bs_frame, 16);
    }
    if (info->layer == 3)
    {
        int main_data_begin = drmp3_L3_read_side_info(bs_frame, scratch.gr_info, hdr);
        if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit)
        {
            drmp3dec_init(dec);
            return 0;
        }
        success = drmp3_L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin);
        if (success && pcm != NULL)
        {
            for (igr = 0; igr < (DRMP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*576*info->channels))
            {
                memset(scratch.grbuf[0], 0, 576*2*sizeof(float));
                drmp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels);
                drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]);
            }
        }
        drmp3_L3_save_reservoir(dec, &scratch);
    } else
    {
#ifdef DR_MP3_ONLY_MP3
        return 0;
#else
        drmp3_L12_scale_info sci[1];
        if (pcm == NULL) {
            return drmp3_hdr_frame_samples(hdr);
        }
        drmp3_L12_read_scale_info(hdr, bs_frame, sci);
        memset(scratch.grbuf[0], 0, 576*2*sizeof(float));
        for (i = 0, igr = 0; igr < 3; igr++)
        {
            if (12 == (i += drmp3_L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1)))
            {
                i = 0;
                drmp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]);
                drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]);
                memset(scratch.grbuf[0], 0, 576*2*sizeof(float));
                pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*384*info->channels);
            }
            if (bs_frame->pos > bs_frame->limit)
            {
                drmp3dec_init(dec);
                return 0;
            }
        }
#endif
    }
    return success*drmp3_hdr_frame_samples(dec->header);
}
DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples)
{
    size_t i = 0;
#if DRMP3_HAVE_SIMD
    size_t aligned_count = num_samples & ~7;
    for(; i < aligned_count; i+=8)
    {
        drmp3_f4 scale = DRMP3_VSET(32768.0f);
        drmp3_f4 a = DRMP3_VMUL(DRMP3_VLD(&in[i  ]), scale);

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

            offset = 0;
        } else {
            if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_current)) {
                return DRMP3_FALSE;
            }
            offset -= 0x7FFFFFFF;
        }
    }
    return DRMP3_TRUE;
}
static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
{
    drmp3_uint32 pcmFramesRead = 0;
    DRMP3_ASSERT(pMP3 != NULL);
    DRMP3_ASSERT(pMP3->onRead != NULL);
    if (pMP3->atEnd) {
        return 0;
    }
    for (;;) {
        drmp3dec_frame_info info;
        if (pMP3->dataSize < DRMP3_MIN_DATA_CHUNK_SIZE) {
            size_t bytesRead;
            if (pMP3->pData != NULL) {
                memmove(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
            }
            pMP3->dataConsumed = 0;
            if (pMP3->dataCapacity < DRMP3_DATA_CHUNK_SIZE) {
                drmp3_uint8* pNewData;
                size_t newDataCap;
                newDataCap = DRMP3_DATA_CHUNK_SIZE;

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

                    pMP3->atEnd = DRMP3_TRUE;
                    return 0;
                }
            }
            pMP3->dataSize += bytesRead;
        }
        if (pMP3->dataSize > INT_MAX) {
            pMP3->atEnd = DRMP3_TRUE;
            return 0;
        }
        pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info);
        if (info.frame_bytes > 0) {
            pMP3->dataConsumed += (size_t)info.frame_bytes;
            pMP3->dataSize     -= (size_t)info.frame_bytes;
        }
        if (pcmFramesRead > 0) {
            pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header);
            pMP3->pcmFramesConsumedInMP3Frame = 0;
            pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
            pMP3->mp3FrameChannels = info.channels;
            pMP3->mp3FrameSampleRate = info.hz;
            break;
        } else if (info.frame_bytes == 0) {
            size_t bytesRead;
            memmove(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
            pMP3->dataConsumed = 0;
            if (pMP3->dataCapacity == pMP3->dataSize) {
                drmp3_uint8* pNewData;
                size_t newDataCap;
                newDataCap = pMP3->dataCapacity + DRMP3_DATA_CHUNK_SIZE;
                pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
                if (pNewData == NULL) {
                    return 0;

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

            bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
            if (bytesRead == 0) {
                pMP3->atEnd = DRMP3_TRUE;
                return 0;
            }
            pMP3->dataSize += bytesRead;
        }
    };
    return pcmFramesRead;
}
static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
{
    drmp3_uint32 pcmFramesRead = 0;
    drmp3dec_frame_info info;
    DRMP3_ASSERT(pMP3 != NULL);
    DRMP3_ASSERT(pMP3->memory.pData != NULL);
    if (pMP3->atEnd) {
        return 0;
    }
    pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->memory.pData + pMP3->memory.currentReadPos, (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos), pPCMFrames, &info);
    if (pcmFramesRead > 0) {
        pMP3->pcmFramesConsumedInMP3Frame  = 0;
        pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
        pMP3->mp3FrameChannels             = info.channels;
        pMP3->mp3FrameSampleRate           = info.hz;
    }
    pMP3->memory.currentReadPos += (size_t)info.frame_bytes;
    return pcmFramesRead;
}
static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
{
    if (pMP3->memory.pData != NULL && pMP3->memory.dataSize > 0) {
        return drmp3_decode_next_frame_ex__memory(pMP3, pPCMFrames);
    } else {
        return drmp3_decode_next_frame_ex__callbacks(pMP3, pPCMFrames);
    }
}
static drmp3_uint32 drmp3_decode_next_frame(drmp3* pMP3)
{
    DRMP3_ASSERT(pMP3 != NULL);
    return drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames);
}
#if 0
static drmp3_uint32 drmp3_seek_next_frame(drmp3* pMP3)
{
    drmp3_uint32 pcmFrameCount;
    DRMP3_ASSERT(pMP3 != NULL);
    pcmFrameCount = drmp3_decode_next_frame_ex(pMP3, NULL);
    if (pcmFrameCount == 0) {
        return 0;
    }
    pMP3->currentPCMFrame             += pcmFrameCount;
    pMP3->pcmFramesConsumedInMP3Frame  = pcmFrameCount;
    pMP3->pcmFramesRemainingInMP3Frame = 0;
    return pcmFrameCount;
}
#endif
static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)

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

    DRMP3_ASSERT(pMP3 != NULL);
    DRMP3_ASSERT(onRead != NULL);
    drmp3dec_init(&pMP3->decoder);
    pMP3->onRead = onRead;
    pMP3->onSeek = onSeek;
    pMP3->pUserData = pUserData;
    pMP3->allocationCallbacks = drmp3_copy_allocation_callbacks_or_defaults(pAllocationCallbacks);
    if (pMP3->allocationCallbacks.onFree == NULL || (pMP3->allocationCallbacks.onMalloc == NULL && pMP3->allocationCallbacks.onRealloc == NULL)) {
        return DRMP3_FALSE;
    }
    if (!drmp3_decode_next_frame(pMP3)) {
        drmp3_uninit(pMP3);
        return DRMP3_FALSE;
    }
    pMP3->channels   = pMP3->mp3FrameChannels;
    pMP3->sampleRate = pMP3->mp3FrameSampleRate;
    return DRMP3_TRUE;
}
DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    if (pMP3 == NULL || onRead == NULL) {

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

static void drmp3_s16_to_f32(float* dst, const drmp3_int16* src, drmp3_uint64 sampleCount)
{
    drmp3_uint64 i;
    for (i = 0; i < sampleCount; i += 1) {
        float x = (float)src[i];
        x = x * 0.000030517578125f;
        dst[i] = x;
    }
}
#endif
static drmp3_uint64 drmp3_read_pcm_frames_raw(drmp3* pMP3, drmp3_uint64 framesToRead, void* pBufferOut)
{
    drmp3_uint64 totalFramesRead = 0;
    DRMP3_ASSERT(pMP3 != NULL);
    DRMP3_ASSERT(pMP3->onRead != NULL);
    while (framesToRead > 0) {
        drmp3_uint32 framesToConsume = (drmp3_uint32)DRMP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, framesToRead);
        if (pBufferOut != NULL) {
        #if defined(DR_MP3_FLOAT_OUTPUT)
            float* pFramesOutF32 = (float*)DRMP3_OFFSET_PTR(pBufferOut,          sizeof(float) * totalFramesRead                   * pMP3->channels);
            float* pFramesInF32  = (float*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
            DRMP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels);
        #else
            drmp3_int16* pFramesOutS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut,          sizeof(drmp3_int16) * totalFramesRead                   * pMP3->channels);
            drmp3_int16* pFramesInS16  = (drmp3_int16*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(drmp3_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
            DRMP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(drmp3_int16) * framesToConsume * pMP3->channels);
        #endif
        }
        pMP3->currentPCMFrame              += framesToConsume;
        pMP3->pcmFramesConsumedInMP3Frame  += framesToConsume;
        pMP3->pcmFramesRemainingInMP3Frame -= framesToConsume;
        totalFramesRead                    += framesToConsume;
        framesToRead                       -= framesToConsume;
        if (framesToRead == 0) {
            break;
        }
        DRMP3_ASSERT(pMP3->pcmFramesRemainingInMP3Frame == 0);
        if (drmp3_decode_next_frame(pMP3) == 0) {
            break;
        }
    }
    return totalFramesRead;
}
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut)
{
    if (pMP3 == NULL || pMP3->onRead == NULL) {
        return 0;
    }
#if defined(DR_MP3_FLOAT_OUTPUT)
    return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
#else
    {
        drmp3_int16 pTempS16[8192];
        drmp3_uint64 totalPCMFramesRead = 0;
        while (totalPCMFramesRead < framesToRead) {
            drmp3_uint64 framesJustRead;
            drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
            drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempS16) / pMP3->channels;
            if (framesToReadNow > framesRemaining) {
                framesToReadNow = framesRemaining;
            }
            framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempS16);
            if (framesJustRead == 0) {
                break;
            }
            drmp3_s16_to_f32((float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalPCMFramesRead * pMP3->channels), pTempS16, framesJustRead * pMP3->channels);
            totalPCMFramesRead += framesJustRead;
        }
        return totalPCMFramesRead;
    }
#endif
}
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut)
{
    if (pMP3 == NULL || pMP3->onRead == NULL) {
        return 0;
    }
#if !defined(DR_MP3_FLOAT_OUTPUT)
    return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
#else
    {
        float pTempF32[4096];
        drmp3_uint64 totalPCMFramesRead = 0;
        while (totalPCMFramesRead < framesToRead) {
            drmp3_uint64 framesJustRead;
            drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
            drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempF32) / pMP3->channels;
            if (framesToReadNow > framesRemaining) {
                framesToReadNow = framesRemaining;
            }
            framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempF32);
            if (framesJustRead == 0) {
                break;
            }
            drmp3_f32_to_s16((drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalPCMFramesRead * pMP3->channels), pTempF32, framesJustRead * pMP3->channels);
            totalPCMFramesRead += framesJustRead;
        }
        return totalPCMFramesRead;
    }
#endif
}
static void drmp3_reset(drmp3* pMP3)
{
    DRMP3_ASSERT(pMP3 != NULL);
    pMP3->pcmFramesConsumedInMP3Frame = 0;
    pMP3->pcmFramesRemainingInMP3Frame = 0;

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

static drmp3_bool32 drmp3_seek_to_start_of_stream(drmp3* pMP3)
{
    DRMP3_ASSERT(pMP3 != NULL);
    DRMP3_ASSERT(pMP3->onSeek != NULL);
    if (!drmp3__on_seek(pMP3, 0, drmp3_seek_origin_start)) {
        return DRMP3_FALSE;
    }
    drmp3_reset(pMP3);
    return DRMP3_TRUE;
}
static drmp3_bool32 drmp3_seek_forward_by_pcm_frames__brute_force(drmp3* pMP3, drmp3_uint64 frameOffset)
{
    drmp3_uint64 framesRead;
#if defined(DR_MP3_FLOAT_OUTPUT)
    framesRead = drmp3_read_pcm_frames_f32(pMP3, frameOffset, NULL);
#else
    framesRead = drmp3_read_pcm_frames_s16(pMP3, frameOffset, NULL);
#endif
    if (framesRead != frameOffset) {
        return DRMP3_FALSE;
    }
    return DRMP3_TRUE;
}
static drmp3_bool32 drmp3_seek_to_pcm_frame__brute_force(drmp3* pMP3, drmp3_uint64 frameIndex)
{
    DRMP3_ASSERT(pMP3 != NULL);
    if (frameIndex == pMP3->currentPCMFrame) {
        return DRMP3_TRUE;
    }
    if (frameIndex < pMP3->currentPCMFrame) {
        if (!drmp3_seek_to_start_of_stream(pMP3)) {
            return DRMP3_FALSE;
        }
    }
    DRMP3_ASSERT(frameIndex >= pMP3->currentPCMFrame);
    return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, (frameIndex - pMP3->currentPCMFrame));
}
static drmp3_bool32 drmp3_find_closest_seek_point(drmp3* pMP3, drmp3_uint64 frameIndex, drmp3_uint32* pSeekPointIndex)
{
    drmp3_uint32 iSeekPoint;
    DRMP3_ASSERT(pSeekPointIndex != NULL);
    *pSeekPointIndex = 0;
    if (frameIndex < pMP3->pSeekPoints[0].pcmFrameIndex) {
        return DRMP3_FALSE;
    }
    for (iSeekPoint = 0; iSeekPoint < pMP3->seekPointCount; ++iSeekPoint) {
        if (pMP3->pSeekPoints[iSeekPoint].pcmFrameIndex > frameIndex) {
            break;
        }
        *pSeekPointIndex = iSeekPoint;
    }
    return DRMP3_TRUE;
}
static drmp3_bool32 drmp3_seek_to_pcm_frame__seek_table(drmp3* pMP3, drmp3_uint64 frameIndex)
{
    drmp3_seek_point seekPoint;
    drmp3_uint32 priorSeekPointIndex;
    drmp3_uint16 iMP3Frame;
    drmp3_uint64 leftoverFrames;
    DRMP3_ASSERT(pMP3 != NULL);
    DRMP3_ASSERT(pMP3->pSeekPoints != NULL);
    DRMP3_ASSERT(pMP3->seekPointCount > 0);
    if (drmp3_find_closest_seek_point(pMP3, frameIndex, &priorSeekPointIndex)) {
        seekPoint = pMP3->pSeekPoints[priorSeekPointIndex];
    } else {
        seekPoint.seekPosInBytes     = 0;
        seekPoint.pcmFrameIndex      = 0;
        seekPoint.mp3FramesToDiscard = 0;
        seekPoint.pcmFramesToDiscard = 0;
    }
    if (!drmp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, drmp3_seek_origin_start)) {
        return DRMP3_FALSE;
    }
    drmp3_reset(pMP3);
    for (iMP3Frame = 0; iMP3Frame < seekPoint.mp3FramesToDiscard; ++iMP3Frame) {
        drmp3_uint32 pcmFramesRead;
        drmp3d_sample_t* pPCMFrames;
        pPCMFrames = NULL;
        if (iMP3Frame == seekPoint.mp3FramesToDiscard-1) {
            pPCMFrames = (drmp3d_sample_t*)pMP3->pcmFrames;
        }
        pcmFramesRead = drmp3_decode_next_frame_ex(pMP3, pPCMFrames);
        if (pcmFramesRead == 0) {
            return DRMP3_FALSE;
        }
    }
    pMP3->currentPCMFrame = seekPoint.pcmFrameIndex - seekPoint.pcmFramesToDiscard;
    leftoverFrames = frameIndex - pMP3->currentPCMFrame;
    return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, leftoverFrames);
}
DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex)
{
    if (pMP3 == NULL || pMP3->onSeek == NULL) {
        return DRMP3_FALSE;
    }
    if (frameIndex == 0) {
        return drmp3_seek_to_start_of_stream(pMP3);
    }
    if (pMP3->pSeekPoints != NULL && pMP3->seekPointCount > 0) {
        return drmp3_seek_to_pcm_frame__seek_table(pMP3, frameIndex);
    } else {
        return drmp3_seek_to_pcm_frame__brute_force(pMP3, frameIndex);
    }
}
DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount)
{
    drmp3_uint64 currentPCMFrame;
    drmp3_uint64 totalPCMFrameCount;
    drmp3_uint64 totalMP3FrameCount;
    if (pMP3 == NULL) {
        return DRMP3_FALSE;
    }
    if (pMP3->onSeek == NULL) {
        return DRMP3_FALSE;
    }
    currentPCMFrame = pMP3->currentPCMFrame;
    if (!drmp3_seek_to_start_of_stream(pMP3)) {
        return DRMP3_FALSE;
    }
    totalPCMFrameCount = 0;
    totalMP3FrameCount = 0;
    for (;;) {
        drmp3_uint32 pcmFramesInCurrentMP3Frame;
        pcmFramesInCurrentMP3Frame = drmp3_decode_next_frame_ex(pMP3, NULL);
        if (pcmFramesInCurrentMP3Frame == 0) {
            break;
        }
        totalPCMFrameCount += pcmFramesInCurrentMP3Frame;
        totalMP3FrameCount += 1;
    }
    if (!drmp3_seek_to_start_of_stream(pMP3)) {
        return DRMP3_FALSE;
    }
    if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
        return DRMP3_FALSE;
    }
    if (pMP3FrameCount != NULL) {
        *pMP3FrameCount = totalMP3FrameCount;
    }
    if (pPCMFrameCount != NULL) {
        *pPCMFrameCount = totalPCMFrameCount;
    }
    return DRMP3_TRUE;
}
DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3)
{
    drmp3_uint64 totalPCMFrameCount;
    if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, NULL, &totalPCMFrameCount)) {
        return 0;
    }
    return totalPCMFrameCount;
}
DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3)
{
    drmp3_uint64 totalMP3FrameCount;
    if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, NULL)) {
        return 0;
    }
    return totalMP3FrameCount;
}
static void drmp3__accumulate_running_pcm_frame_count(drmp3* pMP3, drmp3_uint32 pcmFrameCountIn, drmp3_uint64* pRunningPCMFrameCount, float* pRunningPCMFrameCountFractionalPart)
{
    float srcRatio;
    float pcmFrameCountOutF;
    drmp3_uint32 pcmFrameCountOut;
    srcRatio = (float)pMP3->mp3FrameSampleRate / (float)pMP3->sampleRate;
    DRMP3_ASSERT(srcRatio > 0);
    pcmFrameCountOutF = *pRunningPCMFrameCountFractionalPart + (pcmFrameCountIn / srcRatio);
    pcmFrameCountOut  = (drmp3_uint32)pcmFrameCountOutF;
    *pRunningPCMFrameCountFractionalPart = pcmFrameCountOutF - pcmFrameCountOut;
    *pRunningPCMFrameCount += pcmFrameCountOut;
}
typedef struct
{
    drmp3_uint64 bytePos;
    drmp3_uint64 pcmFrameIndex;
} drmp3__seeking_mp3_frame_info;
DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints)
{
    drmp3_uint32 seekPointCount;
    drmp3_uint64 currentPCMFrame;
    drmp3_uint64 totalMP3FrameCount;
    drmp3_uint64 totalPCMFrameCount;
    if (pMP3 == NULL || pSeekPointCount == NULL || pSeekPoints == NULL) {
        return DRMP3_FALSE;
    }
    seekPointCount = *pSeekPointCount;
    if (seekPointCount == 0) {
        return DRMP3_FALSE;
    }
    currentPCMFrame = pMP3->currentPCMFrame;
    if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, &totalPCMFrameCount)) {
        return DRMP3_FALSE;
    }
    if (totalMP3FrameCount < DRMP3_SEEK_LEADING_MP3_FRAMES+1) {
        seekPointCount = 1;
        pSeekPoints[0].seekPosInBytes     = 0;
        pSeekPoints[0].pcmFrameIndex      = 0;
        pSeekPoints[0].mp3FramesToDiscard = 0;
        pSeekPoints[0].pcmFramesToDiscard = 0;
    } else {
        drmp3_uint64 pcmFramesBetweenSeekPoints;
        drmp3__seeking_mp3_frame_info mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES+1];
        drmp3_uint64 runningPCMFrameCount = 0;
        float runningPCMFrameCountFractionalPart = 0;
        drmp3_uint64 nextTargetPCMFrame;
        drmp3_uint32 iMP3Frame;
        drmp3_uint32 iSeekPoint;
        if (seekPointCount > totalMP3FrameCount-1) {
            seekPointCount = (drmp3_uint32)totalMP3FrameCount-1;
        }
        pcmFramesBetweenSeekPoints = totalPCMFrameCount / (seekPointCount+1);
        if (!drmp3_seek_to_start_of_stream(pMP3)) {
            return DRMP3_FALSE;
        }
        for (iMP3Frame = 0; iMP3Frame < DRMP3_SEEK_LEADING_MP3_FRAMES+1; ++iMP3Frame) {
            drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
            DRMP3_ASSERT(pMP3->streamCursor >= pMP3->dataSize);
            mp3FrameInfo[iMP3Frame].bytePos       = pMP3->streamCursor - pMP3->dataSize;
            mp3FrameInfo[iMP3Frame].pcmFrameIndex = runningPCMFrameCount;
            pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL);
            if (pcmFramesInCurrentMP3FrameIn == 0) {
                return DRMP3_FALSE;
            }
            drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
        }
        nextTargetPCMFrame = 0;
        for (iSeekPoint = 0; iSeekPoint < seekPointCount; ++iSeekPoint) {
            nextTargetPCMFrame += pcmFramesBetweenSeekPoints;
            for (;;) {
                if (nextTargetPCMFrame < runningPCMFrameCount) {
                    pSeekPoints[iSeekPoint].seekPosInBytes     = mp3FrameInfo[0].bytePos;
                    pSeekPoints[iSeekPoint].pcmFrameIndex      = nextTargetPCMFrame;
                    pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
                    pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
                    break;
                } else {
                    size_t i;
                    drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
                    for (i = 0; i < DRMP3_COUNTOF(mp3FrameInfo)-1; ++i) {
                        mp3FrameInfo[i] = mp3FrameInfo[i+1];
                    }
                    mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].bytePos       = pMP3->streamCursor - pMP3->dataSize;
                    mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].pcmFrameIndex = runningPCMFrameCount;
                    pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL);
                    if (pcmFramesInCurrentMP3FrameIn == 0) {
                        pSeekPoints[iSeekPoint].seekPosInBytes     = mp3FrameInfo[0].bytePos;
                        pSeekPoints[iSeekPoint].pcmFrameIndex      = nextTargetPCMFrame;
                        pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
                        pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
                        break;
                    }
                    drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
                }
            }
        }
        if (!drmp3_seek_to_start_of_stream(pMP3)) {
            return DRMP3_FALSE;
        }
        if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
            return DRMP3_FALSE;
        }
    }
    *pSeekPointCount = seekPointCount;
    return DRMP3_TRUE;
}
DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints)
{
    if (pMP3 == NULL) {
        return DRMP3_FALSE;

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

        pMP3->pSeekPoints = NULL;
    } else {
        pMP3->seekPointCount = seekPointCount;
        pMP3->pSeekPoints = pSeekPoints;
    }
    return DRMP3_TRUE;
}
static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
{
    drmp3_uint64 totalFramesRead = 0;
    drmp3_uint64 framesCapacity = 0;
    float* pFrames = NULL;
    float temp[4096];
    DRMP3_ASSERT(pMP3 != NULL);
    for (;;) {
        drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
        drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_f32(pMP3, framesToReadRightNow, temp);
        if (framesJustRead == 0) {
            break;
        }
        if (framesCapacity < totalFramesRead + framesJustRead) {
            drmp3_uint64 oldFramesBufferSize;
            drmp3_uint64 newFramesBufferSize;
            drmp3_uint64 newFramesCap;
            float* pNewFrames;
            newFramesCap = framesCapacity * 2;
            if (newFramesCap < totalFramesRead + framesJustRead) {
                newFramesCap = totalFramesRead + framesJustRead;
            }
            oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(float);
            newFramesBufferSize = newFramesCap   * pMP3->channels * sizeof(float);
            if (newFramesBufferSize > DRMP3_SIZE_MAX) {
                break;
            }
            pNewFrames = (float*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
            if (pNewFrames == NULL) {
                drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
                break;
            }
            pFrames = pNewFrames;
            framesCapacity = newFramesCap;
        }
        DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float)));
        totalFramesRead += framesJustRead;
        if (framesJustRead != framesToReadRightNow) {
            break;
        }
    }
    if (pConfig != NULL) {
        pConfig->channels   = pMP3->channels;
        pConfig->sampleRate = pMP3->sampleRate;
    }
    drmp3_uninit(pMP3);
    if (pTotalFrameCount) {
        *pTotalFrameCount = totalFramesRead;
    }
    return pFrames;
}
static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
{
    drmp3_uint64 totalFramesRead = 0;
    drmp3_uint64 framesCapacity = 0;
    drmp3_int16* pFrames = NULL;
    drmp3_int16 temp[4096];
    DRMP3_ASSERT(pMP3 != NULL);
    for (;;) {
        drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
        drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_s16(pMP3, framesToReadRightNow, temp);
        if (framesJustRead == 0) {
            break;
        }
        if (framesCapacity < totalFramesRead + framesJustRead) {
            drmp3_uint64 newFramesBufferSize;
            drmp3_uint64 oldFramesBufferSize;
            drmp3_uint64 newFramesCap;
            drmp3_int16* pNewFrames;
            newFramesCap = framesCapacity * 2;
            if (newFramesCap < totalFramesRead + framesJustRead) {
                newFramesCap = totalFramesRead + framesJustRead;
            }
            oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(drmp3_int16);
            newFramesBufferSize = newFramesCap   * pMP3->channels * sizeof(drmp3_int16);
            if (newFramesBufferSize > DRMP3_SIZE_MAX) {
                break;
            }
            pNewFrames = (drmp3_int16*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
            if (pNewFrames == NULL) {
                drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
                break;
            }
            pFrames = pNewFrames;
            framesCapacity = newFramesCap;
        }
        DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(drmp3_int16)));
        totalFramesRead += framesJustRead;
        if (framesJustRead != framesToReadRightNow) {
            break;
        }
    }
    if (pConfig != NULL) {
        pConfig->channels   = pMP3->channels;
        pConfig->sampleRate = pMP3->sampleRate;
    }
    drmp3_uninit(pMP3);
    if (pTotalFrameCount) {
        *pTotalFrameCount = totalFramesRead;
    }
    return pFrames;
}
DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    drmp3 mp3;
    if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
        return NULL;
    }
    return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
}
DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    drmp3 mp3;
    if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
        return NULL;
    }
    return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
}
DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    drmp3 mp3;
    if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
        return NULL;
    }
    return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
}
DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    drmp3 mp3;
    if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
        return NULL;
    }
    return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
}
#ifndef DR_MP3_NO_STDIO
DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    drmp3 mp3;
    if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
        return NULL;
    }
    return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
}
DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    drmp3 mp3;
    if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
        return NULL;
    }
    return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
}
#endif
DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks)
{

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



Changes to Data Conversion
--------------------------
The previous data conversion system used callbacks to deliver input data for conversion. This design works well in some specific situations, but in other
situations it has some major readability and maintenance issues. The decision was made to replace this with a more iterative approach where you just pass in a
pointer to the input data directly rather than dealing with a callback.

The following are the data conversion APIs that have been removed and their replacements:

  - ma_format_converter -> ma_convert_pcm_frames_format()
  - ma_channel_router   -> ma_channel_converter
  - ma_src              -> ma_resampler
  - ma_pcm_converter    -> ma_data_converter

The previous conversion APIs accepted a callback in their configs. There are no longer any callbacks to deal with. Instead you just pass the data into the
`*_process_pcm_frames()` function as a pointer to a buffer.

The simplest aspect of data conversion is sample format conversion. To convert between two formats, just call `ma_convert_pcm_frames_format()`. Channel
conversion is also simple which you can do with `ma_channel_converter` via `ma_channel_converter_process_pcm_frames()`.

Resampling is more complicated because the number of output frames that are processed is different to the number of input frames that are consumed. When you
call `ma_resampler_process_pcm_frames()` you need to pass in the number of input frames available for processing and the number of output frames you want to
output. Upon returning they will receive the number of input frames that were consumed and the number of output frames that were generated.

The `ma_data_converter` API is a wrapper around format, channel and sample rate conversion and handles all of the data conversion you'll need which probably
makes it the best option if you need to do data conversion.

In addition to changes to the API design, a few other changes have been made to the data conversion pipeline:

  - The sinc resampler has been removed. This was completely broken and never actually worked properly.
  - The linear resampler now uses low-pass filtering to remove aliasing. The quality of the low-pass filter can be controlled via the resampler config with the
    `lpfOrder` option, which has a maximum value of MA_MAX_FILTER_ORDER.
  - Data conversion now supports s16 natively which runs through a fixed point pipeline. Previously everything needed to be converted to floating point before

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

latency, when in fact it was that value divided by the period count that determined it. These variables have been removed and replaced with new ones called
`periodSizeInFrames` and `periodSizeInMilliseconds`.

These new configuration variables work in the same way as their predecessors in that if one is set to 0, the other will be used, but the main difference is
that you now set these to you desired latency rather than the size of the entire buffer. The benefit of this is that it's much easier and less confusing to
configure latency.

The following unused APIs have been removed:

    ma_get_default_buffer_size_in_milliseconds()
    ma_get_default_buffer_size_in_frames()

The following macros have been removed:

    MA_BASE_BUFFER_SIZE_IN_MILLISECONDS_LOW_LATENCY
    MA_BASE_BUFFER_SIZE_IN_MILLISECONDS_CONSERVATIVE


Other API Changes
-----------------
Other less major API changes have also been made in version 0.10.

`ma_device_set_stop_callback()` has been removed. If you require a stop callback, you must now set it via the device config just like the data callback.

The `ma_sine_wave` API has been replaced with a more general API called `ma_waveform`. This supports generation of different types of waveforms, including
sine, square, triangle and sawtooth. Use `ma_waveform_init()` in place of `ma_sine_wave_init()` to initialize the waveform object. This takes a configuration
object called `ma_waveform_config` which defines the properties of the waveform. Use `ma_waveform_config_init()` to initialize a `ma_waveform_config` object.
Use `ma_waveform_read_pcm_frames()` in place of `ma_sine_wave_read_f32()` and `ma_sine_wave_read_f32_ex()`.

`ma_convert_frames()` and `ma_convert_frames_ex()` have been changed. Both of these functions now take a new parameter called `frameCountOut` which specifies
the size of the output buffer in PCM frames. This has been added for safety. In addition to this, the parameters for `ma_convert_frames_ex()` have changed to
take a pointer to a `ma_data_converter_config` object to specify the input and output formats to convert between. This was done to make it more flexible, to
prevent the parameter list getting too long, and to prevent API breakage whenever a new conversion property is added.

`ma_calculate_frame_count_after_src()` has been renamed to `ma_calculate_frame_count_after_resampling()` for consistency with the new `ma_resampler` API.


Filters
-------
The following filters have been added:

    |-------------|-------------------------------------------------------------------|
    | API         | Description                                                       |
    |-------------|-------------------------------------------------------------------|
    | ma_biquad   | Biquad filter (transposed direct form 2)                          |

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

    | ma_hishelf2 | Second order high shelf filter                                    |
    |-------------|-------------------------------------------------------------------|

These filters all support 32-bit floating point and 16-bit signed integer formats natively. Other formats need to be converted beforehand.


Sine, Square, Triangle and Sawtooth Waveforms
---------------------------------------------
Previously miniaudio supported only sine wave generation. This has now been generalized to support sine, square, triangle and sawtooth waveforms. The old
`ma_sine_wave` API has been removed and replaced with the `ma_waveform` API. Use `ma_waveform_config_init()` to initialize a config object, and then pass it
into `ma_waveform_init()`. Then use `ma_waveform_read_pcm_frames()` to read PCM data.


Noise Generation
----------------
A noise generation API has been added. This is used via the `ma_noise` API. Currently white, pink and Brownian noise is supported. The `ma_noise` API is
similar to the waveform API. Use `ma_noise_config_init()` to initialize a config object, and then pass it into `ma_noise_init()` to initialize a `ma_noise`
object. Then use `ma_noise_read_pcm_frames()` to read PCM data.


Miscellaneous Changes
---------------------
The MA_NO_STDIO option has been removed. This would disable file I/O APIs, however this has proven to be too hard to maintain for it's perceived value and was
therefore removed.

Internal functions have all been made static where possible. If you get warnings about unused functions, please submit a bug report.

The `ma_device` structure is no longer defined as being aligned to MA_SIMD_ALIGNMENT. This resulted in a possible crash when allocating a `ma_device` object on

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



Full-Duplex Support
-------------------
The major feature added to version 0.9 is full-duplex. This has necessitated a few API changes.

1) The data callback has now changed. Previously there was one type of callback for playback and another for capture. I wanted to avoid a third callback just
   for full-duplex so the decision was made to break this API and unify the callbacks. Now, there is just one callback which is the same for all three modes
   (playback, capture, duplex). The new callback looks like the following:

       void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);

   This callback allows you to move data straight out of the input buffer and into the output buffer in full-duplex mode. In playback-only mode, pInput will be
   null. Likewise, pOutput will be null in capture-only mode. The sample count is no longer returned from the callback since it's not necessary for miniaudio
   anymore.

2) The device config needed to change in order to support full-duplex. Full-duplex requires the ability to allow the client to choose a different PCM format
   for the playback and capture sides. The old ma_device_config object simply did not allow this and needed to change. With these changes you now specify the
   device ID, format, channels, channel map and share mode on a per-playback and per-capture basis (see example below). The sample rate must be the same for
   playback and capture.

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


Other API Changes
-----------------
In addition to the above, the following API changes have been made:

- The log callback is no longer passed to ma_context_config_init(). Instead you need to set it manually after initialization.
- The onLogCallback member of ma_context_config has been renamed to "logCallback".
- The log callback now takes a logLevel parameter. The new callback looks like: void log_callback(ma_context* pContext, ma_device* pDevice, ma_uint32 logLevel, const char* message)
  - You can use ma_log_level_to_string() to convert the logLevel to human readable text if you want to log it.
- Some APIs have been renamed:
  - mal_decoder_read()          -> ma_decoder_read_pcm_frames()
  - mal_decoder_seek_to_frame() -> ma_decoder_seek_to_pcm_frame()
  - mal_sine_wave_read()        -> ma_sine_wave_read_f32()
  - mal_sine_wave_read_ex()     -> ma_sine_wave_read_f32_ex()
- Some APIs have been removed:
  - mal_device_get_buffer_size_in_bytes()
  - mal_device_set_recv_callback()
  - mal_device_set_send_callback()
  - mal_src_set_input_sample_rate()
  - mal_src_set_output_sample_rate()
- Error codes have been rearranged. If you're a binding maintainer you will need to update.
- The ma_backend enums have been rearranged to priority order. The rationale for this is to simplify automatic backend selection and to make it easier to see
  the priority. If you're a binding maintainer you will need to update.
- ma_dsp has been renamed to ma_pcm_converter. The rationale for this change is that I'm expecting "ma_dsp" to conflict with some future planned high-level
  APIs.
- For functions that take a pointer/count combo, such as ma_decoder_read_pcm_frames(), the parameter order has changed so that the pointer comes before the
  count. The rationale for this is to keep it consistent with things like memcpy().


Miscellaneous Changes
---------------------
The following miscellaneous changes have also been made.

- The AAudio backend has been added for Android 8 and above. This is Android's new "High-Performance Audio" API. (For the record, this is one of the nicest
  audio APIs out there, just behind the BSD audio APIs).
- The WebAudio backend has been added. This is based on ScriptProcessorNode. This removes the need for SDL.
- The SDL and OpenAL backends have been removed. These were originally implemented to add support for platforms for which miniaudio was not explicitly
  supported. These are no longer needed and have therefore been removed.
- Device initialization now fails if the requested share mode is not supported. If you ask for exclusive mode, you either get an exclusive mode device, or an
  error. The rationale for this change is to give the client more control over how to handle cases when the desired shared mode is unavailable.
- A lock-free ring buffer API has been added. There are two varients of this. "ma_rb" operates on bytes, whereas "ma_pcm_rb" operates on PCM frames.
- The library is now licensed as a choice of Public Domain (Unlicense) _or_ MIT-0 (No Attribution) which is the same as MIT, but removes the attribution
  requirement. The rationale for this is to support countries that don't recognize public domain.
*/

/*
REVISION HISTORY
================
v0.10.21 - 2020-10-30
  - Add ma_is_backend_enabled() and ma_get_enabled_backends() for retrieving enabled backends at run-time.
  - WASAPI: Fix a copy and paste bug relating to loopback mode.

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

  - Core Audio: Improvements to format/channels/rate selection when requesting defaults.
  - Core Audio: Add notes regarding the Apple notarization process.
  - Fix some bugs due to null pointer dereferences.

v0.10.20 - 2020-10-06
  - Fix build errors with UWP.
  - Minor documentation updates.

v0.10.19 - 2020-09-22
  - WASAPI: Return an error when exclusive mode is requested, but the native format is not supported by miniaudio.
  - Fix a bug where ma_decoder_seek_to_pcm_frames() never returns MA_SUCCESS even though it was successful.
  - Store the sample rate in the `ma_lpf` and `ma_hpf` structures.

v0.10.18 - 2020-08-30
  - Fix build errors with VC6.
  - Fix a bug in channel converter for s32 format.
  - Change channel converter configs to use the default channel map instead of a blank channel map when no channel map is specified when initializing the
    config. This fixes an issue where the optimized mono expansion path would never get used.
  - Use a more appropriate default format for FLAC decoders. This will now use ma_format_s16 when the FLAC is encoded as 16-bit.
  - Update FLAC decoder.
  - Update links to point to the new repository location (https://github.com/mackron/miniaudio).

v0.10.17 - 2020-08-28
  - Fix an error where the WAV codec is incorrectly excluded from the build depending on which compile time options are set.
  - Fix a bug in ma_audio_buffer_read_pcm_frames() where it isn't returning the correct number of frames processed.
  - Fix compilation error on Android.
  - Core Audio: Fix a bug with full-duplex mode.
  - Add ma_decoder_get_cursor_in_pcm_frames().
  - Update WAV codec.

v0.10.16 - 2020-08-14
  - WASAPI: Fix a potential crash due to using an uninitialized variable.
  - OpenSL: Enable runtime linking.
  - OpenSL: Fix a multithreading bug when initializing and uninitializing multiple contexts at the same time.
  - iOS: Improvements to device enumeration.
  - Fix a crash in ma_data_source_read_pcm_frames() when the output frame count parameter is NULL.
  - Fix a bug in ma_data_source_read_pcm_frames() where looping doesn't work.
  - Fix some compilation warnings on Windows when both DirectSound and WinMM are disabled.
  - Fix some compilation warnings when no decoders are enabled.
  - Add ma_audio_buffer_get_available_frames().
  - Add ma_decoder_get_available_frames().
  - Add sample rate to ma_data_source_get_data_format().
  - Change volume APIs to take 64-bit frame counts.
  - Updates to documentation.

v0.10.15 - 2020-07-15
  - Fix a bug when converting bit-masked channel maps to miniaudio channel maps. This affects the WASAPI and OpenSL backends.

v0.10.14 - 2020-07-14
  - Fix compilation errors on Android.
  - Fix compilation errors with -march=armv6.
  - Updates to the documentation.

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

    If you get errors about multiple definitions you need to either enable the options above, move the implementation of dr_wav, dr_flac and/or dr_mp3 to before
    the implementation of miniaudio, or update dr_wav, dr_flac and/or dr_mp3.
  - Changes to the internal atomics library. This has been replaced with c89atomic.h which is embedded within this file.
  - Fix a bug when a decoding backend reports configurations outside the limits of miniaudio's decoder abstraction.
  - Fix the UWP build.
  - Fix the Core Audio build.
  - Fix the -std=c89 build on GCC.

v0.10.8 - 2020-06-22
  - Remove dependency on ma_context from mutexes.
  - Change ma_data_source_read_pcm_frames() to return a result code and output the frames read as an output parameter.
  - Change ma_data_source_seek_pcm_frames() to return a result code and output the frames seeked as an output parameter.
  - Change ma_audio_buffer_unmap() to return MA_AT_END when the end has been reached. This should be considered successful.
  - Change playback.pDeviceID and capture.pDeviceID to constant pointers in ma_device_config.
  - Add support for initializing decoders from a virtual file system object. This is achieved via the ma_vfs API and allows the application to customize file
    IO for the loading and reading of raw audio data. Passing in NULL for the VFS will use defaults. New APIs:
    - ma_decoder_init_vfs()
    - ma_decoder_init_vfs_wav()
    - ma_decoder_init_vfs_flac()
    - ma_decoder_init_vfs_mp3()
    - ma_decoder_init_vfs_vorbis()
    - ma_decoder_init_vfs_w()
    - ma_decoder_init_vfs_wav_w()
    - ma_decoder_init_vfs_flac_w()
    - ma_decoder_init_vfs_mp3_w()
    - ma_decoder_init_vfs_vorbis_w()
  - Add support for memory mapping to ma_data_source.
    - ma_data_source_map()
    - ma_data_source_unmap()
  - Add ma_offset_pcm_frames_ptr() and ma_offset_pcm_frames_const_ptr() which can be used for offsetting a pointer by a specified number of PCM frames.
  - Add initial implementation of ma_yield() which is useful for spin locks which will be used in some upcoming work.
  - Add documentation for log levels.
  - The ma_event API has been made public in preparation for some uncoming work.
  - Fix a bug in ma_decoder_seek_to_pcm_frame() where the internal sample rate is not being taken into account for determining the seek location.
  - Fix some bugs with the linear resampler when dynamically changing the sample rate.
  - Fix compilation errors with MA_NO_DEVICE_IO.
  - Fix some warnings with GCC and -std=c89.
  - Fix some formatting warnings with GCC and -Wall and -Wpedantic.
  - Fix some warnings with VC6.
  - Minor optimization to ma_copy_pcm_frames(). This is now a no-op when the input and output buffers are the same.

v0.10.7 - 2020-05-25
  - Fix a compilation error in the C++ build.
  - Silence a warning.

v0.10.6 - 2020-05-24
  - Change ma_clip_samples_f32() and ma_clip_pcm_frames_f32() to take a 64-bit sample/frame count.
  - Change ma_zero_pcm_frames() to clear to 128 for ma_format_u8.
  - Add ma_silence_pcm_frames() which replaces ma_zero_pcm_frames(). ma_zero_pcm_frames() will be removed in version 0.11.
  - Add support for u8, s24 and s32 formats to ma_channel_converter.
  - Add compile-time and run-time version querying.
    - MA_VERSION_MINOR
    - MA_VERSION_MAJOR
    - MA_VERSION_REVISION
    - MA_VERSION_STRING
    - ma_version()
    - ma_version_string()
  - Add ma_audio_buffer for reading raw audio data directly from memory.
  - Fix a bug in shuffle mode in ma_channel_converter.
  - Fix compilation errors in certain configurations for ALSA and PulseAudio.
  - The data callback now initializes the output buffer to 128 when the playback sample format is ma_format_u8.

v0.10.5 - 2020-05-05
  - Change ma_zero_pcm_frames() to take a 64-bit frame count.
  - Add ma_copy_pcm_frames().
  - Add MA_NO_GENERATION build option to exclude the `ma_waveform` and `ma_noise` APIs from the build.
  - Add support for formatted logging to the VC6 build.
  - Fix a crash in the linear resampler when LPF order is 0.
  - Fix compilation errors and warnings with older versions of Visual Studio.
  - Minor documentation updates.

v0.10.4 - 2020-04-12
  - Fix a data conversion bug when converting from the client format to the native device format.

v0.10.3 - 2020-04-07

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

  - Fix a bug in ma_linear_resampler_set_rate() and ma_linear_resampler_set_rate_ratio().

v0.10.1 - 2020-03-17
  - Add MA_API decoration. This can be customized by defining it before including miniaudio.h.
  - Fix a bug where opening a file would return a success code when in fact it failed.
  - Fix compilation errors with Visual Studio 6 and 2003.
  - Fix warnings on macOS.

v0.10.0 - 2020-03-07
  - API CHANGE: Refactor data conversion APIs
    - ma_format_converter has been removed. Use ma_convert_pcm_frames_format() instead.
    - ma_channel_router has been replaced with ma_channel_converter.
    - ma_src has been replaced with ma_resampler
    - ma_pcm_converter has been replaced with ma_data_converter
  - API CHANGE: Add support for custom memory allocation callbacks. The following APIs have been updated to take an extra parameter for the allocation
    callbacks:
    - ma_malloc()
    - ma_realloc()
    - ma_free()
    - ma_aligned_malloc()
    - ma_aligned_free()
    - ma_rb_init() / ma_rb_init_ex()
    - ma_pcm_rb_init() / ma_pcm_rb_init_ex()
  - API CHANGE: Simplify latency specification in device configurations. The bufferSizeInFrames and bufferSizeInMilliseconds parameters have been replaced with
    periodSizeInFrames and periodSizeInMilliseconds respectively. The previous variables defined the size of the entire buffer, whereas the new ones define the
    size of a period. The following APIs have been removed since they are no longer relevant:
    - ma_get_default_buffer_size_in_milliseconds()
    - ma_get_default_buffer_size_in_frames()
  - API CHANGE: ma_device_set_stop_callback() has been removed. If you require a stop callback, you must now set it via the device config just like the data
    callback.
  - API CHANGE: The ma_sine_wave API has been replaced with ma_waveform. The following APIs have been removed:
    - ma_sine_wave_init()
    - ma_sine_wave_read_f32()
    - ma_sine_wave_read_f32_ex()
  - API CHANGE: ma_convert_frames() has been updated to take an extra parameter which is the size of the output buffer in PCM frames. Parameters have also been
    reordered.
  - API CHANGE: ma_convert_frames_ex() has been changed to take a pointer to a ma_data_converter_config object to specify the input and output formats to
    convert between.
  - API CHANGE: ma_calculate_frame_count_after_src() has been renamed to ma_calculate_frame_count_after_resampling().
  - Add support for the following filters:
    - Biquad (ma_biquad)
    - First order low-pass (ma_lpf1)
    - Second order low-pass (ma_lpf2)
    - Low-pass with configurable order (ma_lpf)
    - First order high-pass (ma_hpf1)
    - Second order high-pass (ma_hpf2)
    - High-pass with configurable order (ma_hpf)
    - Second order band-pass (ma_bpf2)
    - Band-pass with configurable order (ma_bpf)

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

  - Add noise generation API (ma_noise) with support for the following:
    - White
    - Pink
    - Brownian
  - Add encoding API (ma_encoder). This only supports outputting to WAV files via dr_wav.
  - Add ma_result_description() which is used to retrieve a human readable description of a given result code.
  - Result codes have been changed. Binding maintainers will need to update their result code constants.
  - More meaningful result codes are now returned when a file fails to open.
  - Internal functions have all been made static where possible.
  - Fix potential crash when ma_device object's are not aligned to MA_SIMD_ALIGNMENT.
  - Fix a bug in ma_decoder_get_length_in_pcm_frames() where it was returning the length based on the internal sample rate rather than the output sample rate.
  - Fix bugs in some backends where the device is not drained properly in ma_device_stop().
  - Improvements to documentation.

v0.9.10 - 2020-01-15
  - Fix compilation errors due to #if/#endif mismatches.
  - WASAPI: Fix a bug where automatic stream routing is being performed for devices that are initialized with an explicit device ID.
  - iOS: Fix a crash on device uninitialization.

v0.9.9 - 2020-01-09
  - Fix compilation errors with MinGW.

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

  - Fix a compilation error when compiling for ARM architectures.
  - Fix a bug with the audio(4) backend where the device is incorrectly being opened in non-blocking mode.
  - Fix memory leaks in the Core Audio backend.
  - Minor refactoring to the WinMM, ALSA, PulseAudio, OSS, audio(4), sndio and null backends.

v0.9.6 - 2019-08-04
  - Add support for loading decoders using a wchar_t string for file paths.
  - Don't trigger an assert when ma_device_start() is called on a device that is already started. This will now log a warning
    and return MA_INVALID_OPERATION. The same applies for ma_device_stop().
  - Try fixing an issue with PulseAudio taking a long time to start playback.
  - Fix a bug in ma_convert_frames() and ma_convert_frames_ex().
  - Fix memory leaks in the WASAPI backend.
  - Fix a compilation error with Visual Studio 2010.

v0.9.5 - 2019-05-21
  - Add logging to ma_dlopen() and ma_dlsym().
  - Add ma_decoder_get_length_in_pcm_frames().
  - Fix a bug with capture on the OpenSL|ES backend.
  - Fix a bug with the ALSA backend where a device would not restart after being stopped.

v0.9.4 - 2019-05-06
  - Add support for C89. With this change, miniaudio should compile clean with GCC/Clang with "-std=c89 -ansi -pedantic" and
    Microsoft compilers back to VC6. Other compilers should also work, but have not been tested.

v0.9.3 - 2019-04-19
  - Fix compiler errors on GCC when compiling with -std=c99.

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

    - The device type, device ID and user data pointer have moved from ma_device_init() to the config.
    - All variations of ma_device_config_init_*() have been removed in favor of just ma_device_config_init().
    - ma_device_config_init() now takes only one parameter which is the device type. All other properties need
      to be set on the returned object directly.
    - The onDataCallback and onStopCallback members of ma_device_config have been renamed to "dataCallback"
      and "stopCallback".
    - The ID of the physical device is now split into two: one for the playback device and the other for the
      capture device. This is required for full-duplex. These are named "pPlaybackDeviceID" and "pCaptureDeviceID".
  - API CHANGE: The data callback has changed. It now uses a unified callback for all device types rather than
    being separate for each. It now takes two pointers - one containing input data and the other output data. This
    design in required for full-duplex. The return value is now void instead of the number of frames written. The
    new callback looks like the following:
        void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);
  - API CHANGE: Remove the log callback parameter from ma_context_config_init(). With this change,
    ma_context_config_init() now takes no parameters and the log callback is set via the structure directly. The
    new policy for config initialization is that only mandatory settings are passed in to *_config_init(). The
    "onLog" member of ma_context_config has been renamed to "logCallback".
  - API CHANGE: Remove ma_device_get_buffer_size_in_bytes().
  - API CHANGE: Rename decoding APIs to "pcm_frames" convention.
    - mal_decoder_read()          -> ma_decoder_read_pcm_frames()
    - mal_decoder_seek_to_frame() -> ma_decoder_seek_to_pcm_frame()
  - API CHANGE: Rename sine wave reading APIs to f32 convention.
    - mal_sine_wave_read()    -> ma_sine_wave_read_f32()
    - mal_sine_wave_read_ex() -> ma_sine_wave_read_f32_ex()
  - API CHANGE: Remove some deprecated APIs
    - mal_device_set_recv_callback()
    - mal_device_set_send_callback()
    - mal_src_set_input_sample_rate()
    - mal_src_set_output_sample_rate()
  - API CHANGE: Add log level to the log callback. New signature:
    - void on_log(ma_context* pContext, ma_device* pDevice, ma_uint32 logLevel, const char* message)
  - API CHANGE: Changes to result codes. Constants have changed and unused codes have been removed. If you're
    a binding mainainer you will need to update your result code constants.
  - API CHANGE: Change the order of the ma_backend enums to priority order. If you are a binding maintainer, you
    will need to update.
  - API CHANGE: Rename mal_dsp to ma_pcm_converter. All functions have been renamed from mal_dsp_*() to
    ma_pcm_converter_*(). All structures have been renamed from mal_dsp* to ma_pcm_converter*.
  - API CHANGE: Reorder parameters of ma_decoder_read_pcm_frames() to be consistent with the new parameter order scheme.
  - The resampling algorithm has been changed from sinc to linear. The rationale for this is that the sinc implementation
    is too inefficient right now. This will hopefully be improved at a later date.
  - Device initialization will no longer fall back to shared mode if exclusive mode is requested but is unusable.
    With this change, if you request an device in exclusive mode, but exclusive mode is not supported, it will not
    automatically fall back to shared mode. The client will need to reinitialize the device in shared mode if that's
    what they want.
  - Add ring buffer API. This is ma_rb and ma_pcm_rb, the difference being that ma_rb operates on bytes and
    ma_pcm_rb operates on PCM frames.
  - Add Web Audio backend. This is used when compiling with Emscripten. The SDL backend, which was previously
    used for web support, will be removed in a future version.
  - Add AAudio backend (Android Audio). This is the new priority backend for Android. Support for AAudio starts
    with Android 8. OpenSL|ES is used as a fallback for older versions of Android.
  - Remove OpenAL and SDL backends.
  - Fix a possible deadlock when rapidly stopping the device after it has started.
  - Update documentation.
  - Change licensing to a choice of public domain _or_ MIT-0 (No Attribution).

v0.8.14 - 2018-12-16

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

    user switches the default device via the operating system's audio preferences, miniaudio will automatically switch
    the internal device to the new default. This is not supported in exclusive mode.
  - WASAPI: Add support for hardware offloading via IAudioClient2. Only supported on Windows 8 and newer.
  - WASAPI: Add support for low-latency shared mode via IAudioClient3. Only supported on Windows 10 and newer.
  - Add support for compiling the UWP build as C.
  - mal_device_set_recv_callback() and mal_device_set_send_callback() have been deprecated. You must now set this
    when the device is initialized with mal_device_init*(). These will be removed in version 0.9.0.

v0.8.5 - 2018-08-12
  - Add support for specifying the size of a device's buffer in milliseconds. You can still set the buffer size in
    frames if that suits you. When bufferSizeInFrames is 0, bufferSizeInMilliseconds will be used. If both are non-0
    then bufferSizeInFrames will take priority. If both are set to 0 the default buffer size is used.
  - Add support for the audio(4) backend to OpenBSD.
  - Fix a bug with the ALSA backend that was causing problems on Raspberry Pi. This significantly improves the
    Raspberry Pi experience.
  - Fix a bug where an incorrect number of samples is returned from sinc resampling.
  - Add support for setting the value to be passed to internal calls to CoInitializeEx().
  - WASAPI and WinMM: Stop the device when it is unplugged.

v0.8.4 - 2018-08-06
  - Add sndio backend for OpenBSD.

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

v0.8.1 - 2018-07-06
  - Fix compilation errors and warnings.

v0.8 - 2018-07-05
  - Changed MAL_IMPLEMENTATION to MINI_AL_IMPLEMENTATION for consistency with other libraries. The old
    way is still supported for now, but you should update as it may be removed in the future.
  - API CHANGE: Replace device enumeration APIs. mal_enumerate_devices() has been replaced with
    mal_context_get_devices(). An additional low-level device enumration API has been introduced called
    mal_context_enumerate_devices() which uses a callback to report devices.
  - API CHANGE: Rename mal_get_sample_size_in_bytes() to mal_get_bytes_per_sample() and add
    mal_get_bytes_per_frame().
  - API CHANGE: Replace mal_device_config.preferExclusiveMode with mal_device_config.shareMode.
    - This new config can be set to mal_share_mode_shared (default) or mal_share_mode_exclusive.
  - API CHANGE: Remove excludeNullDevice from mal_context_config.alsa.
  - API CHANGE: Rename MAL_MAX_SAMPLE_SIZE_IN_BYTES to MAL_MAX_PCM_SAMPLE_SIZE_IN_BYTES.
  - API CHANGE: Change the default channel mapping to the standard Microsoft mapping.
  - API CHANGE: Remove backend-specific result codes.
  - API CHANGE: Changes to the format conversion APIs (mal_pcm_f32_to_s16(), etc.)
  - Add support for Core Audio (Apple).
  - Add support for PulseAudio.
    - This is the highest priority backend on Linux (higher priority than ALSA) since it is commonly

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

  - Make some APIs more const-correct.
  - Fix errors with SDL detection on Apple platforms.
  - Fix errors with OpenAL detection.
  - Fix some memory leaks.
  - Fix a bug with opening decoders from memory.
  - Early work on SSE2, AVX2 and NEON optimizations.
  - Miscellaneous bug fixes.
  - Documentation updates.

v0.7 - 2018-02-25
  - API CHANGE: Change mal_src_read_frames() and mal_dsp_read_frames() to use 64-bit sample counts.
  - Add decoder APIs for loading WAV, FLAC, Vorbis and MP3 files.
  - Allow opening of devices without a context.
    - In this case the context is created and managed internally by the device.
  - Change the default channel mapping to the same as that used by FLAC.
  - Fix build errors with macOS.

v0.6c - 2018-02-12
  - Fix build errors with BSD/OSS.

v0.6b - 2018-02-03

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

v0.6 - 2017-12-08
  - API CHANGE: Expose and improve mutex APIs. If you were using the mutex APIs before this version you'll
    need to update.
  - API CHANGE: SRC and DSP callbacks now take a pointer to a mal_src and mal_dsp object respectively.
  - API CHANGE: Improvements to event and thread APIs. These changes make these APIs more consistent.
  - Add support for SDL and Emscripten.
  - Simplify the build system further for when development packages for various backends are not installed.
    With this change, when the compiler supports __has_include, backends without the relevant development
    packages installed will be ignored. This fixes the build for old versions of MinGW.
  - Fixes to the Android build.
  - Add mal_convert_frames(). This is a high-level helper API for performing a one-time, bulk conversion of
    audio data to a different format.
  - Improvements to f32 -> u8/s16/s24/s32 conversion routines.
  - Fix a bug where the wrong value is returned from mal_device_start() for the OpenSL backend.
  - Fixes and improvements for Raspberry Pi.
  - Warning fixes.

v0.5 - 2017-11-11
  - API CHANGE: The mal_context_init() function now takes a pointer to a mal_context_config object for
    configuring the context. The works in the same kind of way as the device config. The rationale for this
    change is to give applications better control over context-level properties, add support for backend-

share/public_html/static/music_inc/test.html  view on Meta::CPAN

    GainNode = mycontext.createGain();
    GainNode.connect(mycontext.destination);
    return mycontext;
}
    let MainAudioContext = CreateAudioContext({'sampleRate' : 44100 });
    
    let ab = new AbortController();
    let mysignal = ab.signal;
    (async function() {
    let nwdrflac = await NetworkDrFlac('/stream/music_dl?name=Alien Ant Farm - ANThology (2001) [FLAC]/12 - Smooth Criminal.flac&max_sample_rate=48000', mysignal);
    let AB = await nwdrflac.read_pcm_frames_to_AudioBuffer(0, nwdrflac.totalPCMFrameCount, mysignal, MainAudioContext);
    let chanzero = AB.getChannelData(0);
    let tarr =  new Uint8Array(chanzero);
    var blob = new Blob([tarr], {type: "application/octet-stream"});
    var objectUrl = URL.createObjectURL(blob);
    window.open(objectUrl);
    })();
</script>

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

async function Module(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?....
;return moduleRtn}export default Module;

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

Every API that opens a drflac object now takes this extra parameter. These include the following:

    drflac_open()
    drflac_open_relaxed()
    drflac_open_with_metadata()
    drflac_open_with_metadata_relaxed()
    drflac_open_file()
    drflac_open_file_with_metadata()
    drflac_open_memory()
    drflac_open_memory_with_metadata()
    drflac_open_and_read_pcm_frames_s32()
    drflac_open_and_read_pcm_frames_s16()
    drflac_open_and_read_pcm_frames_f32()
    drflac_open_file_and_read_pcm_frames_s32()
    drflac_open_file_and_read_pcm_frames_s16()
    drflac_open_file_and_read_pcm_frames_f32()
    drflac_open_memory_and_read_pcm_frames_s32()
    drflac_open_memory_and_read_pcm_frames_s16()
    drflac_open_memory_and_read_pcm_frames_f32()



Optimizations
-------------
Seeking performance has been greatly improved. A new binary search based seeking algorithm has been introduced which significantly
improves performance over the brute force method which was used when no seek table was present. Seek table based seeking also takes
advantage of the new binary search seeking system to further improve performance there as well. Note that this depends on CRC which
means it will be disabled when DR_FLAC_NO_CRC is used.

The SSE4.1 pipeline has been cleaned up and optimized. You should see some improvements with decoding speed of 24-bit files in
particular. 16-bit streams should also see some improvement.

drflac_read_pcm_frames_s16() has been optimized. Previously this sat on top of drflac_read_pcm_frames_s32() and performed it's s32
to s16 conversion in a second pass. This is now all done in a single pass. This includes SSE2 and ARM NEON optimized paths.

A minor optimization has been implemented for drflac_read_pcm_frames_s32(). This will now use an SSE2 optimized pipeline for stereo
channel reconstruction which is the last part of the decoding process.

The ARM build has seen a few improvements. The CLZ (count leading zeroes) and REV (byte swap) instructions are now used when
compiling with GCC and Clang which is achieved using inline assembly. The CLZ instruction requires ARM architecture version 5 at
compile time and the REV instruction requires ARM architecture version 6.

An ARM NEON optimized pipeline has been implemented. To enable this you'll need to add -mfpu=neon to the command line when compiling.


Removed APIs
------------
The following APIs were deprecated in version 0.11.0 and have been completely removed in version 0.12.0:

    drflac_read_s32()                   -> drflac_read_pcm_frames_s32()
    drflac_read_s16()                   -> drflac_read_pcm_frames_s16()
    drflac_read_f32()                   -> drflac_read_pcm_frames_f32()
    drflac_seek_to_sample()             -> drflac_seek_to_pcm_frame()
    drflac_open_and_decode_s32()        -> drflac_open_and_read_pcm_frames_s32()
    drflac_open_and_decode_s16()        -> drflac_open_and_read_pcm_frames_s16()
    drflac_open_and_decode_f32()        -> drflac_open_and_read_pcm_frames_f32()
    drflac_open_and_decode_file_s32()   -> drflac_open_file_and_read_pcm_frames_s32()
    drflac_open_and_decode_file_s16()   -> drflac_open_file_and_read_pcm_frames_s16()
    drflac_open_and_decode_file_f32()   -> drflac_open_file_and_read_pcm_frames_f32()
    drflac_open_and_decode_memory_s32() -> drflac_open_memory_and_read_pcm_frames_s32()
    drflac_open_and_decode_memory_s16() -> drflac_open_memory_and_read_pcm_frames_s16()
    drflac_open_and_decode_memory_f32() -> drflac_open_memroy_and_read_pcm_frames_f32()

Prior versions of dr_flac operated on a per-sample basis whereas now it operates on PCM frames. The removed APIs all relate
to the old per-sample APIs. You now need to use the "pcm_frame" versions.
*/


/*
Introduction
============
dr_flac is a single file library. To use it, do something like the following in one .c file.

    ```c
    #define DR_FLAC_IMPLEMENTATION

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


You can then #include this file in other parts of the program as you would with any other header file. To decode audio data, do something like the following:

    ```c
    drflac* pFlac = drflac_open_file("MySong.flac", NULL);
    if (pFlac == NULL) {
        // Failed to open FLAC file
    }

    drflac_int32* pSamples = malloc(pFlac->totalPCMFrameCount * pFlac->channels * sizeof(drflac_int32));
    drflac_uint64 numberOfInterleavedSamplesActuallyRead = drflac_read_pcm_frames_s32(pFlac, pFlac->totalPCMFrameCount, pSamples);
    ```

The drflac object represents the decoder. It is a transparent type so all the information you need, such as the number of channels and the bits per sample,
should be directly accessible - just make sure you don't change their values. Samples are always output as interleaved signed 32-bit PCM. In the example above
a native FLAC stream was opened, however dr_flac has seamless support for Ogg encapsulated FLAC streams as well.

You do not need to decode the entire stream in one go - you just specify how many samples you'd like at any given time and the decoder will give you as many
samples as it can, up to the amount requested. Later on when you need the next batch of samples, just call it again. Example:

    ```c
    while (drflac_read_pcm_frames_s32(pFlac, chunkSizeInPCMFrames, pChunkSamples) > 0) {
        do_something();
    }
    ```

You can seek to a specific PCM frame with `drflac_seek_to_pcm_frame()`.

If you just want to quickly decode an entire FLAC file in one go you can do something like this:

    ```c
    unsigned int channels;
    unsigned int sampleRate;
    drflac_uint64 totalPCMFrameCount;
    drflac_int32* pSampleData = drflac_open_file_and_read_pcm_frames_s32("MySong.flac", &channels, &sampleRate, &totalPCMFrameCount, NULL);
    if (pSampleData == NULL) {
        // Failed to open and decode FLAC file.
    }

    ...

    drflac_free(pSampleData, NULL);
    ```

You can read samples as signed 16-bit integer and 32-bit floating-point PCM with the *_s16() and *_f32() family of APIs respectively, but note that these

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

The rationale for keeping these APIs separate is that they're slightly slower than the normal versions and also just a little bit harder to use. dr_flac
reports metadata to the application through the use of a callback, and every metadata block is reported before `drflac_open_with_metdata()` returns.

The main opening APIs (`drflac_open()`, etc.) will fail if the header is not present. The presents a problem in certain scenarios such as broadcast style
streams or internet radio where the header may not be present because the user has started playback mid-stream. To handle this, use the relaxed APIs:
    
    `drflac_open_relaxed()`
    `drflac_open_with_metadata_relaxed()`

It is not recommended to use these APIs for file based streams because a missing header would usually indicate a corrupt or perverse file. In addition, these
APIs can take a long time to initialize because they may need to spend a lot of time finding the first frame.



Build Options
=============
#define these options before including this file.

#define DR_FLAC_NO_STDIO
  Disable `drflac_open_file()` and family.

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

{
    drflac_seek_origin_start,
    drflac_seek_origin_current
} drflac_seek_origin;

/* Packing is important on this structure because we map this directly to the raw data within the SEEKTABLE metadata block. */
#pragma pack(2)
typedef struct
{
    drflac_uint64 firstPCMFrame;
    drflac_uint64 flacFrameOffset;   /* The offset from the first byte of the header of the first frame. */
    drflac_uint16 pcmFrameCount;
} drflac_seekpoint;
#pragma pack()

typedef struct
{
    drflac_uint16 minBlockSizeInPCMFrames;
    drflac_uint16 maxBlockSizeInPCMFrames;
    drflac_uint32 minFrameSizeInPCMFrames;
    drflac_uint32 maxFrameSizeInPCMFrames;

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

Return Value
------------
Whether or not the seek was successful.


Remarks
-------
The offset will never be negative. Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which will be
either drflac_seek_origin_start or drflac_seek_origin_current.

When seeking to a PCM frame using drflac_seek_to_pcm_frame(), dr_flac may call this with an offset beyond the end of the FLAC stream. This needs to be detected
and handled by returning DRFLAC_FALSE.
*/
typedef drflac_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin);

/*
Callback for when a metadata block is read.


Parameters
----------

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


    /*
    The cached data which was most recently read from the client. There are two levels of cache. Data flows as such:
    Client -> L2 -> L1. The L2 -> L1 movement is aligned and runs on a fast path in just a few instructions.
    */
    drflac_cache_t cacheL2[DR_FLAC_BUFFER_SIZE/sizeof(drflac_cache_t)];
    drflac_cache_t cache;

    /*
    CRC-16. This is updated whenever bits are read from the bit stream. Manually set this to 0 to reset the CRC. For FLAC, this
    is reset to 0 at the beginning of each frame.
    */
    drflac_uint16 crc16;
    drflac_cache_t crc16Cache;              /* A cache for optimizing CRC calculations. This is filled when when the L1 cache is reloaded. */
    drflac_uint32 crc16CacheIgnoredBytes;   /* The number of bytes to ignore when updating the CRC-16 from the CRC-16 cache. */
} drflac_bs;

typedef struct
{
    /* The type of the subframe: SUBFRAME_CONSTANT, SUBFRAME_VERBATIM, SUBFRAME_FIXED or SUBFRAME_LPC. */
    drflac_uint8 subframeType;

    /* The number of wasted bits per sample as specified by the sub-frame header. */
    drflac_uint8 wastedBitsPerSample;

    /* The order to use for the prediction stage for SUBFRAME_FIXED and SUBFRAME_LPC. */
    drflac_uint8 lpcOrder;

    /* A pointer to the buffer containing the decoded samples in the subframe. This pointer is an offset from drflac::pExtraData. */
    drflac_int32* pSamplesS32;
} drflac_subframe;

typedef struct
{
    /*
    If the stream uses variable block sizes, this will be set to the index of the first PCM frame. If fixed block sizes are used, this will
    always be set to 0. This is 64-bit because the decoded PCM frame number will be 36 bits.
    */
    drflac_uint64 pcmFrameNumber;

    /*
    If the stream uses fixed block sizes, this will be set to the frame number. If variable block sizes are used, this will always be 0. This
    is 32-bit because in fixed block sizes, the maximum frame number will be 31 bits.
    */
    drflac_uint32 flacFrameNumber;

    /* The sample rate of this frame. */
    drflac_uint32 sampleRate;

    /* The number of PCM frames in each sub-frame within this frame. */
    drflac_uint16 blockSizeInPCMFrames;

    /*
    The channel assignment of this frame. This is not always set to the channel count. If interchannel decorrelation is being used this
    will be set to DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE, DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE or DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE.
    */
    drflac_uint8 channelAssignment;

    /* The number of bits per sample within this frame. */
    drflac_uint8 bitsPerSample;

    /* The frame's CRC. */
    drflac_uint8 crc8;
} drflac_frame_header;

typedef struct
{
    /* The header. */
    drflac_frame_header header;

    /*
    The number of PCM frames left to be read in this FLAC frame. This is initially set to the block size. As PCM frames are read,
    this will be decremented. When it reaches 0, the decoder will see this frame as fully consumed and load the next frame.
    */
    drflac_uint32 pcmFramesRemaining;

    /* The list of sub-frames within the frame. There is one sub-frame for each channel, and there's a maximum of 8 channels. */
    drflac_subframe subframes[8];
} drflac_frame;

typedef struct
{
    /* The function to call when a metadata block is read. */
    drflac_meta_proc onMeta;

    /* The user data posted to the metadata callback function. */
    void* pUserDataMD;

    /* Memory allocation callbacks. */

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

    drflac_uint8 channels;

    /* The bits per sample. Will be set to something like 16, 24, etc. */
    drflac_uint8 bitsPerSample;

    /* The maximum block size, in samples. This number represents the number of samples in each channel (not combined). */
    drflac_uint16 maxBlockSizeInPCMFrames;

    /*
    The total number of PCM Frames making up the stream. Can be 0 in which case it's still a valid stream, but just means
    the total PCM frame count is unknown. Likely the case with streams like internet radio.
    */
    drflac_uint64 totalPCMFrameCount;


    /* The container type. This is set based on whether or not the decoder was opened from a native or Ogg stream. */
    drflac_container container;

    /* The number of seekpoints in the seektable. */
    drflac_uint32 seekpointCount;


    /* Information about the frame the decoder is currently sitting on. */
    drflac_frame currentFLACFrame;


    /* The index of the PCM frame the decoder is currently sitting on. This is only used for seeking. */
    drflac_uint64 currentPCMFrame;

    /* The position of the first FLAC frame in the stream. This is only ever used for seeking. */
    drflac_uint64 firstFLACFramePosInBytes;


    /* A hack to avoid a malloc() when opening a decoder with drflac_open_memory(). */
    drflac__memory_stream memoryStream;


    /* A pointer to the decoded sample data. This is an offset of pExtraData. */
    drflac_int32* pDecodedSamples;

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

A pointer to an object representing the decoder.


Remarks
-------
The same as drflac_open(), except attempts to open the stream even when a header block is not present.

Because the header is not necessarily available, the caller must explicitly define the container (Native or Ogg). Do not set this to `drflac_container_unknown`
as that is for internal use only.

Opening in relaxed mode will continue reading data from onRead until it finds a valid frame. If a frame is never found it will continue forever. To abort,
force your `onRead` callback to return 0, which dr_flac will use as an indicator that the end of the stream was found.

Use `drflac_open_with_metadata_relaxed()` if you need access to metadata.
*/
DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);

/*
Opens a FLAC decoder and notifies the caller of the metadata chunks (album art, etc.).


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


/*
Reads sample data from the given FLAC decoder, output as interleaved signed 32-bit PCM.


Parameters
----------
pFlac (in)
    The decoder.

framesToRead (in)
    The number of PCM frames to read.

pBufferOut (out, optional)
    A pointer to the buffer that will receive the decoded samples.


Return Value
------------
Returns the number of PCM frames actually read. If the return value is less than `framesToRead` it has reached the end.


Remarks
-------
pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames seeked.
*/
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut);


/*
Reads sample data from the given FLAC decoder, output as interleaved signed 16-bit PCM.


Parameters
----------
pFlac (in)
    The decoder.

framesToRead (in)
    The number of PCM frames to read.

pBufferOut (out, optional)
    A pointer to the buffer that will receive the decoded samples.


Return Value
------------
Returns the number of PCM frames actually read. If the return value is less than `framesToRead` it has reached the end.


Remarks
-------
pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames seeked.

Note that this is lossy for streams where the bits per sample is larger than 16.
*/
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut);

/*
Reads sample data from the given FLAC decoder, output as interleaved 32-bit floating point PCM.


Parameters
----------
pFlac (in)
    The decoder.

framesToRead (in)
    The number of PCM frames to read.

pBufferOut (out, optional)
    A pointer to the buffer that will receive the decoded samples.


Return Value
------------
Returns the number of PCM frames actually read. If the return value is less than `framesToRead` it has reached the end.


Remarks
-------
pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames seeked.

Note that this should be considered lossy due to the nature of floating point numbers not being able to exactly represent every possible number.
*/
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut);

/*
Seeks to the PCM frame at the given index.


Parameters
----------
pFlac (in)
    The decoder.

pcmFrameIndex (in)
    The index of the PCM frame to seek to. See notes below.


Return Value
-------------
`DRFLAC_TRUE` if successful; `DRFLAC_FALSE` otherwise.
*/
DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex);



#ifndef DR_FLAC_NO_STDIO
/*
Opens a FLAC decoder from the file at the given path.


Parameters
----------

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

pointer to the sample data as interleaved signed 32-bit PCM. The returned data must be freed with drflac_free().

You can pass in custom memory allocation callbacks via the pAllocationCallbacks parameter. This can be NULL in which
case it will use DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE.

Sometimes a FLAC file won't keep track of the total sample count. In this situation the function will continuously
read samples into a dynamically sized buffer on the heap until no samples are left.

Do not call this function on a broadcast type of stream (like internet radio streams and whatnot).
*/
DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pA...

/* Same as drflac_open_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pA...

/* Same as drflac_open_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocati...

#ifndef DR_FLAC_NO_STDIO
/* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a file. */
DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);

/* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);

/* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
#endif

/* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a block of memory. */
DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);

/* Same as drflac_open_memory_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
DRFLAC_API drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);

/* Same as drflac_open_memory_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
DRFLAC_API float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);

/*
Frees memory that was allocated internally by dr_flac.

Set pAllocationCallbacks to the same object that was passed to drflac_open_*_and_read_pcm_frames_*(). If you originally passed in NULL, pass in NULL for this.
*/
DRFLAC_API void drflac_free(void* p, const drflac_allocation_callbacks* pAllocationCallbacks);


/* Structure representing an iterator for vorbis comments in a VORBIS_COMMENT metadata block. */
typedef struct
{
    drflac_uint32 countRemaining;
    const char* pRunningData;
} drflac_vorbis_comment_iterator;

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

            }
            bitsToSeek = 0; /* <-- Necessary for the assert below. */
        }

        DRFLAC_ASSERT(bitsToSeek == 0);
        return DRFLAC_TRUE;
    }
}


/* This function moves the bit streamer to the first bit after the sync code (bit 15 of the of the frame header). It will also update the CRC-16. */
static drflac_bool32 drflac__find_and_seek_to_next_sync_code(drflac_bs* bs)
{
    DRFLAC_ASSERT(bs != NULL);

    /*
    The sync code is always aligned to 8 bits. This is convenient for us because it means we can do byte-aligned movements. The first
    thing to do is align to the next byte.
    */
    if (!drflac__seek_bits(bs, DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) {
        return DRFLAC_FALSE;

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

        } else {
            pSamplesOut[i] += drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + i);
        }
    }

    return DRFLAC_TRUE;
}


/*
Reads and decodes the residual for the sub-frame the decoder is currently sitting on. This function should be called
when the decoder is sitting at the very start of the RESIDUAL block. The first <order> residuals will be ignored. The
<blockSize> and <order> parameters are used to determine how many residual values need to be decoded.
*/
static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 blockSize, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* ...
{
    drflac_uint8 residualMethod;
    drflac_uint8 partitionOrder;
    drflac_uint32 samplesInPartition;
    drflac_uint32 partitionsRemaining;

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


        if (partitionOrder != 0) {
            samplesInPartition = blockSize / (1 << partitionOrder);
        }
    }

    return DRFLAC_TRUE;
}

/*
Reads and seeks past the residual for the sub-frame the decoder is currently sitting on. This function should be called
when the decoder is sitting at the very start of the RESIDUAL block. The first <order> residuals will be set to 0. The
<blockSize> and <order> parameters are used to determine how many residual values need to be decoded.
*/
static drflac_bool32 drflac__read_and_seek_residual(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 order)
{
    drflac_uint8 residualMethod;
    drflac_uint8 partitionOrder;
    drflac_uint32 samplesInPartition;
    drflac_uint32 partitionsRemaining;

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

        }

        partitionsRemaining -= 1;
        samplesInPartition = blockSize / (1 << partitionOrder);
    }

    return DRFLAC_TRUE;
}


static drflac_bool32 drflac__decode_samples__constant(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
{
    drflac_uint32 i;

    /* Only a single sample needs to be decoded here. */
    drflac_int32 sample;
    if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
        return DRFLAC_FALSE;
    }

    /*
    We don't really need to expand this, but it does simplify the process of reading samples. If this becomes a performance issue (unlikely)
    we'll want to look at a more efficient way.
    */
    for (i = 0; i < blockSize; ++i) {
        pDecodedSamples[i] = sample;
    }

    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
{
    drflac_uint32 i;

    for (i = 0; i < blockSize; ++i) {
        drflac_int32 sample;
        if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
            return DRFLAC_FALSE;
        }

        pDecodedSamples[i] = sample;
    }

    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__decode_samples__fixed(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
{
    drflac_uint32 i;

    static drflac_int32 lpcCoefficientsTable[5][4] = {
        {0,  0, 0,  0},
        {1,  0, 0,  0},
        {2, -1, 0,  0},
        {3, -3, 1,  0},
        {4, -6, 4, -1}
    };

    /* Warm up samples and coefficients. */
    for (i = 0; i < lpcOrder; ++i) {
        drflac_int32 sample;
        if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
            return DRFLAC_FALSE;
        }

        pDecodedSamples[i] = sample;
    }

    if (!drflac__decode_samples_with_residual(bs, subframeBitsPerSample, blockSize, lpcOrder, 0, 4, lpcCoefficientsTable[lpcOrder], pDecodedSamples)) {
        return DRFLAC_FALSE;
    }

    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__decode_samples__lpc(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
{
    drflac_uint8 i;
    drflac_uint8 lpcPrecision;

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

    }

    if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
        return DRFLAC_FALSE;
    }

    return DRFLAC_TRUE;
}


static drflac_bool32 drflac__read_next_flac_frame_header(drflac_bs* bs, drflac_uint8 streaminfoBitsPerSample, drflac_frame_header* header)
{
    const drflac_uint32 sampleRateTable[12]  = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
    const drflac_uint8 bitsPerSampleTable[8] = {0, 8, 12, (drflac_uint8)-1, 16, 20, 24, (drflac_uint8)-1};   /* -1 = reserved. */

    DRFLAC_ASSERT(bs != NULL);
    DRFLAC_ASSERT(header != NULL);

    /* Keep looping until we find a valid sync code. */
    for (;;) {
        drflac_uint8 crc8 = 0xCE; /* 0xCE = drflac_crc8(0, 0x3FFE, 14); */

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

                return DRFLAC_FALSE;
            }
            crc8 = drflac_crc8(crc8, header->blockSizeInPCMFrames, 8);
            header->blockSizeInPCMFrames += 1;
        } else if (blockSize == 7) {
            if (!drflac__read_uint16(bs, 16, &header->blockSizeInPCMFrames)) {
                return DRFLAC_FALSE;
            }
            crc8 = drflac_crc8(crc8, header->blockSizeInPCMFrames, 16);
            if (header->blockSizeInPCMFrames == 0xFFFF) {
                return DRFLAC_FALSE;    /* Frame is too big. This is the size of the frame minus 1. The STREAMINFO block defines the max block size which is 16-bits. Adding one will make it 17 bits and therefore too big. */
            }
            header->blockSizeInPCMFrames += 1;
        } else {
            DRFLAC_ASSERT(blockSize >= 8);
            header->blockSizeInPCMFrames = 256 * (1 << (blockSize - 8));
        }


        if (sampleRate <= 11) {
            header->sampleRate = sampleRateTable[sampleRate];

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



        header->channelAssignment = channelAssignment;

        header->bitsPerSample = bitsPerSampleTable[bitsPerSample];
        if (header->bitsPerSample == 0) {
            header->bitsPerSample = streaminfoBitsPerSample;
        }

        if (header->bitsPerSample != streaminfoBitsPerSample) {
            /* If this subframe has a different bitsPerSample then streaminfo or the first frame, reject it */
            return DRFLAC_FALSE;
        }

        if (!drflac__read_uint8(bs, 8, &header->crc8)) {
            return DRFLAC_FALSE;
        }

#ifndef DR_FLAC_NO_CRC
        if (header->crc8 != crc8) {
            continue;    /* CRC mismatch. Loop back to the top and find the next sync code. */
        }
#endif
        return DRFLAC_TRUE;
    }
}

static drflac_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe)
{
    drflac_uint8 header;
    int type;

    if (!drflac__read_uint8(bs, 8, &header)) {
        return DRFLAC_FALSE;
    }

    /* First bit should always be 0. */
    if ((header & 0x80) != 0) {
        return DRFLAC_FALSE;
    }

    type = (header & 0x7E) >> 1;
    if (type == 0) {
        pSubframe->subframeType = DRFLAC_SUBFRAME_CONSTANT;
    } else if (type == 1) {
        pSubframe->subframeType = DRFLAC_SUBFRAME_VERBATIM;
    } else {
        if ((type & 0x20) != 0) {
            pSubframe->subframeType = DRFLAC_SUBFRAME_LPC;
            pSubframe->lpcOrder = (drflac_uint8)(type & 0x1F) + 1;
        } else if ((type & 0x08) != 0) {
            pSubframe->subframeType = DRFLAC_SUBFRAME_FIXED;
            pSubframe->lpcOrder = (drflac_uint8)(type & 0x07);
            if (pSubframe->lpcOrder > 4) {
                pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED;
                pSubframe->lpcOrder = 0;
            }
        } else {
            pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED;
        }
    }

    if (pSubframe->subframeType == DRFLAC_SUBFRAME_RESERVED) {
        return DRFLAC_FALSE;
    }

    /* Wasted bits per sample. */
    pSubframe->wastedBitsPerSample = 0;
    if ((header & 0x01) == 1) {
        unsigned int wastedBitsPerSample;
        if (!drflac__seek_past_next_set_bit(bs, &wastedBitsPerSample)) {
            return DRFLAC_FALSE;
        }
        pSubframe->wastedBitsPerSample = (drflac_uint8)wastedBitsPerSample + 1;
    }

    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, drflac_int32* pDecodedSamplesOut)
{
    drflac_subframe* pSubframe;
    drflac_uint32 subframeBitsPerSample;

    DRFLAC_ASSERT(bs != NULL);
    DRFLAC_ASSERT(frame != NULL);

    pSubframe = frame->subframes + subframeIndex;
    if (!drflac__read_subframe_header(bs, pSubframe)) {
        return DRFLAC_FALSE;
    }

    /* Side channels require an extra bit per sample. Took a while to figure that one out... */
    subframeBitsPerSample = frame->header.bitsPerSample;
    if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
        subframeBitsPerSample += 1;
    } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
        subframeBitsPerSample += 1;
    }

    if (subframeBitsPerSample > 32) {
        /* libFLAC and ffmpeg reject 33-bit subframes as well */
        return DRFLAC_FALSE;
    }

    /* Need to handle wasted bits per sample. */
    if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
        return DRFLAC_FALSE;
    }
    subframeBitsPerSample -= pSubframe->wastedBitsPerSample;

    pSubframe->pSamplesS32 = pDecodedSamplesOut;

    switch (pSubframe->subframeType)
    {
        case DRFLAC_SUBFRAME_CONSTANT:
        {
            drflac__decode_samples__constant(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
        } break;

        case DRFLAC_SUBFRAME_VERBATIM:
        {
            drflac__decode_samples__verbatim(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
        } break;

        case DRFLAC_SUBFRAME_FIXED:
        {
            drflac__decode_samples__fixed(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
        } break;

        case DRFLAC_SUBFRAME_LPC:
        {
            drflac__decode_samples__lpc(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
        } break;

        default: return DRFLAC_FALSE;
    }

    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex)
{
    drflac_subframe* pSubframe;
    drflac_uint32 subframeBitsPerSample;

    DRFLAC_ASSERT(bs != NULL);
    DRFLAC_ASSERT(frame != NULL);

    pSubframe = frame->subframes + subframeIndex;
    if (!drflac__read_subframe_header(bs, pSubframe)) {
        return DRFLAC_FALSE;
    }

    /* Side channels require an extra bit per sample. Took a while to figure that one out... */
    subframeBitsPerSample = frame->header.bitsPerSample;
    if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
        subframeBitsPerSample += 1;
    } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
        subframeBitsPerSample += 1;
    }

    /* Need to handle wasted bits per sample. */
    if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
        return DRFLAC_FALSE;
    }
    subframeBitsPerSample -= pSubframe->wastedBitsPerSample;

    pSubframe->pSamplesS32 = NULL;

    switch (pSubframe->subframeType)
    {
        case DRFLAC_SUBFRAME_CONSTANT:
        {
            if (!drflac__seek_bits(bs, subframeBitsPerSample)) {
                return DRFLAC_FALSE;
            }
        } break;

        case DRFLAC_SUBFRAME_VERBATIM:
        {
            unsigned int bitsToSeek = frame->header.blockSizeInPCMFrames * subframeBitsPerSample;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }
        } break;

        case DRFLAC_SUBFRAME_FIXED:
        {
            unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }

            if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
                return DRFLAC_FALSE;
            }
        } break;

        case DRFLAC_SUBFRAME_LPC:
        {
            drflac_uint8 lpcPrecision;

            unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }

            if (!drflac__read_uint8(bs, 4, &lpcPrecision)) {
                return DRFLAC_FALSE;
            }
            if (lpcPrecision == 15) {
                return DRFLAC_FALSE;    /* Invalid. */
            }
            lpcPrecision += 1;


            bitsToSeek = (pSubframe->lpcOrder * lpcPrecision) + 5;    /* +5 for shift. */
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }

            if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
                return DRFLAC_FALSE;
            }
        } break;

        default: return DRFLAC_FALSE;
    }

    return DRFLAC_TRUE;
}


static DRFLAC_INLINE drflac_uint8 drflac__get_channel_count_from_channel_assignment(drflac_int8 channelAssignment)
{
    drflac_uint8 lookup[] = {1, 2, 3, 4, 5, 6, 7, 8, 2, 2, 2};

    DRFLAC_ASSERT(channelAssignment <= 10);
    return lookup[channelAssignment];
}

static drflac_result drflac__decode_flac_frame(drflac* pFlac)
{
    int channelCount;
    int i;
    drflac_uint8 paddingSizeInBits;
    drflac_uint16 desiredCRC16;
#ifndef DR_FLAC_NO_CRC
    drflac_uint16 actualCRC16;
#endif

    /* This function should be called while the stream is sitting on the first byte after the frame header. */
    DRFLAC_ZERO_MEMORY(pFlac->currentFLACFrame.subframes, sizeof(pFlac->currentFLACFrame.subframes));

    /* The frame block size must never be larger than the maximum block size defined by the FLAC stream. */
    if (pFlac->currentFLACFrame.header.blockSizeInPCMFrames > pFlac->maxBlockSizeInPCMFrames) {
        return DRFLAC_ERROR;
    }

    /* The number of channels in the frame must match the channel count from the STREAMINFO block. */
    channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
    if (channelCount != (int)pFlac->channels) {
        return DRFLAC_ERROR;
    }

    for (i = 0; i < channelCount; ++i) {
        if (!drflac__decode_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i, pFlac->pDecodedSamples + (pFlac->currentFLACFrame.header.blockSizeInPCMFrames * i))) {
            return DRFLAC_ERROR;
        }
    }

    paddingSizeInBits = (drflac_uint8)(DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7);
    if (paddingSizeInBits > 0) {
        drflac_uint8 padding = 0;
        if (!drflac__read_uint8(&pFlac->bs, paddingSizeInBits, &padding)) {
            return DRFLAC_AT_END;
        }

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

    if (actualCRC16 != desiredCRC16) {
        return DRFLAC_CRC_MISMATCH;    /* CRC mismatch. */
    }
#endif

    pFlac->currentFLACFrame.pcmFramesRemaining = pFlac->currentFLACFrame.header.blockSizeInPCMFrames;

    return DRFLAC_SUCCESS;
}

static drflac_result drflac__seek_flac_frame(drflac* pFlac)
{
    int channelCount;
    int i;
    drflac_uint16 desiredCRC16;
#ifndef DR_FLAC_NO_CRC
    drflac_uint16 actualCRC16;
#endif

    channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
    for (i = 0; i < channelCount; ++i) {
        if (!drflac__seek_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i)) {
            return DRFLAC_ERROR;
        }
    }

    /* Padding. */
    if (!drflac__seek_bits(&pFlac->bs, DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7)) {
        return DRFLAC_ERROR;
    }

    /* CRC. */

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


#ifndef DR_FLAC_NO_CRC
    if (actualCRC16 != desiredCRC16) {
        return DRFLAC_CRC_MISMATCH;    /* CRC mismatch. */
    }
#endif

    return DRFLAC_SUCCESS;
}

static drflac_bool32 drflac__read_and_decode_next_flac_frame(drflac* pFlac)
{
    DRFLAC_ASSERT(pFlac != NULL);

    for (;;) {
        drflac_result result;

        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }

        result = drflac__decode_flac_frame(pFlac);
        if (result != DRFLAC_SUCCESS) {
            if (result == DRFLAC_CRC_MISMATCH) {
                continue;   /* CRC mismatch. Skip to the next frame. */
            } else {
                return DRFLAC_FALSE;
            }
        }

        return DRFLAC_TRUE;
    }
}

static void drflac__get_pcm_frame_range_of_current_flac_frame(drflac* pFlac, drflac_uint64* pFirstPCMFrame, drflac_uint64* pLastPCMFrame)
{
    drflac_uint64 firstPCMFrame;
    drflac_uint64 lastPCMFrame;

    DRFLAC_ASSERT(pFlac != NULL);

    firstPCMFrame = pFlac->currentFLACFrame.header.pcmFrameNumber;
    if (firstPCMFrame == 0) {
        firstPCMFrame = ((drflac_uint64)pFlac->currentFLACFrame.header.flacFrameNumber) * pFlac->maxBlockSizeInPCMFrames;
    }

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

    }

    if (pFirstPCMFrame) {
        *pFirstPCMFrame = firstPCMFrame;
    }
    if (pLastPCMFrame) {
        *pLastPCMFrame = lastPCMFrame;
    }
}

static drflac_bool32 drflac__seek_to_first_frame(drflac* pFlac)
{
    drflac_bool32 result;

    DRFLAC_ASSERT(pFlac != NULL);

    result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes);

    DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
    pFlac->currentPCMFrame = 0;

    return result;
}

static DRFLAC_INLINE drflac_result drflac__seek_to_next_flac_frame(drflac* pFlac)
{
    /* This function should only ever be called while the decoder is sitting on the first byte past the FRAME_HEADER section. */
    DRFLAC_ASSERT(pFlac != NULL);
    return drflac__seek_flac_frame(pFlac);
}


static drflac_uint64 drflac__seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 pcmFramesToSeek)
{
    drflac_uint64 pcmFramesRead = 0;
    while (pcmFramesToSeek > 0) {
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;  /* Couldn't read the next frame, so just break from the loop and return. */
            }
        } else {
            if (pFlac->currentFLACFrame.pcmFramesRemaining > pcmFramesToSeek) {
                pcmFramesRead   += pcmFramesToSeek;
                pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)pcmFramesToSeek;   /* <-- Safe cast. Will always be < currentFrame.pcmFramesRemaining < 65536. */
                pcmFramesToSeek  = 0;
            } else {
                pcmFramesRead   += pFlac->currentFLACFrame.pcmFramesRemaining;
                pcmFramesToSeek -= pFlac->currentFLACFrame.pcmFramesRemaining;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
            }
        }
    }

    pFlac->currentPCMFrame += pcmFramesRead;
    return pcmFramesRead;
}


static drflac_bool32 drflac__seek_to_pcm_frame__brute_force(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_bool32 isMidFrame = DRFLAC_FALSE;
    drflac_uint64 runningPCMFrameCount;

    DRFLAC_ASSERT(pFlac != NULL);

    /* If we are seeking forward we start from the current position. Otherwise we need to start all the way from the start of the file. */
    if (pcmFrameIndex >= pFlac->currentPCMFrame) {
        /* Seeking forward. Need to seek from the current position. */
        runningPCMFrameCount = pFlac->currentPCMFrame;

        /* The frame header for the first frame may not yet have been read. We need to do that if necessary. */
        if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                return DRFLAC_FALSE;
            }
        } else {
            isMidFrame = DRFLAC_TRUE;
        }
    } else {
        /* Seeking backwards. Need to seek from the start of the file. */
        runningPCMFrameCount = 0;

        /* Move back to the start. */
        if (!drflac__seek_to_first_frame(pFlac)) {
            return DRFLAC_FALSE;
        }

        /* Decode the first frame in preparation for sample-exact seeking below. */
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }

    /*
    We need to as quickly as possible find the frame that contains the target sample. To do this, we iterate over each frame and inspect its
    header. If based on the header we can determine that the frame contains the sample, we do a full decode of that frame.
    */
    for (;;) {
        drflac_uint64 pcmFrameCountInThisFLACFrame;
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
        drflac_uint64 lastPCMFrameInFLACFrame = 0;

        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);

        pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
            /*
            The sample should be in this frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend
            it never existed and keep iterating.
            */
            drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;

            if (!isMidFrame) {
                drflac_result result = drflac__decode_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
                    return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;  /* <-- If this fails, something bad has happened (it should never fail). */
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;   /* CRC mismatch. Pretend this frame never existed. */
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                /* We started seeking mid-frame which means we need to skip the frame decoding part. */
                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
            }
        } else {
            /*
            It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
            frame never existed and leave the running sample count untouched.
            */
            if (!isMidFrame) {
                drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;   /* CRC mismatch. Pretend this frame never existed. */
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                /*
                We started seeking mid-frame which means we need to seek by reading to the end of the frame instead of with
                drflac__seek_to_next_flac_frame() which only works if the decoder is sitting on the byte just after the frame header.
                */
                runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
                isMidFrame = DRFLAC_FALSE;
            }

            /* If we are seeking to the end of the file and we've just hit it, we're done. */
            if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
                return DRFLAC_TRUE;
            }
        }

    next_iteration:
        /* Grab the next frame in preparation for the next iteration. */
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }
}


#if !defined(DR_FLAC_NO_CRC)
/*
We use an average compression ratio to determine our approximate start location. FLAC files are generally about 50%-70% the size of their
uncompressed counterparts so we'll use this as a basis. I'm going to split the middle and use a factor of 0.6 to determine the starting
location.
*/
#define DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO 0.6f

static drflac_bool32 drflac__seek_to_approximate_flac_frame_to_byte(drflac* pFlac, drflac_uint64 targetByte, drflac_uint64 rangeLo, drflac_uint64 rangeHi, drflac_uint64* pLastSuccessfulSeekOffset)
{
    DRFLAC_ASSERT(pFlac != NULL);
    DRFLAC_ASSERT(pLastSuccessfulSeekOffset != NULL);
    DRFLAC_ASSERT(targetByte >= rangeLo);
    DRFLAC_ASSERT(targetByte <= rangeHi);

    *pLastSuccessfulSeekOffset = pFlac->firstFLACFramePosInBytes;

    for (;;) {
        /* After rangeLo == rangeHi == targetByte fails, we need to break out. */
        drflac_uint64 lastTargetByte = targetByte;

        /* When seeking to a byte, failure probably means we've attempted to seek beyond the end of the stream. To counter this we just halve it each attempt. */
        if (!drflac__seek_to_byte(&pFlac->bs, targetByte)) {
            /* If we couldn't even seek to the first byte in the stream we have a problem. Just abandon the whole thing. */
            if (targetByte == 0) {
                drflac__seek_to_first_frame(pFlac); /* Try to recover. */
                return DRFLAC_FALSE;
            }

            /* Halve the byte location and continue. */
            targetByte = rangeLo + ((rangeHi - rangeLo)/2);
            rangeHi = targetByte;
        } else {
            /* Getting here should mean that we have seeked to an appropriate byte. */

            /* Clear the details of the FLAC frame so we don't misreport data. */
            DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));

            /*
            Now seek to the next FLAC frame. We need to decode the entire frame (not just the header) because it's possible for the header to incorrectly pass the
            CRC check and return bad data. We need to decode the entire frame to be more certain. Although this seems unlikely, this has happened to me in testing
            so it needs to stay this way for now.
            */
#if 1
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                /* Halve the byte location and continue. */
                targetByte = rangeLo + ((rangeHi - rangeLo)/2);
                rangeHi = targetByte;
            } else {
                break;
            }
#else
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                /* Halve the byte location and continue. */
                targetByte = rangeLo + ((rangeHi - rangeLo)/2);
                rangeHi = targetByte;
            } else {
                break;
            }
#endif
        }

        /* We already tried this byte and there are no more to try, break out. */
        if(targetByte == lastTargetByte) {
            return DRFLAC_FALSE;
        }
    }

    /* The current PCM frame needs to be updated based on the frame we just seeked to. */
    drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);

    DRFLAC_ASSERT(targetByte <= rangeHi);

    *pLastSuccessfulSeekOffset = targetByte;
    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 offset)
{
    /* This section of code would be used if we were only decoding the FLAC frame header when calling drflac__seek_to_approximate_flac_frame_to_byte(). */
#if 0
    if (drflac__decode_flac_frame(pFlac) != DRFLAC_SUCCESS) {
        /* We failed to decode this frame which may be due to it being corrupt. We'll just use the next valid FLAC frame. */
        if (drflac__read_and_decode_next_flac_frame(pFlac) == DRFLAC_FALSE) {
            return DRFLAC_FALSE;
        }
    }
#endif

    return drflac__seek_forward_by_pcm_frames(pFlac, offset) == offset;
}


static drflac_bool32 drflac__seek_to_pcm_frame__binary_search_internal(drflac* pFlac, drflac_uint64 pcmFrameIndex, drflac_uint64 byteRangeLo, drflac_uint64 byteRangeHi)
{
    /* This assumes pFlac->currentPCMFrame is sitting on byteRangeLo upon entry. */

    drflac_uint64 targetByte;
    drflac_uint64 pcmRangeLo = pFlac->totalPCMFrameCount;
    drflac_uint64 pcmRangeHi = 0;
    drflac_uint64 lastSuccessfulSeekOffset = (drflac_uint64)-1;
    drflac_uint64 closestSeekOffsetBeforeTargetPCMFrame = byteRangeLo;
    drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;

    targetByte = byteRangeLo + (drflac_uint64)(((drflac_int64)((pcmFrameIndex - pFlac->currentPCMFrame) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO);
    if (targetByte > byteRangeHi) {
        targetByte = byteRangeHi;
    }

    for (;;) {
        if (drflac__seek_to_approximate_flac_frame_to_byte(pFlac, targetByte, byteRangeLo, byteRangeHi, &lastSuccessfulSeekOffset)) {
            /* We found a FLAC frame. We need to check if it contains the sample we're looking for. */
            drflac_uint64 newPCMRangeLo;
            drflac_uint64 newPCMRangeHi;
            drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &newPCMRangeLo, &newPCMRangeHi);

            /* If we selected the same frame, it means we should be pretty close. Just decode the rest. */
            if (pcmRangeLo == newPCMRangeLo) {
                if (!drflac__seek_to_approximate_flac_frame_to_byte(pFlac, closestSeekOffsetBeforeTargetPCMFrame, closestSeekOffsetBeforeTargetPCMFrame, byteRangeHi, &lastSuccessfulSeekOffset)) {
                    break;  /* Failed to seek to closest frame. */
                }

                if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
                    return DRFLAC_TRUE;
                } else {
                    break;  /* Failed to seek forward. */
                }
            }

            pcmRangeLo = newPCMRangeLo;
            pcmRangeHi = newPCMRangeHi;

            if (pcmRangeLo <= pcmFrameIndex && pcmRangeHi >= pcmFrameIndex) {
                /* The target PCM frame is in this FLAC frame. */
                if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame) ) {
                    return DRFLAC_TRUE;
                } else {
                    break;  /* Failed to seek to FLAC frame. */
                }
            } else {
                const float approxCompressionRatio = (drflac_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / ((drflac_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0f);

                if (pcmRangeLo > pcmFrameIndex) {
                    /* We seeked too far forward. We need to move our target byte backward and try again. */
                    byteRangeHi = lastSuccessfulSeekOffset;
                    if (byteRangeLo > byteRangeHi) {
                        byteRangeLo = byteRangeHi;
                    }

                    targetByte = byteRangeLo + ((byteRangeHi - byteRangeLo) / 2);
                    if (targetByte < byteRangeLo) {
                        targetByte = byteRangeLo;
                    }
                } else /*if (pcmRangeHi < pcmFrameIndex)*/ {
                    /* We didn't seek far enough. We need to move our target byte forward and try again. */

                    /* If we're close enough we can just seek forward. */
                    if ((pcmFrameIndex - pcmRangeLo) < seekForwardThreshold) {
                        if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
                            return DRFLAC_TRUE;
                        } else {
                            break;  /* Failed to seek to FLAC frame. */
                        }
                    } else {
                        byteRangeLo = lastSuccessfulSeekOffset;
                        if (byteRangeHi < byteRangeLo) {
                            byteRangeHi = byteRangeLo;
                        }

                        targetByte = lastSuccessfulSeekOffset + (drflac_uint64)(((drflac_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * approxCompressionRatio);
                        if (targetByte > byteRangeHi) {
                            targetByte = byteRangeHi;
                        }

                        if (closestSeekOffsetBeforeTargetPCMFrame < lastSuccessfulSeekOffset) {
                            closestSeekOffsetBeforeTargetPCMFrame = lastSuccessfulSeekOffset;
                        }
                    }
                }
            }
        } else {
            /* Getting here is really bad. We just recover as best we can, but moving to the first frame in the stream, and then abort. */
            break;
        }
    }

    drflac__seek_to_first_frame(pFlac); /* <-- Try to recover. */
    return DRFLAC_FALSE;
}

static drflac_bool32 drflac__seek_to_pcm_frame__binary_search(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_uint64 byteRangeLo;
    drflac_uint64 byteRangeHi;
    drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;

    /* Our algorithm currently assumes the FLAC stream is currently sitting at the start. */
    if (drflac__seek_to_first_frame(pFlac) == DRFLAC_FALSE) {
        return DRFLAC_FALSE;
    }

    /* If we're close enough to the start, just move to the start and seek forward. */
    if (pcmFrameIndex < seekForwardThreshold) {
        return drflac__seek_forward_by_pcm_frames(pFlac, pcmFrameIndex) == pcmFrameIndex;
    }

    /*
    Our starting byte range is the byte position of the first FLAC frame and the approximate end of the file as if it were completely uncompressed. This ensures
    the entire file is included, even though most of the time it'll exceed the end of the actual stream. This is OK as the frame searching logic will handle it.
    */
    byteRangeLo = pFlac->firstFLACFramePosInBytes;
    byteRangeHi = pFlac->firstFLACFramePosInBytes + (drflac_uint64)((drflac_int64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample)/8.0f);

    return drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi);
}
#endif  /* !DR_FLAC_NO_CRC */

static drflac_bool32 drflac__seek_to_pcm_frame__seek_table(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_uint32 iClosestSeekpoint = 0;
    drflac_bool32 isMidFrame = DRFLAC_FALSE;
    drflac_uint64 runningPCMFrameCount;
    drflac_uint32 iSeekpoint;


    DRFLAC_ASSERT(pFlac != NULL);

    if (pFlac->pSeekpoints == NULL || pFlac->seekpointCount == 0) {

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

            if (pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset >= pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset || pFlac->pSeekpoints[iNextSeekpoint].pcmFrameCount == 0) {
                return DRFLAC_FALSE;    /* The next seekpoint doesn't look right. The seek table cannot be trusted from here. Abort. */
            }

            if (pFlac->pSeekpoints[iNextSeekpoint].firstPCMFrame != (((drflac_uint64)0xFFFFFFFF << 32) | 0xFFFFFFFF)) { /* Make sure it's not a placeholder seekpoint. */
                byteRangeHi = pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset - 1; /* byteRangeHi must be zero based. */
            }
        }

        if (drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
            if (drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);

                if (drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi)) {
                    return DRFLAC_TRUE;
                }
            }
        }
    }
#endif  /* !DR_FLAC_NO_CRC */

    /* Getting here means we need to use a slower algorithm because the binary search method failed or cannot be used. */

    /*
    If we are seeking forward and the closest seekpoint is _before_ the current sample, we just seek forward from where we are. Otherwise we start seeking
    from the seekpoint's first sample.
    */
    if (pcmFrameIndex >= pFlac->currentPCMFrame && pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame <= pFlac->currentPCMFrame) {
        /* Optimized case. Just seek forward from where we are. */
        runningPCMFrameCount = pFlac->currentPCMFrame;

        /* The frame header for the first frame may not yet have been read. We need to do that if necessary. */
        if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                return DRFLAC_FALSE;
            }
        } else {
            isMidFrame = DRFLAC_TRUE;
        }
    } else {
        /* Slower case. Seek to the start of the seekpoint and then seek forward from there. */
        runningPCMFrameCount = pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame;

        if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
            return DRFLAC_FALSE;
        }

        /* Grab the frame the seekpoint is sitting on in preparation for the sample-exact seeking below. */
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }

    for (;;) {
        drflac_uint64 pcmFrameCountInThisFLACFrame;
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
        drflac_uint64 lastPCMFrameInFLACFrame = 0;

        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);

        pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
            /*
            The sample should be in this frame. We need to fully decode it, but if it's an invalid frame (a CRC mismatch) we need to pretend
            it never existed and keep iterating.
            */
            drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;

            if (!isMidFrame) {
                drflac_result result = drflac__decode_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
                    return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;  /* <-- If this fails, something bad has happened (it should never fail). */
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;   /* CRC mismatch. Pretend this frame never existed. */
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                /* We started seeking mid-frame which means we need to skip the frame decoding part. */
                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
            }
        } else {
            /*
            It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
            frame never existed and leave the running sample count untouched.
            */
            if (!isMidFrame) {
                drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;   /* CRC mismatch. Pretend this frame never existed. */
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                /*
                We started seeking mid-frame which means we need to seek by reading to the end of the frame instead of with
                drflac__seek_to_next_flac_frame() which only works if the decoder is sitting on the byte just after the frame header.
                */
                runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
                isMidFrame = DRFLAC_FALSE;
            }

            /* If we are seeking to the end of the file and we've just hit it, we're done. */
            if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
                return DRFLAC_TRUE;
            }
        }

    next_iteration:
        /* Grab the next frame in preparation for the next iteration. */
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }
}


#ifndef DR_FLAC_NO_OGG
typedef struct
{
    drflac_uint8 capturePattern[4];  /* Should be "OggS" */

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

    void* pUserDataMD;
    drflac_uint32 sampleRate;
    drflac_uint8  channels;
    drflac_uint8  bitsPerSample;
    drflac_uint64 totalPCMFrameCount;
    drflac_uint16 maxBlockSizeInPCMFrames;
    drflac_uint64 runningFilePos;
    drflac_bool32 hasStreamInfoBlock;
    drflac_bool32 hasMetadataBlocks;
    drflac_bs bs;                           /* <-- A bit streamer is required for loading data during initialization. */
    drflac_frame_header firstFrameHeader;   /* <-- The header of the first frame that was read during relaxed initalization. Only set if there is no STREAMINFO block. */

#ifndef DR_FLAC_NO_OGG
    drflac_uint32 oggSerial;
    drflac_uint64 oggFirstBytePos;
    drflac_ogg_page_header oggBosHeader;
#endif
} drflac_init_info;

static DRFLAC_INLINE void drflac__decode_block_header(drflac_uint32 blockHeader, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize)
{

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

        return DRFLAC_FALSE;
    }

    drflac__decode_block_header(blockHeader, isLastBlock, blockType, blockSize);
    return DRFLAC_TRUE;
}

static drflac_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo)
{
    drflac_uint32 blockSizes;
    drflac_uint64 frameSizes = 0;
    drflac_uint64 importantProps;
    drflac_uint8 md5[16];

    /* min/max block size. */
    if (onRead(pUserData, &blockSizes, 4) != 4) {
        return DRFLAC_FALSE;
    }

    /* min/max frame size. */
    if (onRead(pUserData, &frameSizes, 6) != 6) {
        return DRFLAC_FALSE;
    }

    /* Sample rate, channels, bits per sample and total sample count. */
    if (onRead(pUserData, &importantProps, 8) != 8) {
        return DRFLAC_FALSE;
    }

    /* MD5 */
    if (onRead(pUserData, md5, sizeof(md5)) != sizeof(md5)) {
        return DRFLAC_FALSE;
    }

    blockSizes     = drflac__be2host_32(blockSizes);
    frameSizes     = drflac__be2host_64(frameSizes);
    importantProps = drflac__be2host_64(importantProps);

    pStreamInfo->minBlockSizeInPCMFrames = (drflac_uint16)((blockSizes & 0xFFFF0000) >> 16);
    pStreamInfo->maxBlockSizeInPCMFrames = (drflac_uint16) (blockSizes & 0x0000FFFF);
    pStreamInfo->minFrameSizeInPCMFrames = (drflac_uint32)((frameSizes     &  (((drflac_uint64)0x00FFFFFF << 16) << 24)) >> 40);
    pStreamInfo->maxFrameSizeInPCMFrames = (drflac_uint32)((frameSizes     &  (((drflac_uint64)0x00FFFFFF << 16) <<  0)) >> 16);
    pStreamInfo->sampleRate              = (drflac_uint32)((importantProps &  (((drflac_uint64)0x000FFFFF << 16) << 28)) >> 44);
    pStreamInfo->channels                = (drflac_uint8 )((importantProps &  (((drflac_uint64)0x0000000E << 16) << 24)) >> 41) + 1;
    pStreamInfo->bitsPerSample           = (drflac_uint8 )((importantProps &  (((drflac_uint64)0x0000001F << 16) << 20)) >> 36) + 1;
    pStreamInfo->totalPCMFrameCount      =                ((importantProps & ((((drflac_uint64)0x0000000F << 16) << 16) | 0xFFFFFFFF)));
    DRFLAC_COPY_MEMORY(pStreamInfo->md5, md5, sizeof(md5));

    return DRFLAC_TRUE;
}


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

    if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
        return DRFLAC_FALSE;
    }

    if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) {
        if (!relaxed) {
            /* We're opening in strict mode and the first block is not the STREAMINFO block. Error. */
            return DRFLAC_FALSE;
        } else {
            /*
            Relaxed mode. To open from here we need to just find the first frame and set the sample rate, etc. to whatever is defined
            for that frame.
            */
            pInit->hasStreamInfoBlock = DRFLAC_FALSE;
            pInit->hasMetadataBlocks  = DRFLAC_FALSE;

            if (!drflac__read_next_flac_frame_header(&pInit->bs, 0, &pInit->firstFrameHeader)) {
                return DRFLAC_FALSE;    /* Couldn't find a frame. */
            }

            if (pInit->firstFrameHeader.bitsPerSample == 0) {
                return DRFLAC_FALSE;    /* Failed to initialize because the first frame depends on the STREAMINFO block, which does not exist. */
            }

            pInit->sampleRate              = pInit->firstFrameHeader.sampleRate;
            pInit->channels                = drflac__get_channel_count_from_channel_assignment(pInit->firstFrameHeader.channelAssignment);
            pInit->bitsPerSample           = pInit->firstFrameHeader.bitsPerSample;
            pInit->maxBlockSizeInPCMFrames = 65535;   /* <-- See notes here: https://xiph.org/flac/format.html#metadata_block_streaminfo */
            return DRFLAC_TRUE;
        }
    } else {
        drflac_streaminfo streaminfo;

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

            if ((oggbs->currentPageHeader.headerType & 0x01) == 0) {
                return DRFLAC_TRUE;
            }
        } else {
            /* We're at the next packet. */
            return DRFLAC_TRUE;
        }
    }
}

static drflac_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs)
{
    /* The bitstream should be sitting on the first byte just after the header of the frame. */

    /* What we're actually doing here is seeking to the start of the next packet. */
    return drflac_oggbs__seek_to_next_packet(oggbs);
}
#endif

static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytesToRead)
{
    drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
    drflac_uint8* pRunningBufferOut = (drflac_uint8*)bufferOut;

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

        if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
            /* Failed to go to the next page. We either hit the end of the stream or had a CRC mismatch. */
            return DRFLAC_FALSE;
        }
    }

    return DRFLAC_TRUE;
}


static drflac_bool32 drflac_ogg__seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
    drflac_uint64 originalBytePos;
    drflac_uint64 runningGranulePosition;
    drflac_uint64 runningFrameBytePos;
    drflac_uint64 runningPCMFrameCount;

    DRFLAC_ASSERT(oggbs != NULL);

    originalBytePos = oggbs->currentBytePos;   /* For recovery. Points to the OggS identifier. */

    /* First seek to the first frame. */
    if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes)) {
        return DRFLAC_FALSE;
    }
    oggbs->bytesRemainingInPage = 0;

    runningGranulePosition = 0;
    for (;;) {
        if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
            drflac_oggbs__seek_physical(oggbs, originalBytePos, drflac_seek_origin_start);
            return DRFLAC_FALSE;   /* Never did find that sample... */

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

        /*
        At this point we know the sample is not in the previous page. It could possibly be in this page. For simplicity we
        disregard any pages that do not begin a fresh packet.
        */
        if ((oggbs->currentPageHeader.headerType & 0x01) == 0) {    /* <-- Is it a fresh page? */
            if (oggbs->currentPageHeader.segmentTable[0] >= 2) {
                drflac_uint8 firstBytesInPage[2];
                firstBytesInPage[0] = oggbs->pageData[0];
                firstBytesInPage[1] = oggbs->pageData[1];

                if ((firstBytesInPage[0] == 0xFF) && (firstBytesInPage[1] & 0xFC) == 0xF8) {    /* <-- Does the page begin with a frame's sync code? */
                    runningGranulePosition = oggbs->currentPageHeader.granulePosition;
                }

                continue;
            }
        }
    }

    /*
    We found the page that that is closest to the sample, so now we need to find it. The first thing to do is seek to the
    start of that page. In the loop above we checked that it was a fresh page which means this page is also the start of
    a new frame. This property means that after we've seeked to the page we can immediately start looping over frames until
    we find the one containing the target sample.
    */
    if (!drflac_oggbs__seek_physical(oggbs, runningFrameBytePos, drflac_seek_origin_start)) {
        return DRFLAC_FALSE;
    }
    if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
        return DRFLAC_FALSE;
    }

    /*
    At this point we'll be sitting on the first byte of the frame header of the first frame in the page. We just keep
    looping over these frames until we find the one containing the sample we're after.
    */
    runningPCMFrameCount = runningGranulePosition;
    for (;;) {
        /*
        There are two ways to find the sample and seek past irrelevant frames:
          1) Use the native FLAC decoder.
          2) Use Ogg's framing system.

        Both of these options have their own pros and cons. Using the native FLAC decoder is slower because it needs to
        do a full decode of the frame. Using Ogg's framing system is faster, but more complicated and involves some code
        duplication for the decoding of frame headers.

        Another thing to consider is that using the Ogg framing system will perform direct seeking of the physical Ogg
        bitstream. This is important to consider because it means we cannot read data from the drflac_bs object using the
        standard drflac__*() APIs because that will read in extra data for its own internal caching which in turn breaks
        the positioning of the read pointer of the physical Ogg bitstream. Therefore, anything that would normally be read
        using the native FLAC decoding APIs, such as drflac__read_next_flac_frame_header(), need to be re-implemented so as to
        avoid the use of the drflac_bs object.

        Considering these issues, I have decided to use the slower native FLAC decoding method for the following reasons:
          1) Seeking is already partially accelerated using Ogg's paging system in the code block above.
          2) Seeking in an Ogg encapsulated FLAC stream is probably quite uncommon.
          3) Simplicity.
        */
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
        drflac_uint64 lastPCMFrameInFLACFrame = 0;
        drflac_uint64 pcmFrameCountInThisFrame;

        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }

        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);

        pcmFrameCountInThisFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;

        /* If we are seeking to the end of the file and we've just hit it, we're done. */
        if (pcmFrameIndex == pFlac->totalPCMFrameCount && (runningPCMFrameCount + pcmFrameCountInThisFrame) == pFlac->totalPCMFrameCount) {
            drflac_result result = drflac__decode_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                pFlac->currentPCMFrame = pcmFrameIndex;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
                return DRFLAC_TRUE;
            } else {
                return DRFLAC_FALSE;
            }
        }

        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFrame)) {
            /*
            The sample should be in this FLAC frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend
            it never existed and keep iterating.
            */
            drflac_result result = drflac__decode_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
                drflac_uint64 pcmFramesToDecode = (size_t)(pcmFrameIndex - runningPCMFrameCount);    /* <-- Safe cast because the maximum number of samples in a frame is 65535. */
                if (pcmFramesToDecode == 0) {
                    return DRFLAC_TRUE;
                }

                pFlac->currentPCMFrame = runningPCMFrameCount;

                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;  /* <-- If this fails, something bad has happened (it should never fail). */
            } else {
                if (result == DRFLAC_CRC_MISMATCH) {
                    continue;   /* CRC mismatch. Pretend this frame never existed. */
                } else {
                    return DRFLAC_FALSE;
                }
            }
        } else {
            /*
            It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
            frame never existed and leave the running sample count untouched.
            */
            drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                runningPCMFrameCount += pcmFrameCountInThisFrame;
            } else {
                if (result == DRFLAC_CRC_MISMATCH) {
                    continue;   /* CRC mismatch. Pretend this frame never existed. */
                } else {
                    return DRFLAC_FALSE;
                }
            }
        }
    }
}



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

        allocationCallbacks.pUserData = NULL;
        allocationCallbacks.onMalloc  = drflac__malloc_default;
        allocationCallbacks.onRealloc = drflac__realloc_default;
        allocationCallbacks.onFree    = drflac__free_default;
    }


    /*
    The size of the allocation for the drflac object needs to be large enough to fit the following:
      1) The main members of the drflac structure
      2) A block of memory large enough to store the decoded samples of the largest frame in the stream
      3) If the container is Ogg, a drflac_oggbs object

    The complicated part of the allocation is making sure there's enough room the decoded samples, taking into consideration
    the different SIMD instruction sets.
    */
    allocationSize = sizeof(drflac);

    /*
    The allocation size for decoded frames depends on the number of 32-bit integers that fit inside the largest SIMD vector
    we are supporting.
    */
    if ((init.maxBlockSizeInPCMFrames % (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) == 0) {
        wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32)));
    } else {
        wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) + 1;
    }

    decodedSamplesAllocationSize = wholeSIMDVectorCountPerChannel * DRFLAC_MAX_SIMD_VECTOR_SIZE * init.channels;

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

                /* Failed to seek to the seektable. Ominous sign, but for now we can just pretend we don't have one. */
                pFlac->pSeekpoints = NULL;
                pFlac->seekpointCount = 0;
            }
        }
    }


    /*
    If we get here, but don't have a STREAMINFO block, it means we've opened the stream in relaxed mode and need to decode
    the first frame.
    */
    if (!init.hasStreamInfoBlock) {
        pFlac->currentFLACFrame.header = init.firstFrameHeader;
        for (;;) {
            drflac_result result = drflac__decode_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                break;
            } else {
                if (result == DRFLAC_CRC_MISMATCH) {
                    if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                        drflac__free_from_callbacks(pFlac, &allocationCallbacks);
                        return NULL;
                    }
                    continue;
                } else {
                    drflac__free_from_callbacks(pFlac, &allocationCallbacks);
                    return NULL;
                }
            }
        }

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

        }
    }
#endif
#endif

    drflac__free_from_callbacks(pFlac, &pFlac->allocationCallbacks);
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutpu...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int32)left0;
        pOutputSamples[i*8+1] = (drflac_int32)right0;
        pOutputSamples[i*8+2] = (drflac_int32)left1;
        pOutputSamples[i*8+3] = (drflac_int32)right1;
        pOutputSamples[i*8+4] = (drflac_int32)left2;
        pOutputSamples[i*8+5] = (drflac_int32)right2;
        pOutputSamples[i*8+6] = (drflac_int32)left3;
        pOutputSamples[i*8+7] = (drflac_int32)right3;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i right = _mm_sub_epi32(left, side);

        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t left;
        uint32x4_t side;
        uint32x4_t right;

        left  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        right = vsubq_u32(left, side);

        drflac__vst2q_u32((drflac_uint32*)pOutputSamples + i*8, vzipq_u32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutp...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputS...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int32)left0;
        pOutputSamples[i*8+1] = (drflac_int32)right0;
        pOutputSamples[i*8+2] = (drflac_int32)left1;
        pOutputSamples[i*8+3] = (drflac_int32)right1;
        pOutputSamples[i*8+4] = (drflac_int32)left2;
        pOutputSamples[i*8+5] = (drflac_int32)right2;
        pOutputSamples[i*8+6] = (drflac_int32)left3;
        pOutputSamples[i*8+7] = (drflac_int32)right3;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    for (i = 0; i < frameCount4; ++i) {
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i left  = _mm_add_epi32(right, side);

        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t side;
        uint32x4_t right;
        uint32x4_t left;

        side  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        right = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        left  = vaddq_u32(right, side);

        drflac__vst2q_u32((drflac_uint32*)pOutputSamples + i*8, vzipq_u32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutput...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

        mid = (mid << 1) | (side & 0x01);

        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_int32 shift = unusedBitsPerSample;

    if (shift > 0) {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;

            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;

            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);

            temp0L = (mid0 + side0) << shift;
            temp1L = (mid1 + side1) << shift;
            temp2L = (mid2 + side2) << shift;
            temp3L = (mid3 + side3) << shift;

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

            pOutputSamples[i*8+0] = (drflac_int32)temp0L;
            pOutputSamples[i*8+1] = (drflac_int32)temp0R;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R;
        }
    } else {
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;

            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;

            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);

            temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
            temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
            temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
            temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);

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

            pOutputSamples[i*8+1] = (drflac_int32)temp0R;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R;
        }
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

        mid = (mid << 1) | (side & 0x01);

        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_int32 shift = unusedBitsPerSample;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;

            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));

            left  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
            right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);

            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int32)(mid + side) >> 1;
            pOutputSamples[i*2+1] = (drflac_int32)(mid - side) >> 1;
        }
    } else {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;

            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));

            left  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
            right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);

            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
        }
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_int32 shift = unusedBitsPerSample;
    int32x4_t  wbpsShift0_4; /* wbps = Wasted Bits Per Sample */
    int32x4_t  wbpsShift1_4; /* wbps = Wasted Bits Per Sample */
    uint32x4_t one4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
    wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
    one4         = vdupq_n_u32(1);

    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;

            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);

            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, one4));

            left  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
            right = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);

            drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int32)(mid + side) >> 1;
            pOutputSamples[i*2+1] = (drflac_int32)(mid - side) >> 1;
        }
    } else {
        int32x4_t shift4;

        shift -= 1;
        shift4 = vdupq_n_s32(shift);

        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;

            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);

            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, one4));

            left  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
            right = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));

            drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
        }
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int3...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample));
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample));
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* ...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;

        pOutputSamples[i*8+0] = (drflac_int32)tempL0;
        pOutputSamples[i*8+1] = (drflac_int32)tempR0;
        pOutputSamples[i*8+2] = (drflac_int32)tempL1;
        pOutputSamples[i*8+3] = (drflac_int32)tempR1;
        pOutputSamples[i*8+4] = (drflac_int32)tempL2;
        pOutputSamples[i*8+5] = (drflac_int32)tempR2;
        pOutputSamples[i*8+6] = (drflac_int32)tempL3;
        pOutputSamples[i*8+7] = (drflac_int32)tempR3;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);

        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    int32x4_t shift4_0 = vdupq_n_s32(shift0);
    int32x4_t shift4_1 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        int32x4_t left;
        int32x4_t right;

        left  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift4_0));
        right = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift4_1));

        drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputS...
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut)
{
    drflac_uint64 framesRead;
    drflac_uint32 unusedBitsPerSample;

    if (pFlac == NULL || framesToRead == 0) {
        return 0;
    }

    if (pBufferOut == NULL) {
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
    }

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;

    framesRead = 0;
    while (framesToRead > 0) {
        /* If we've run out of samples in this frame, go to the next. */
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;  /* Couldn't read the next frame, so just break from the loop and return. */
            }
        } else {
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
            drflac_uint64 frameCountThisIteration = framesToRead;

            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
            }

            if (channelCount == 2) {
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;

                switch (pFlac->currentFLACFrame.header.channelAssignment)
                {
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
                    {
                        drflac_read_pcm_frames_s32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
                    {
                        drflac_read_pcm_frames_s32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
                    {
                        drflac_read_pcm_frames_s32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
                    default:
                    {
                        drflac_read_pcm_frames_s32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                }
            } else {
                /* Generic interleaving. */
                drflac_uint64 i;
                for (i = 0; i < frameCountThisIteration; ++i) {
                    unsigned int j;
                    for (j = 0; j < channelCount; ++j) {
                        pBufferOut[(i*channelCount)+j] = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
                    }
                }
            }

            framesRead                += frameCountThisIteration;
            pBufferOut                += frameCountThisIteration * channelCount;
            framesToRead              -= frameCountThisIteration;
            pFlac->currentPCMFrame    += frameCountThisIteration;
            pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
        }
    }

    return framesRead;
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutpu...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 right = left - side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int16)left0;
        pOutputSamples[i*8+1] = (drflac_int16)right0;
        pOutputSamples[i*8+2] = (drflac_int16)left1;
        pOutputSamples[i*8+3] = (drflac_int16)right1;
        pOutputSamples[i*8+4] = (drflac_int16)left2;
        pOutputSamples[i*8+5] = (drflac_int16)right2;
        pOutputSamples[i*8+6] = (drflac_int16)left3;
        pOutputSamples[i*8+7] = (drflac_int16)right3;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i right = _mm_sub_epi32(left, side);

        left  = _mm_srai_epi32(left,  16);
        right = _mm_srai_epi32(right, 16);

        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t left;
        uint32x4_t side;
        uint32x4_t right;

        left  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        right = vsubq_u32(left, side);

        left  = vshrq_n_u32(left,  16);
        right = vshrq_n_u32(right, 16);

        drflac__vst2q_u16((drflac_uint16*)pOutputSamples + i*8, vzip_u16(vmovn_u32(left), vmovn_u32(right)));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s16__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutp...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 left  = right + side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputS...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int16)left0;
        pOutputSamples[i*8+1] = (drflac_int16)right0;
        pOutputSamples[i*8+2] = (drflac_int16)left1;
        pOutputSamples[i*8+3] = (drflac_int16)right1;
        pOutputSamples[i*8+4] = (drflac_int16)left2;
        pOutputSamples[i*8+5] = (drflac_int16)right2;
        pOutputSamples[i*8+6] = (drflac_int16)left3;
        pOutputSamples[i*8+7] = (drflac_int16)right3;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    for (i = 0; i < frameCount4; ++i) {
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i left  = _mm_add_epi32(right, side);

        left  = _mm_srai_epi32(left,  16);
        right = _mm_srai_epi32(right, 16);

        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t side;
        uint32x4_t right;
        uint32x4_t left;

        side  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        right = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        left  = vaddq_u32(right, side);

        left  = vshrq_n_u32(left,  16);
        right = vshrq_n_u32(right, 16);

        drflac__vst2q_u16((drflac_uint16*)pOutputSamples + i*8, vzip_u16(vmovn_u32(left), vmovn_u32(right)));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        left  >>= 16;
        right >>= 16;

        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s16__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutput...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        drflac_uint32 mid  = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

        mid = (mid << 1) | (side & 0x01);

        pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;

    if (shift > 0) {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;

            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;

            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);

            temp0L = (mid0 + side0) << shift;
            temp1L = (mid1 + side1) << shift;
            temp2L = (mid2 + side2) << shift;
            temp3L = (mid3 + side3) << shift;

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

            pOutputSamples[i*8+0] = (drflac_int16)temp0L;
            pOutputSamples[i*8+1] = (drflac_int16)temp0R;
            pOutputSamples[i*8+2] = (drflac_int16)temp1L;
            pOutputSamples[i*8+3] = (drflac_int16)temp1R;
            pOutputSamples[i*8+4] = (drflac_int16)temp2L;
            pOutputSamples[i*8+5] = (drflac_int16)temp2R;
            pOutputSamples[i*8+6] = (drflac_int16)temp3L;
            pOutputSamples[i*8+7] = (drflac_int16)temp3R;
        }
    } else {
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;

            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;

            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);

            temp0L = ((drflac_int32)(mid0 + side0) >> 1);
            temp1L = ((drflac_int32)(mid1 + side1) >> 1);
            temp2L = ((drflac_int32)(mid2 + side2) >> 1);
            temp3L = ((drflac_int32)(mid3 + side3) >> 1);

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

            pOutputSamples[i*8+1] = (drflac_int16)temp0R;
            pOutputSamples[i*8+2] = (drflac_int16)temp1L;
            pOutputSamples[i*8+3] = (drflac_int16)temp1R;
            pOutputSamples[i*8+4] = (drflac_int16)temp2L;
            pOutputSamples[i*8+5] = (drflac_int16)temp2R;
            pOutputSamples[i*8+6] = (drflac_int16)temp3L;
            pOutputSamples[i*8+7] = (drflac_int16)temp3R;
        }
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

        mid = (mid << 1) | (side & 0x01);

        pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;

            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));

            left  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
            right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);

            left  = _mm_srai_epi32(left,  16);
            right = _mm_srai_epi32(right, 16);

            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
        }
    } else {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;

            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));

            left  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
            right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);

            left  = _mm_srai_epi32(left,  16);
            right = _mm_srai_epi32(right, 16);

            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
        }
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;
    int32x4_t wbpsShift0_4; /* wbps = Wasted Bits Per Sample */
    int32x4_t wbpsShift1_4; /* wbps = Wasted Bits Per Sample */

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
    wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;

            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);

            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));

            left  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
            right = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);

            left  = vshrq_n_s32(left,  16);
            right = vshrq_n_s32(right, 16);

            drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
        }
    } else {
        int32x4_t shift4;

        shift -= 1;
        shift4 = vdupq_n_s32(shift);

        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;

            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);

            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));

            left  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
            right = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));

            left  = vshrq_n_s32(left,  16);
            right = vshrq_n_s32(right, 16);

            drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
        }
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s16__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int1...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) >> 16);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* ...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int16)tempL0;
        pOutputSamples[i*8+1] = (drflac_int16)tempR0;
        pOutputSamples[i*8+2] = (drflac_int16)tempL1;
        pOutputSamples[i*8+3] = (drflac_int16)tempR1;
        pOutputSamples[i*8+4] = (drflac_int16)tempL2;
        pOutputSamples[i*8+5] = (drflac_int16)tempR2;
        pOutputSamples[i*8+6] = (drflac_int16)tempL3;
        pOutputSamples[i*8+7] = (drflac_int16)tempR3;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);

        left  = _mm_srai_epi32(left,  16);
        right = _mm_srai_epi32(right, 16);

        /* At this point we have results. We can now pack and interleave these into a single __m128i object and then store the in the output buffer. */
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    int32x4_t shift0_4 = vdupq_n_s32(shift0);
    int32x4_t shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        int32x4_t left;
        int32x4_t right;

        left  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4));
        right = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4));

        left  = vshrq_n_s32(left,  16);
        right = vshrq_n_s32(right, 16);

        drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputS...
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_s16__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}

DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut)
{
    drflac_uint64 framesRead;
    drflac_uint32 unusedBitsPerSample;

    if (pFlac == NULL || framesToRead == 0) {
        return 0;
    }

    if (pBufferOut == NULL) {
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
    }

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;

    framesRead = 0;
    while (framesToRead > 0) {
        /* If we've run out of samples in this frame, go to the next. */
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;  /* Couldn't read the next frame, so just break from the loop and return. */
            }
        } else {
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
            drflac_uint64 frameCountThisIteration = framesToRead;

            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
            }

            if (channelCount == 2) {
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;

                switch (pFlac->currentFLACFrame.header.channelAssignment)
                {
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
                    {
                        drflac_read_pcm_frames_s16__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
                    {
                        drflac_read_pcm_frames_s16__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
                    {
                        drflac_read_pcm_frames_s16__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
                    default:
                    {
                        drflac_read_pcm_frames_s16__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                }
            } else {
                /* Generic interleaving. */
                drflac_uint64 i;
                for (i = 0; i < frameCountThisIteration; ++i) {
                    unsigned int j;
                    for (j = 0; j < channelCount; ++j) {
                        drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
                        pBufferOut[(i*channelCount)+j] = (drflac_int16)(sampleS32 >> 16);
                    }
                }
            }

            framesRead                += frameCountThisIteration;
            pBufferOut                += frameCountThisIteration * channelCount;
            framesToRead              -= frameCountThisIteration;
            pFlac->currentPCMFrame    += frameCountThisIteration;
            pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
        }
    }

    return framesRead;
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSample...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (float)((drflac_int32)left  / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

    float factor = 1 / 2147483648.0;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int32)left0  * factor;
        pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
        pOutputSamples[i*8+2] = (drflac_int32)left1  * factor;
        pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
        pOutputSamples[i*8+4] = (drflac_int32)left2  * factor;
        pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
        pOutputSamples[i*8+6] = (drflac_int32)left3  * factor;
        pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left  * factor;
        pOutputSamples[i*2+1] = (drflac_int32)right * factor;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    __m128 factor;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    factor = _mm_set1_ps(1.0f / 8388608.0f);

    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i right = _mm_sub_epi32(left, side);
        __m128 leftf  = _mm_mul_ps(_mm_cvtepi32_ps(left),  factor);
        __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);

        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    float32x4_t factor4;
    int32x4_t shift0_4;
    int32x4_t shift1_4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    factor4  = vdupq_n_f32(1.0f / 8388608.0f);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t left;
        uint32x4_t side;
        uint32x4_t right;
        float32x4_t leftf;
        float32x4_t rightf;

        left   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        side   = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        right  = vsubq_u32(left, side);
        leftf  = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(left)),  factor4);
        rightf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(right)), factor4);

        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;

        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_f32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSampl...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (float)((drflac_int32)left  / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    float factor = 1 / 2147483648.0;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;

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

        pOutputSamples[i*8+0] = (drflac_int32)left0  * factor;
        pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
        pOutputSamples[i*8+2] = (drflac_int32)left1  * factor;
        pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
        pOutputSamples[i*8+4] = (drflac_int32)left2  * factor;
        pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
        pOutputSamples[i*8+6] = (drflac_int32)left3  * factor;
        pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left  * factor;
        pOutputSamples[i*2+1] = (drflac_int32)right * factor;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    __m128 factor;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    factor = _mm_set1_ps(1.0f / 8388608.0f);

    for (i = 0; i < frameCount4; ++i) {
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i left  = _mm_add_epi32(right, side);
        __m128 leftf  = _mm_mul_ps(_mm_cvtepi32_ps(left),  factor);
        __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);

        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    float32x4_t factor4;
    int32x4_t shift0_4;
    int32x4_t shift1_4;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    factor4  = vdupq_n_f32(1.0f / 8388608.0f);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t side;
        uint32x4_t right;
        uint32x4_t left;
        float32x4_t leftf;
        float32x4_t rightf;

        side   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        right  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        left   = vaddq_u32(right, side);
        leftf  = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(left)),  factor4);
        rightf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(right)), factor4);

        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;

        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_f32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}


#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        drflac_uint32 mid  = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

        mid = (mid << 1) | (side & 0x01);

        pOutputSamples[i*2+0] = (float)((((drflac_int32)(mid + side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((((drflac_int32)(mid - side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;
    float factor = 1 / 2147483648.0;

    if (shift > 0) {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;

            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;

            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);

            temp0L = (mid0 + side0) << shift;
            temp1L = (mid1 + side1) << shift;
            temp2L = (mid2 + side2) << shift;
            temp3L = (mid3 + side3) << shift;

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

            pOutputSamples[i*8+0] = (drflac_int32)temp0L * factor;
            pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
        }
    } else {
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;

            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;

            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);

            temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
            temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
            temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
            temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);

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

            pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
        }
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

        mid = (mid << 1) | (side & 0x01);

        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) * factor;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample - 8;
    float factor;
    __m128 factor128;

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    factor = 1.0f / 8388608.0f;
    factor128 = _mm_set1_ps(factor);

    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i tempL;
            __m128i tempR;
            __m128  leftf;
            __m128  rightf;

            mid    = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

            mid    = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));

            tempL  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
            tempR  = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);

            leftf  = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
            rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);

            _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
            _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
            pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
        }
    } else {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i tempL;
            __m128i tempR;
            __m128 leftf;
            __m128 rightf;

            mid    = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

            mid    = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));

            tempL  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
            tempR  = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);

            leftf  = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
            rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);

            _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
            _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
        }
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample - 8;
    float factor;
    float32x4_t factor4;
    int32x4_t shift4;
    int32x4_t wbps0_4;  /* Wasted Bits Per Sample */
    int32x4_t wbps1_4;  /* Wasted Bits Per Sample */

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);

    factor  = 1.0f / 8388608.0f;
    factor4 = vdupq_n_f32(factor);
    wbps0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
    wbps1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);

    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            int32x4_t lefti;
            int32x4_t righti;
            float32x4_t leftf;
            float32x4_t rightf;

            uint32x4_t mid  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbps0_4);
            uint32x4_t side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbps1_4);

            mid    = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));

            lefti  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
            righti = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);

            leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
            rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);

            drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
            pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
        }
    } else {
        shift -= 1;
        shift4 = vdupq_n_s32(shift);
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t lefti;
            int32x4_t righti;
            float32x4_t leftf;
            float32x4_t rightf;

            mid    = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbps0_4);
            side   = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbps1_4);

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


            lefti  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
            righti = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));

            leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
            rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);

            drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
        }

        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;

            mid = (mid << 1) | (side & 0x01);

            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
        }
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_f32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}

#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOut...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (float)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) / 2147483648.0);
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutput...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    float factor = 1 / 2147483648.0;

    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;

        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;

        pOutputSamples[i*8+0] = (drflac_int32)tempL0 * factor;
        pOutputSamples[i*8+1] = (drflac_int32)tempR0 * factor;
        pOutputSamples[i*8+2] = (drflac_int32)tempL1 * factor;
        pOutputSamples[i*8+3] = (drflac_int32)tempR1 * factor;
        pOutputSamples[i*8+4] = (drflac_int32)tempL2 * factor;
        pOutputSamples[i*8+5] = (drflac_int32)tempR2 * factor;
        pOutputSamples[i*8+6] = (drflac_int32)tempL3 * factor;
        pOutputSamples[i*8+7] = (drflac_int32)tempR3 * factor;
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
    }
}

#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;

    float factor = 1.0f / 8388608.0f;
    __m128 factor128 = _mm_set1_ps(factor);

    for (i = 0; i < frameCount4; ++i) {
        __m128i lefti;
        __m128i righti;
        __m128 leftf;
        __m128 rightf;

        lefti  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        righti = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);

        leftf  = _mm_mul_ps(_mm_cvtepi32_ps(lefti),  factor128);
        rightf = _mm_mul_ps(_mm_cvtepi32_ps(righti), factor128);

        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
    }
}
#endif

#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;

    float factor = 1.0f / 8388608.0f;
    float32x4_t factor4 = vdupq_n_f32(factor);
    int32x4_t shift0_4  = vdupq_n_s32(shift0);
    int32x4_t shift1_4  = vdupq_n_s32(shift1);

    for (i = 0; i < frameCount4; ++i) {
        int32x4_t lefti;
        int32x4_t righti;
        float32x4_t leftf;
        float32x4_t rightf;

        lefti  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4));
        righti = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4));

        leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
        rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);

        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
    }

    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
    }
}
#endif

static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
        /* Scalar fallback. */
#if 0
        drflac_read_pcm_frames_f32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}

DRFLAC_API drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut)
{
    drflac_uint64 framesRead;
    drflac_uint32 unusedBitsPerSample;

    if (pFlac == NULL || framesToRead == 0) {
        return 0;
    }

    if (pBufferOut == NULL) {
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
    }

    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;

    framesRead = 0;
    while (framesToRead > 0) {
        /* If we've run out of samples in this frame, go to the next. */
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;  /* Couldn't read the next frame, so just break from the loop and return. */
            }
        } else {
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
            drflac_uint64 frameCountThisIteration = framesToRead;

            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
            }

            if (channelCount == 2) {
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;

                switch (pFlac->currentFLACFrame.header.channelAssignment)
                {
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
                    {
                        drflac_read_pcm_frames_f32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
                    {
                        drflac_read_pcm_frames_f32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
                    {
                        drflac_read_pcm_frames_f32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;

                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
                    default:
                    {
                        drflac_read_pcm_frames_f32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                }
            } else {
                /* Generic interleaving. */
                drflac_uint64 i;
                for (i = 0; i < frameCountThisIteration; ++i) {
                    unsigned int j;
                    for (j = 0; j < channelCount; ++j) {
                        drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
                        pBufferOut[(i*channelCount)+j] = (float)(sampleS32 / 2147483648.0);
                    }
                }
            }

            framesRead                += frameCountThisIteration;
            pBufferOut                += frameCountThisIteration * channelCount;
            framesToRead              -= frameCountThisIteration;
            pFlac->currentPCMFrame    += frameCountThisIteration;
            pFlac->currentFLACFrame.pcmFramesRemaining -= (unsigned int)frameCountThisIteration;
        }
    }

    return framesRead;
}


DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    if (pFlac == NULL) {
        return DRFLAC_FALSE;
    }

    /* Don't do anything if we're already on the seek point. */
    if (pFlac->currentPCMFrame == pcmFrameIndex) {
        return DRFLAC_TRUE;
    }

    /*
    If we don't know where the first frame begins then we can't seek. This will happen when the STREAMINFO block was not present
    when the decoder was opened.
    */
    if (pFlac->firstFLACFramePosInBytes == 0) {
        return DRFLAC_FALSE;
    }

    if (pcmFrameIndex == 0) {
        pFlac->currentPCMFrame = 0;
        return drflac__seek_to_first_frame(pFlac);
    } else {
        drflac_bool32 wasSuccessful = DRFLAC_FALSE;
        drflac_uint64 originalPCMFrame = pFlac->currentPCMFrame;

        /* Clamp the sample to the end. */
        if (pcmFrameIndex > pFlac->totalPCMFrameCount) {
            pcmFrameIndex = pFlac->totalPCMFrameCount;
        }

        /* If the target sample and the current sample are in the same frame we just move the position forward. */
        if (pcmFrameIndex > pFlac->currentPCMFrame) {
            /* Forward. */
            drflac_uint32 offset = (drflac_uint32)(pcmFrameIndex - pFlac->currentPCMFrame);
            if (pFlac->currentFLACFrame.pcmFramesRemaining >  offset) {
                pFlac->currentFLACFrame.pcmFramesRemaining -= offset;
                pFlac->currentPCMFrame = pcmFrameIndex;
                return DRFLAC_TRUE;
            }
        } else {
            /* Backward. */

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

            }
        }

        /*
        Different techniques depending on encapsulation. Using the native FLAC seektable with Ogg encapsulation is a bit awkward so
        we'll instead use Ogg's natural seeking facility.
        */
#ifndef DR_FLAC_NO_OGG
        if (pFlac->container == drflac_container_ogg)
        {
            wasSuccessful = drflac_ogg__seek_to_pcm_frame(pFlac, pcmFrameIndex);
        }
        else
#endif
        {
            /* First try seeking via the seek table. If this fails, fall back to a brute force seek which is much slower. */
            if (/*!wasSuccessful && */!pFlac->_noSeekTableSeek) {
                wasSuccessful = drflac__seek_to_pcm_frame__seek_table(pFlac, pcmFrameIndex);
            }

#if !defined(DR_FLAC_NO_CRC)
            /* Fall back to binary search if seek table seeking fails. This requires the length of the stream to be known. */
            if (!wasSuccessful && !pFlac->_noBinarySearchSeek && pFlac->totalPCMFrameCount > 0) {
                wasSuccessful = drflac__seek_to_pcm_frame__binary_search(pFlac, pcmFrameIndex);
            }
#endif

            /* Fall back to brute force if all else fails. */
            if (!wasSuccessful && !pFlac->_noBruteForceSeek) {
                wasSuccessful = drflac__seek_to_pcm_frame__brute_force(pFlac, pcmFrameIndex);
            }
        }

        if (wasSuccessful) {
            pFlac->currentPCMFrame = pcmFrameIndex;
        } else {
            /* Seek failed. Try putting the decoder back to it's original state. */
            if (drflac_seek_to_pcm_frame(pFlac, originalPCMFrame) == DRFLAC_FALSE) {
                /* Failed to seek back to the original PCM frame. Fall back to 0. */
                drflac_seek_to_pcm_frame(pFlac, 0);
            }
        }

        return wasSuccessful;
    }
}



/* High Level APIs */

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

    if (totalPCMFrameCount == 0) {                                                                                                                                  \
        type buffer[4096];                                                                                                                                          \
        drflac_uint64 pcmFramesRead;                                                                                                                                \
        size_t sampleDataBufferSize = sizeof(buffer);                                                                                                               \
                                                                                                                                                                    \
        pSampleData = (type*)drflac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks);                                                      \
        if (pSampleData == NULL) {                                                                                                                                  \
            goto on_error;                                                                                                                                          \
        }                                                                                                                                                           \
                                                                                                                                                                    \
        while ((pcmFramesRead = (drflac_uint64)drflac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) {          \
            if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) {                                                   \
                type* pNewSampleData;                                                                                                                               \
                size_t newSampleDataBufferSize;                                                                                                                     \
                                                                                                                                                                    \
                newSampleDataBufferSize = sampleDataBufferSize * 2;                                                                                                 \
                pNewSampleData = (type*)drflac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks);    \
                if (pNewSampleData == NULL) {                                                                                                                       \
                    drflac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks);                                                                          \
                    goto on_error;                                                                                                                                  \
                }                                                                                                                                                   \

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

        drflac_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type);                                                                                   \
        if (dataSize > (drflac_uint64)DRFLAC_SIZE_MAX) {                                                                                                            \
            goto on_error;  /* The decoded data is too big. */                                                                                                      \
        }                                                                                                                                                           \
                                                                                                                                                                    \
        pSampleData = (type*)drflac__malloc_from_callbacks((size_t)dataSize, &pFlac->allocationCallbacks);    /* <-- Safe cast as per the check above. */           \
        if (pSampleData == NULL) {                                                                                                                                  \
            goto on_error;                                                                                                                                          \
        }                                                                                                                                                           \
                                                                                                                                                                    \
        totalPCMFrameCount = drflac_read_pcm_frames_##extension(pFlac, pFlac->totalPCMFrameCount, pSampleData);                                                     \
    }                                                                                                                                                               \
                                                                                                                                                                    \
    if (sampleRateOut) *sampleRateOut = pFlac->sampleRate;                                                                                                          \
    if (channelsOut) *channelsOut = pFlac->channels;                                                                                                                \
    if (totalPCMFrameCountOut) *totalPCMFrameCountOut = totalPCMFrameCount;                                                                                         \
                                                                                                                                                                    \
    drflac_close(pFlac);                                                                                                                                            \
    return pSampleData;                                                                                                                                             \
                                                                                                                                                                    \
on_error:                                                                                                                                                           \
    drflac_close(pFlac);                                                                                                                                            \
    return NULL;                                                                                                                                                    \
}

DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s32, drflac_int32)
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s16, drflac_int16)
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(f32, float)

DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_call...
{
    drflac* pFlac;

    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalPCMFrameCountOut) {

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

    }

    pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_s32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}

DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_call...
{
    drflac* pFlac;

    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalPCMFrameCountOut) {

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

    }

    pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_s16(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}

DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* ...
{
    drflac* pFlac;

    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalPCMFrameCountOut) {

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


    pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_f32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}

#ifndef DR_FLAC_NO_STDIO
DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;

    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {

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

    }

    pFlac = drflac_open_file(filename, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
}

DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;

    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {

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

    }

    pFlac = drflac_open_file(filename, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
}

DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;

    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {

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


    pFlac = drflac_open_file(filename, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_f32(pFlac, channels, sampleRate, totalPCMFrameCount);
}
#endif

DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;

    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {

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

    }

    pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
}

DRFLAC_API drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;

    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {

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

    }

    pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }

    return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
}

DRFLAC_API float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;

    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {

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

  - Fix a compilation error with the ARM build.

v0.12.35 - 2022-02-06
  - Fix a bug due to underestimating the amount of precision required for the prediction stage.
  - Fix some bugs found from fuzz testing.

v0.12.34 - 2022-01-07
  - Fix some misalignment bugs when reading metadata.

v0.12.33 - 2021-12-22
  - Fix a bug with seeking when the seek table does not start at PCM frame 0.

v0.12.32 - 2021-12-11
  - Fix a warning with Clang.

v0.12.31 - 2021-08-16
  - Silence some warnings.

v0.12.30 - 2021-07-31
  - Fix platform detection for ARM64.

v0.12.29 - 2021-04-02
  - Fix a bug where the running PCM frame index is set to an invalid value when over-seeking.
  - Fix a decoding error due to an incorrect validation check.

v0.12.28 - 2021-02-21
  - Fix a warning due to referencing _MSC_VER when it is undefined.

v0.12.27 - 2021-01-31
  - Fix a static analysis warning.

v0.12.26 - 2021-01-17
  - Fix a compilation warning due to _BSD_SOURCE being deprecated.

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

  - API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
    routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs:
    - drflac_open()
    - drflac_open_relaxed()
    - drflac_open_with_metadata()
    - drflac_open_with_metadata_relaxed()
    - drflac_open_file()
    - drflac_open_file_with_metadata()
    - drflac_open_memory()
    - drflac_open_memory_with_metadata()
    - drflac_open_and_read_pcm_frames_s32()
    - drflac_open_and_read_pcm_frames_s16()
    - drflac_open_and_read_pcm_frames_f32()
    - drflac_open_file_and_read_pcm_frames_s32()
    - drflac_open_file_and_read_pcm_frames_s16()
    - drflac_open_file_and_read_pcm_frames_f32()
    - drflac_open_memory_and_read_pcm_frames_s32()
    - drflac_open_memory_and_read_pcm_frames_s16()
    - drflac_open_memory_and_read_pcm_frames_f32()
    Set this extra parameter to NULL to use defaults which is the same as the previous behaviour. Setting this NULL will use
    DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE.
  - Remove deprecated APIs:
    - drflac_read_s32()
    - drflac_read_s16()
    - drflac_read_f32()
    - drflac_seek_to_sample()
    - drflac_open_and_decode_s32()
    - drflac_open_and_decode_s16()
    - drflac_open_and_decode_f32()
    - drflac_open_and_decode_file_s32()
    - drflac_open_and_decode_file_s16()
    - drflac_open_and_decode_file_f32()
    - drflac_open_and_decode_memory_s32()
    - drflac_open_and_decode_memory_s16()
    - drflac_open_and_decode_memory_f32()
  - Remove drflac.totalSampleCount which is now replaced with drflac.totalPCMFrameCount. You can emulate drflac.totalSampleCount
    by doing pFlac->totalPCMFrameCount*pFlac->channels.
  - Rename drflac.currentFrame to drflac.currentFLACFrame to remove ambiguity with PCM frames.
  - Fix errors when seeking to the end of a stream.
  - Optimizations to seeking.
  - SSE improvements and optimizations.
  - ARM NEON optimizations.
  - Optimizations to drflac_read_pcm_frames_s16().
  - Optimizations to drflac_read_pcm_frames_s32().

v0.11.10 - 2019-06-26
  - Fix a compiler error.

v0.11.9 - 2019-06-16
  - Silence some ThreadSanitizer warnings.

v0.11.8 - 2019-05-21
  - Fix warnings.

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

  - Silence warnings with GCC.

v0.11.2 - 2019-03-10
  - Fix a warning.

v0.11.1 - 2019-02-17
  - Fix a potential bug with seeking.

v0.11.0 - 2018-12-16
  - API CHANGE: Deprecated drflac_read_s32(), drflac_read_s16() and drflac_read_f32() and replaced them with
    drflac_read_pcm_frames_s32(), drflac_read_pcm_frames_s16() and drflac_read_pcm_frames_f32(). The new APIs take
    and return PCM frame counts instead of sample counts. To upgrade you will need to change the input count by
    dividing it by the channel count, and then do the same with the return value.
  - API_CHANGE: Deprecated drflac_seek_to_sample() and replaced with drflac_seek_to_pcm_frame(). Same rules as
    the changes to drflac_read_*() apply.
  - API CHANGE: Deprecated drflac_open_and_decode_*() and replaced with drflac_open_*_and_read_*(). Same rules as
    the changes to drflac_read_*() apply.
  - Optimizations.

v0.10.0 - 2018-09-11
  - Remove the DR_FLAC_NO_WIN32_IO option and the Win32 file IO functionality. If you need to use Win32 file IO you
    need to do it yourself via the callback API.
  - Fix the clang build.
  - Fix undefined behavior.

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

  - Fix Clang build.
  - Start using major.minor.revision versioning.

v0.8g - 2018-04-19
  - Fix build on non-x86/x64 architectures.

v0.8f - 2018-02-02
  - Stop pretending to support changing rate/channels mid stream.

v0.8e - 2018-02-01
  - Fix a crash when the block size of a frame is larger than the maximum block size defined by the FLAC stream.
  - Fix a crash the the Rice partition order is invalid.

v0.8d - 2017-09-22
  - Add support for decoding streams with ID3 tags. ID3 tags are just skipped.

v0.8c - 2017-09-07
  - Fix warning on non-x86/x64 architectures.

v0.8b - 2017-08-19
  - Fix build on non-x86/x64 architectures.

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

  - Optimizations. This brings dr_flac back to about the same class of efficiency as the reference implementation.
  - Add support for custom implementations of malloc(), realloc(), etc.
  - Add CRC checking to Ogg encapsulated streams.
  - Fix VC++ 6 build. This is only for the C++ compiler. The C compiler is not currently supported.
  - Bug fixes.

v0.7 - 2017-07-23
  - Add support for opening a stream without a header block. To do this, use drflac_open_relaxed() / drflac_open_with_metadata_relaxed().

v0.6 - 2017-07-22
  - Add support for recovering from invalid frames. With this change, dr_flac will simply skip over invalid frames as if they
    never existed. Frames are checked against their sync code, the CRC-8 of the frame header and the CRC-16 of the whole frame.

v0.5 - 2017-07-16
  - Fix typos.
  - Change drflac_bool* types to unsigned.
  - Add CRC checking. This makes dr_flac slower, but can be disabled with #define DR_FLAC_NO_CRC.

v0.4f - 2017-03-10
  - Fix a couple of bugs with the bitstreaming code.

v0.4e - 2017-02-17

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

When initializing the device you first need to configure it. The device configuration allows you to
specify things like the format of the data delivered via the callback, the size of the internal
buffer and the ID of the device you want to emit or capture audio from.

Once you have the device configuration set up you can initialize the device. When initializing a
device you need to allocate memory for the device object beforehand. This gives the application
complete control over how the memory is allocated. In the example below we initialize a playback
device on the stack, but you could allocate it on the heap if that suits your situation better.

    ```c
    void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
    {
        // In playback mode copy data to pOutput. In capture mode read data from pInput. In full-duplex mode, both
        // pOutput and pInput will be valid and you can move data from pInput into pOutput. Never process more than
        // frameCount frames.
    }

    int main()
    {
        ma_device_config config = ma_device_config_init(ma_device_type_playback);
        config.playback.format   = ma_format_f32;   // Set to ma_format_unknown to use the device's native format.
        config.playback.channels = 2;               // Set to 0 to use the device's native channel count.
        config.sampleRate        = 48000;           // Set to 0 to use the device's native sample rate.
        config.dataCallback      = data_callback;   // This function will be called when miniaudio needs more data.
        config.pUserData         = pMyCustomData;   // Can be accessed from the device object (device.pUserData).

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

        // Do something here. Probably your program's main loop.

        ma_device_uninit(&device);    // This will stop the device so no need to do that manually.
        return 0;
    }
    ```

In the example above, `data_callback()` is where audio data is written and read from the device.
The idea is in playback mode you cause sound to be emitted from the speakers by writing audio data
to the output buffer (`pOutput` in the example). In capture mode you read data from the input
buffer (`pInput`) to extract sound captured by the microphone. The `frameCount` parameter tells you
how many frames can be written to the output buffer and read from the input buffer. A "frame" is
one sample for each channel. For example, in a stereo stream (2 channels), one frame is 2
samples: one for the left, one for the right. The channel count is defined by the device config.
The size in bytes of an individual sample is defined by the sample format which is also specified
in the device config. Multi-channel audio data is always interleaved, which means the samples for
each frame are stored next to each other in memory. For example, in a stereo stream the first pair
of samples will be the left and right samples for the first frame, the second pair of samples will
be the left and right samples for the second frame, etc.

The configuration of the device is defined by the `ma_device_config` structure. The config object
is always initialized with `ma_device_config_init()`. It's important to always initialize the
config with this function as it initializes it with logical defaults and ensures your program
doesn't break when new members are added to the `ma_device_config` structure. The example above
uses a fairly simple and standard device configuration. The call to `ma_device_config_init()` takes
a single parameter, which is whether or not the device is a playback, capture, duplex or loopback
device (loopback devices are not supported on all backends). The `config.playback.format` member
sets the sample format which can be one of the following (all formats are native-endian):

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

    ```

This returns a `ma_sound` object which represents a single instance of the specified sound file. If
you want to play the same file multiple times simultaneously, you need to create one sound for each
instance.

Sounds should be uninitialized with `ma_sound_uninit()`.

Sounds are not started by default. Start a sound with `ma_sound_start()` and stop it with
`ma_sound_stop()`. When a sound is stopped, it is not rewound to the start. Use
`ma_sound_seek_to_pcm_frames(&sound, 0)` to seek back to the start of a sound. By default, starting
and stopping sounds happens immediately, but sometimes it might be convenient to schedule the sound
the be started and/or stopped at a specific time. This can be done with the following functions:

    ```c
    ma_sound_set_start_time_in_pcm_frames()
    ma_sound_set_start_time_in_milliseconds()
    ma_sound_set_stop_time_in_pcm_frames()
    ma_sound_set_stop_time_in_milliseconds()
    ```

The start/stop time needs to be specified based on the absolute timer which is controlled by the
engine. The current global time time in PCM frames can be retrieved with `ma_engine_get_time()`.
The engine's global time can be changed with `ma_engine_set_time()` for synchronization purposes if
required. Note that scheduling a start time still requires an explicit call to `ma_sound_start()`
before anything will play:

    ```c
    ma_sound_set_start_time_in_pcm_frames(&sound, ma_engine_get_time(&engine) + (ma_engine_get_sample_rate(&engine) * 2);
    ma_sound_start(&sound);
    ```

The third parameter of `ma_sound_init_from_file()` is a set of flags that control how the sound be
loaded and a few options on which features should be enabled for that sound. By default, the sound
is synchronously loaded fully into memory straight from the file system without any kind of
decoding. If you want to decode the sound before storing it in memory, you need to specify the
`MA_SOUND_FLAG_DECODE` flag. This is useful if you want to incur the cost of decoding at an earlier
stage, such as a loading stage. Without this option, decoding will happen dynamically at mixing
time which might be too expensive on the audio thread.

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

By default, sounds and sound groups have spatialization enabled. If you don't ever want to
spatialize your sounds, initialize the sound with the `MA_SOUND_FLAG_NO_SPATIALIZATION` flag. The
spatialization model is fairly simple and is roughly on feature parity with OpenAL. HRTF and
environmental occlusion are not currently supported, but planned for the future. The supported
features include:

  * Sound and listener positioning and orientation with cones
  * Attenuation models: none, inverse, linear and exponential
  * Doppler effect

Sounds can be faded in and out with `ma_sound_set_fade_in_pcm_frames()`.

To check if a sound is currently playing, you can use `ma_sound_is_playing()`. To check if a sound
is at the end, use `ma_sound_at_end()`. Looping of a sound can be controlled with
`ma_sound_set_looping()`. Use `ma_sound_is_looping()` to check whether or not the sound is looping.



2. Building
===========
miniaudio should work cleanly out of the box without the need to download or install any

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

The Windows build should compile cleanly on all popular compilers without the need to configure any
include paths nor link to any libraries.

The UWP build may require linking to mmdevapi.lib if you get errors about an unresolved external
symbol for `ActivateAudioInterfaceAsync()`.


2.2. macOS and iOS
------------------
The macOS build should compile cleanly without the need to download any dependencies nor link to
any libraries or frameworks. The iOS build needs to be compiled as Objective-C and will need to
link the relevant frameworks but should compile cleanly out of the box with Xcode. Compiling
through the command line requires linking to `-lpthread` and `-lm`.

Due to the way miniaudio links to frameworks at runtime, your application may not pass Apple's
notarization process. To fix this there are two options. The first is to use the
`MA_NO_RUNTIME_LINKING` option, like so:

    ```c
    #ifdef __APPLE__
        #define MA_NO_RUNTIME_LINKING
    #endif
    #define MINIAUDIO_IMPLEMENTATION
    #include "miniaudio.h"
    ```

This will require linking with `-framework CoreFoundation -framework CoreAudio -framework AudioUnit`.
Alternatively, if you would rather keep using runtime linking you can add the following to your
entitlements.xcent file:

    ```
    <key>com.apple.security.cs.allow-dyld-environment-variables</key>
    <true/>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    ```

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

in the use of terms throughout the audio space, so this section is intended to clarify how miniaudio
uses each term.

3.1. Sample
-----------
A sample is a single unit of audio data. If the sample format is f32, then one sample is one 32-bit
floating point number.

3.2. Frame / PCM Frame
----------------------
A frame is a group of samples equal to the number of channels. For a stereo stream a frame is 2
samples, a mono frame is 1 sample, a 5.1 surround sound frame is 6 samples, etc. The terms "frame"
and "PCM frame" are the same thing in miniaudio. Note that this is different to a compressed frame.
If ever miniaudio needs to refer to a compressed frame, such as a FLAC frame, it will always
clarify what it's referring to with something like "FLAC frame".

3.3. Channel
------------
A stream of monaural audio that is emitted from an individual speaker in a speaker system, or
received from an individual microphone in a microphone system. A stereo stream has two channels (a
left channel, and a right channel), a 5.1 surround sound system has 6 channels, etc. Some audio
systems refer to a channel as a complex audio stream that's mixed with other channels to produce
the final mix - this is completely different to miniaudio's use of the term "channel" and should
not be confused.

3.4. Sample Rate
----------------
The sample rate in miniaudio is always expressed in Hz, such as 44100, 48000, etc. It's the number
of PCM frames that are processed per second.

3.5. Formats
------------
Throughout miniaudio you will see references to different sample formats:

    +---------------+----------------------------------------+---------------------------+
    | Symbol        | Description                            | Range                     |
    +---------------+----------------------------------------+---------------------------+
    | ma_format_f32 | 32-bit floating point                  | [-1, 1]                   |
    | ma_format_s16 | 16-bit signed integer                  | [-32768, 32767]           |

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

examples include `ma_decoder`, `ma_noise` and `ma_waveform`. You will need to be familiar with data
sources in order to make sense of some of the higher level concepts in miniaudio.

The `ma_data_source` API is a generic interface for reading from a data source. Any object that
implements the data source interface can be plugged into any `ma_data_source` function.

To read data from a data source:

    ```c
    ma_result result;
    ma_uint64 framesRead;

    result = ma_data_source_read_pcm_frames(pDataSource, pFramesOut, frameCount, &framesRead, loop);
    if (result != MA_SUCCESS) {
        return result;  // Failed to read data from the data source.
    }
    ```

If you don't need the number of frames that were successfully read you can pass in `NULL` to the
`pFramesRead` parameter. If this returns a value less than the number of frames requested it means
the end of the file has been reached. `MA_AT_END` will be returned only when the number of frames
read is 0.

When calling any data source function, with the exception of `ma_data_source_init()` and
`ma_data_source_uninit()`, you can pass in any object that implements a data source. For example,
you could plug in a decoder like so:

    ```c
    ma_result result;
    ma_uint64 framesRead;
    ma_decoder decoder;   // <-- This would be initialized with `ma_decoder_init_*()`.

    result = ma_data_source_read_pcm_frames(&decoder, pFramesOut, frameCount, &framesRead, loop);
    if (result != MA_SUCCESS) {
        return result;  // Failed to read data from the decoder.
    }
    ```

If you want to seek forward you can pass in `NULL` to the `pFramesOut` parameter. Alternatively you
can use `ma_data_source_seek_pcm_frames()`.

To seek to a specific PCM frame:

    ```c
    result = ma_data_source_seek_to_pcm_frame(pDataSource, frameIndex);
    if (result != MA_SUCCESS) {
        return result;  // Failed to seek to PCM frame.
    }
    ```

You can retrieve the total length of a data source in PCM frames, but note that some data sources
may not have the notion of a length, such as noise and waveforms, and others may just not have a
way of determining the length such as some decoders. To retrieve the length:

    ```c
    ma_uint64 length;

    result = ma_data_source_get_length_in_pcm_frames(pDataSource, &length);
    if (result != MA_SUCCESS) {
        return result;  // Failed to retrieve the length.
    }
    ```

Care should be taken when retrieving the length of a data source where the underlying decoder is
pulling data from a data stream with an undefined length, such as internet radio or some kind of
broadcast. If you do this, `ma_data_source_get_length_in_pcm_frames()` may never return.

The current position of the cursor in PCM frames can also be retrieved:

    ```c
    ma_uint64 cursor;

    result = ma_data_source_get_cursor_in_pcm_frames(pDataSource, &cursor);
    if (result != MA_SUCCESS) {
        return result;  // Failed to retrieve the cursor.
    }
    ```

You will often need to know the data format that will be returned after reading. This can be
retrieved like so:

    ```c
    ma_format format;

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

        return result;  // Failed to retrieve data format.
    }
    ```

If you do not need a specific data format property, just pass in NULL to the respective parameter.

There may be cases where you want to implement something like a sound bank where you only want to
read data within a certain range of the underlying data. To do this you can use a range:

    ```c
    result = ma_data_source_set_range_in_pcm_frames(pDataSource, rangeBegInFrames, rangeEndInFrames);
    if (result != MA_SUCCESS) {
        return result;  // Failed to set the range.
    }
    ```

This is useful if you have a sound bank where many sounds are stored in the same file and you want
the data source to only play one of those sub-sounds.

Custom loop points can also be used with data sources. By default, data sources will loop after
they reach the end of the data source, but if you need to loop at a specific location, you can do
the following:

    ```c
    result = ma_data_set_loop_point_in_pcm_frames(pDataSource, loopBegInFrames, loopEndInFrames);
    if (result != MA_SUCCESS) {
        return result;  // Failed to set the loop point.
    }
    ```

The loop point is relative to the current range.

It's sometimes useful to chain data sources together so that a seamless transition can be achieved.
To do this, you can use chaining:

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

    ma_decoder decoder1;
    ma_decoder decoder2;

    // ... initialize decoders with ma_decoder_init_*() ...

    result = ma_data_source_set_next(&decoder1, &decoder2);
    if (result != MA_SUCCESS) {
        return result;  // Failed to set the next data source.
    }

    result = ma_data_source_read_pcm_frames(&decoder1, pFramesOut, frameCount, pFramesRead, MA_FALSE);
    if (result != MA_SUCCESS) {
        return result;  // Failed to read from the decoder.
    }
    ```

In the example above we're using decoders. When reading from a chain, you always want to read from
the top level data source in the chain. In the example above, `decoder1` is the top level data 
source in the chain. When `decoder1` reaches the end, `decoder2` will start seamlessly without any
gaps.

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

the current data source will be looped. You can loop the entire chain by linking in a loop like so:

    ```c
    ma_data_source_set_next(&decoder1, &decoder2);  // decoder1 -> decoder2
    ma_data_source_set_next(&decoder2, &decoder1);  // decoder2 -> decoder1 (loop back to the start).
    ```

Note that setting up chaining is not thread safe, so care needs to be taken if you're dynamically
changing links while the audio thread is in the middle of reading.

Do not use `ma_decoder_seek_to_pcm_frame()` as a means to reuse a data source to play multiple
instances of the same sound simultaneously. Instead, initialize multiple data sources for each
instance. This can be extremely inefficient depending on the data source and can result in
glitching due to subtle changes to the state of internal filters.


4.1. Custom Data Sources
------------------------
You can implement a custom data source by implementing the functions in `ma_data_source_vtable`.
Your custom object must have `ma_data_source_base` as it's first member:

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

    {
        ma_data_source_base base;
        ...
    };
    ```

In your initialization routine, you need to call `ma_data_source_init()` in order to set up the
base object (`ma_data_source_base`):

    ```c
    static ma_result my_data_source_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
    {
        // Read data here. Output in the same format returned by my_data_source_get_data_format().
    }

    static ma_result my_data_source_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
    {
        // Seek to a specific PCM frame here. Return MA_NOT_IMPLEMENTED if seeking is not supported.
    }

    static ma_result my_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
    {
        // Return the format of the data here.
    }

    static ma_result my_data_source_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
    {
        // Retrieve the current position of the cursor here. Return MA_NOT_IMPLEMENTED and set *pCursor to 0 if there is no notion of a cursor.
    }

    static ma_result my_data_source_get_length(ma_data_source* pDataSource, ma_uint64* pLength)
    {
        // Retrieve the length in PCM frames here. Return MA_NOT_IMPLEMENTED and set *pLength to 0 if there is no notion of a length or if the length is unknown.
    }

    static g_my_data_source_vtable =
    {
        my_data_source_read,
        my_data_source_seek,
        my_data_source_get_data_format,
        my_data_source_get_cursor,
        my_data_source_get_length
    };

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

    engineConfig.pPlaybackDevice = &myDevice;

    result = ma_engine_init(&engineConfig, &engine);
    if (result != MA_SUCCESS) {
        return result;  // Failed to initialize the engine.
    }
    ```

In the example above we're passing in a pre-initialized device. Since the caller is the one in
control of the device's data callback, it's their responsibility to manually call
`ma_engine_read_pcm_frames()` from inside their data callback:

    ```c
    void playback_data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
    {
        ma_engine_read_pcm_frames(&g_Engine, pOutput, frameCount, NULL);
    }
    ```

You can also use the engine independent of a device entirely:

    ```c
    ma_result result;
    ma_engine engine;
    ma_engine_config engineConfig;

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

    engineConfig.sampleRate = 48000;    // Must be set when not using a device.

    result = ma_engine_init(&engineConfig, &engine);
    if (result != MA_SUCCESS) {
        return result;  // Failed to initialize the engine.
    }
    ```

Note that when you're not using a device, you must set the channel count and sample rate in the
config or else miniaudio won't know what to use (miniaudio will use the device to determine this
normally). When not using a device, you need to use `ma_engine_read_pcm_frames()` to process audio
data from the engine. This kind of setup is useful if you want to do something like offline
processing.

When a sound is loaded it goes through a resource manager. By default the engine will initialize a
resource manager internally, but you can also specify a pre-initialized resource manager:

    ```c
    ma_result result;
    ma_engine engine1;
    ma_engine engine2;

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

    ma_sound_set_max_distance(&sound, maxDistance);
    ```

The engine's spatialization system supports doppler effect. The doppler factor can be configure on
a per-sound basis like so:

    ```c
    ma_sound_set_doppler_factor(&sound, dopplerFactor);
    ```

You can fade sounds in and out with `ma_sound_set_fade_in_pcm_frames()` and
`ma_sound_set_fade_in_milliseconds()`. Set the volume to -1 to use the current volume as the
starting volume:

    ```c
    // Fade in over 1 second.
    ma_sound_set_fade_in_milliseconds(&sound, 0, 1, 1000);

    // ... sometime later ...

    // Fade out over 1 second, starting from the current volume.
    ma_sound_set_fade_in_milliseconds(&sound, -1, 0, 1000);
    ```

By default sounds will start immediately, but sometimes for timing and synchronization purposes it
can be useful to schedule a sound to start or stop:

    ```c
    // Start the sound in 1 second from now.
    ma_sound_set_start_time_in_pcm_frames(&sound, ma_engine_get_time(&engine) + (ma_engine_get_sample_rate(&engine) * 1));

    // Stop the sound in 2 seconds from now.
    ma_sound_set_stop_time_in_pcm_frames(&sound, ma_engine_get_time(&engine) + (ma_engine_get_sample_rate(&engine) * 2));
    ```

Note that scheduling a start time still requires an explicit call to `ma_sound_start()` before
anything will play.

The time is specified in global time which is controlled by the engine. You can get the engine's
current time with `ma_engine_get_time()`. The engine's global time is incremented automatically as
audio data is read, but it can be reset with `ma_engine_set_time()` in case it needs to be
resynchronized for some reason.

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

Whether or not a sound should loop can be controlled with `ma_sound_set_looping()`. Sounds will not
be looping by default. Use `ma_sound_is_looping()` to determine whether or not a sound is looping.

Use `ma_sound_at_end()` to determine whether or not a sound is currently at the end. For a looping
sound this should never return true.

Internally a sound wraps around a data source. Some APIs exist to control the underlying data
source, mainly for convenience:

    ```c
    ma_sound_seek_to_pcm_frame(&sound, frameIndex);
    ma_sound_get_data_format(&sound, &format, &channels, &sampleRate, pChannelMap, channelMapCapacity);
    ma_sound_get_cursor_in_pcm_frames(&sound, &cursor);
    ma_sound_get_length_in_pcm_frames(&sound, &length);
    ```

Sound groups have the same API as sounds, only they are called `ma_sound_group`, and since they do
not have any notion of a data source, anything relating to a data source is unavailable.

Internally, sound data is loaded via the `ma_decoder` API which means by default in only supports
file formats that have built-in support in miniaudio. You can extend this to support any kind of
file format through the use of custom decoders. To do this you'll need to use a self-managed
resource manager and configure it appropriately. See the "Resource Management" section below for
details on how to set this up.

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

    ```c
    ma_resource_manager_data_source dataSource;
    ma_result result = ma_resource_manager_data_source_init(pResourceManager, pFilePath, flags, &dataSource);
    if (result != MA_SUCCESS) {
        // Error.
    }

    // ...

    // A ma_resource_manager_data_source object is compatible with the `ma_data_source` API. To read data, just call
    // the `ma_data_source_read_pcm_frames()` like you would with any normal data source.
    result = ma_data_source_read_pcm_frames(&dataSource, pDecodedData, frameCount, &framesRead);
    if (result != MA_SUCCESS) {
        // Failed to read PCM frames.
    }

    // ...

    ma_resource_manager_data_source_uninit(pResourceManager, &dataSource);
    ```

The `flags` parameter specifies how you want to perform loading of the sound file. It can be a
combination of the following flags:

    ```
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT
    ```

When no flags are specified (set to 0), the sound will be fully loaded into memory, but not
decoded, meaning the raw file data will be stored in memory, and then dynamically decoded when
`ma_data_source_read_pcm_frames()` is called. To instead decode the audio data before storing it in
memory, use the `MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE` flag. By default, the sound file will
be loaded synchronously, meaning `ma_resource_manager_data_source_init()` will only return after
the entire file has been loaded. This is good for simplicity, but can be prohibitively slow. You
can instead load the sound asynchronously using the `MA_RESOURCE_MANAGER_DATA_SOURCE_ASYNC` flag.
This will result in `ma_resource_manager_data_source_init()` returning quickly, but no data will be
returned by `ma_data_source_read_pcm_frames()` until some data is available. When no data is
available because the asynchronous decoding hasn't caught up, `MA_BUSY` will be returned by
`ma_data_source_read_pcm_frames()`.

For large sounds, it's often prohibitive to store the entire file in memory. To mitigate this, you
can instead stream audio data which you can do by specifying the
`MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM` flag. When streaming, data will be decoded in 1
second pages. When a new page needs to be decoded, a job will be posted to the job queue and then
subsequently processed in a job thread.

For in-memory sounds, reference counting is used to ensure the data is loaded only once. This means
multiple calls to `ma_resource_manager_data_source_init()` with the same file path will result in
the file data only being loaded once. Each call to `ma_resource_manager_data_source_init()` must be

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

When a sound is being loaded asynchronously, playback can begin before the sound has been fully
decoded. This enables the application to start playback of the sound quickly, while at the same
time allowing to resource manager to keep loading in the background. Since there may be less
threads than the number of sounds being loaded at a given time, a simple scheduling system is used
to keep decoding time balanced and fair. The resource manager solves this by splitting decoding
into chunks called pages. By default, each page is 1 second long. When a page has been decoded, a
new job will be posted to start decoding the next page. By dividing up decoding into pages, an
individual sound shouldn't ever delay every other sound from having their first page decoded. Of
course, when loading many sounds at the same time, there will always be an amount of time required
to process jobs in the queue so in heavy load situations there will still be some delay. To
determine if a data source is ready to have some frames read, use
`ma_resource_manager_data_source_get_available_frames()`. This will return the number of frames
available starting from the current position.


6.2.1. Job Queue
----------------
The resource manager uses a job queue which is multi-producer, multi-consumer, and fixed-capacity.
This job queue is not currently lock-free, and instead uses a spinlock to achieve thread-safety.
Only a fixed number of jobs can be allocated and inserted into the queue which is done through a
lock-free data structure for allocating an index into a fixed sized array, with reference counting
for mitigation of the ABA problem. The reference count is 32-bit.

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

decode, the job will post another `MA_JOB_TYPE_RESOURCE_MANAGER_PAGE_DATA_BUFFER_NODE` job which will
keep on happening until the sound has been fully decoded. For sounds of an unknown length, each
page will be linked together as a linked list. Internally this is implemented via the
`ma_paged_audio_buffer` object.


6.2.3. Data Streams
-------------------
Data streams only ever store two pages worth of data for each instance. They are most useful for
large sounds like music tracks in games that would consume too much memory if fully decoded in
memory. After every frame from a page has been read, a job will be posted to load the next page
which is done from the VFS.

For data streams, the `MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC` flag will determine whether or
not initialization of the data source waits until the two pages have been decoded. When unset,
`ma_resource_manager_data_source_init()` will wait until the two pages have been loaded, otherwise
it will return immediately.

When frames are read from a data stream using `ma_resource_manager_data_source_read_pcm_frames()`,
`MA_BUSY` will be returned if there are no frames available. If there are some frames available,
but less than the number requested, `MA_SUCCESS` will be returned, but the actual number of frames
read will be less than the number requested. Due to the asynchronous nature of data streams,
seeking is also asynchronous. If the data stream is in the middle of a seek, `MA_BUSY` will be
returned when trying to read frames.

When `ma_resource_manager_data_source_read_pcm_frames()` results in a page getting fully consumed
a job is posted to load the next page. This will be posted from the same thread that called
`ma_resource_manager_data_source_read_pcm_frames()`.

Data streams are uninitialized by posting a job to the queue, but the function won't return until
that job has been processed. The reason for this is that the caller owns the data stream object and
therefore miniaudio needs to ensure everything completes before handing back control to the caller.
Also, if the data stream is uninitialized while pages are in the middle of decoding, they must
complete before destroying any underlying object and the job system handles this cleanly.

Note that when a new page needs to be loaded, a job will be posted to the resource manager's job
thread from the audio thread. You must keep in mind the details mentioned in the "Job Queue"
section above regarding locking when posting an event if you require a strictly lock-free audio

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

    ```

When you initialize the node graph, you're specifying the channel count of the endpoint. The
endpoint is a special node which has one input bus and one output bus, both of which have the
same channel count, which is specified in the config. Any nodes that connect directly to the
endpoint must be configured such that their output buses have the same channel count. When you read
audio data from the node graph, it'll have the channel count you specified in the config. To read
data from the graph:

    ```c
    ma_uint32 framesRead;
    result = ma_node_graph_read_pcm_frames(&nodeGraph, pFramesOut, frameCount, &framesRead);
    if (result != MA_SUCCESS) {
        // Failed to read data from the node graph.
    }
    ```

When you read audio data, miniaudio starts at the node graph's endpoint node which then pulls in
data from it's input attachments, which in turn recusively pull in data from their inputs, and so
on. At the start of the graph there will be some kind of data source node which will have zero
inputs and will instead read directly from a data source. The base nodes don't literally need to
read from a `ma_data_source` object, but they will always have some kind of underlying object that

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

`ma_node_detach_all_output_buses()`. If you want to just move the output bus from one attachment to
another, you do not need to detach first. You can just call `ma_node_attach_output_bus()` and it'll
deal with it for you.

Less frequently you may want to create a specialized node. This will be a node where you implement
your own processing callback to apply a custom effect of some kind. This is similar to initalizing
one of the stock node types, only this time you need to specify a pointer to a vtable containing a
pointer to the processing function and the number of input and output buses. Example:

    ```c
    static void my_custom_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
    {
        // Do some processing of ppFramesIn (one stream of audio data per input bus)
        const float* pFramesIn_0 = ppFramesIn[0]; // Input bus @ index 0.
        const float* pFramesIn_1 = ppFramesIn[1]; // Input bus @ index 1.
        float* pFramesOut_0 = ppFramesOut[0];     // Output bus @ index 0.

        // Do some processing. On input, `pFrameCountIn` will be the number of input frames in each
        // buffer in `ppFramesIn` and `pFrameCountOut` will be the capacity of each of the buffers
        // in `ppFramesOut`. On output, `pFrameCountIn` should be set to the number of input frames
        // your node consumed and `pFrameCountOut` should be set the number of output frames that
        // were produced.
        //
        // You should process as many frames as you can. If your effect consumes input frames at the
        // same rate as output frames (always the case, unless you're doing resampling), you need
        // only look at `ppFramesOut` and process that exact number of frames. If you're doing
        // resampling, you'll need to be sure to set both `pFrameCountIn` and `pFrameCountOut`
        // properly.
    }

    static ma_node_vtable my_custom_node_vtable =
    {
        my_custom_node_process_pcm_frames, // The function that will be called process your custom node. This is where you'd implement your effect processing.
        NULL,   // Optional. A callback for calculating the number of input frames that are required to process a specified number of output frames.
        2,      // 2 input buses.
        1,      // 1 output bus.
        0       // Default flags.
    };

    ...

    // Each bus needs to have a channel count specified. To do this you need to specify the channel
    // counts in an array and then pass that into the node config.
    ma_uint32 inputChannels[2];     // Equal in size to the number of input channels specified in the vtable.

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

    ```

When initializing a custom node, as in the code above, you'll normally just place your vtable in
static space. The number of input and output buses are specified as part of the vtable. If you need
a variable number of buses on a per-node bases, the vtable should have the relevant bus count set
to `MA_NODE_BUS_COUNT_UNKNOWN`. In this case, the bus count should be set in the node config:

    ```c
    static ma_node_vtable my_custom_node_vtable =
    {
        my_custom_node_process_pcm_frames, // The function that will be called process your custom node. This is where you'd implement your effect processing.
        NULL,   // Optional. A callback for calculating the number of input frames that are required to process a specified number of output frames.
        MA_NODE_BUS_COUNT_UNKNOWN,  // The number of input buses is determined on a per-node basis.
        1,      // 1 output bus.
        0       // Default flags.
    };

    ...

    ma_node_config nodeConfig = ma_node_config_init();
    nodeConfig.vtable          = &my_custom_node_vtable;
    nodeConfig.inputBusCount   = myBusCount;        // <-- Since the vtable specifies MA_NODE_BUS_COUNT_UNKNOWN, the input bus count should be set here.

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

    typedef struct
    {
        ma_node_base base; // <-- Make sure this is always the first member.
        float someCustomData;
    } my_custom_node;
    ```

By doing this, your object will be compatible with all `ma_node` APIs and you can attach it to the
graph just like any other node.

In the custom processing callback (`my_custom_node_process_pcm_frames()` in the example above), the
number of channels for each bus is what was specified by the config when the node was initialized
with `ma_node_init()`. In addition, all attachments to each of the input buses will have been
pre-mixed by miniaudio. The config allows you to specify different channel counts for each
individual input and output bus. It's up to the effect to handle it appropriate, and if it can't,
return an error in it's initialization routine.

Custom nodes can be assigned some flags to describe their behaviour. These are set via the vtable
and include the following:

    +-----------------------------------------+---------------------------------------------------+

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

    |                                         | when no data is available to be read from input   |
    |                                         | attachments. This is useful for effects like      |
    |                                         | echos where there will be a tail of audio data    |
    |                                         | that still needs to be processed even when the    |
    |                                         | original data sources have reached their ends.    |
    +-----------------------------------------+---------------------------------------------------+
    | MA_NODE_FLAG_ALLOW_NULL_INPUT           | Used in conjunction with                          |
    |                                         | `MA_NODE_FLAG_CONTINUOUS_PROCESSING`. When this   |
    |                                         | is set, the `ppFramesIn` parameter of the         |
    |                                         | processing callback will be set to NULL when      |
    |                                         | there are no input frames are available. When     |
    |                                         | this is unset, silence will be posted to the      |
    |                                         | processing callback.                              |
    +-----------------------------------------+---------------------------------------------------+
    | MA_NODE_FLAG_DIFFERENT_PROCESSING_RATES | Used to tell miniaudio that input and output      |
    |                                         | frames are processed at different rates. You      |
    |                                         | should set this for any nodes that perform        |
    |                                         | resampling.                                       |
    +-----------------------------------------+---------------------------------------------------+
    | MA_NODE_FLAG_SILENT_OUTPUT              | Used to tell miniaudio that a node produces only  |
    |                                         | silent output. This is useful for nodes where you |
    |                                         | don't want the output to contribute to the final  |
    |                                         | mix. An example might be if you want split your   |
    |                                         | stream and have one branch be output to a file.   |
    |                                         | When using this flag, you should avoid writing to |
    |                                         | the output buffer of the node's processing        |

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



7.1. Timing
-----------
The node graph supports starting and stopping nodes at scheduled times. This is especially useful
for data source nodes where you want to get the node set up, but only start playback at a specific
time. There are two clocks: local and global.

A local clock is per-node, whereas the global clock is per graph. Scheduling starts and stops can
only be done based on the global clock because the local clock will not be running while the node
is stopped. The global clocks advances whenever `ma_node_graph_read_pcm_frames()` is called. On the
other hand, the local clock only advances when the node's processing callback is fired, and is
advanced based on the output frame count.

To retrieve the global time, use `ma_node_graph_get_time()`. The global time can be set with
`ma_node_graph_set_time()` which might be useful if you want to do seeking on a global timeline.
Getting and setting the local time is similar. Use `ma_node_get_time()` to retrieve the local time,
and `ma_node_set_time()` to set the local time. The global and local times will be advanced by the
audio thread, so care should be taken to avoid data races. Ideally you should avoid calling these
outside of the node processing callbacks which are always run on the audio thread.

There is basic support for scheduling the starting and stopping of nodes. You can only schedule one
start and one stop at a time. This is mainly intended for putting nodes into a started or stopped
state in a frame-exact manner. Without this mechanism, starting and stopping of a node is limited
to the resolution of a call to `ma_node_graph_read_pcm_frames()` which would typically be in blocks
of several milliseconds. The following APIs can be used for scheduling node states:

    ```c
    ma_node_set_state_time()
    ma_node_get_state_time()
    ```

The time is absolute and must be based on the global clock. An example is below:

    ```c

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

Note that due to the nature of multi-threading the times may not be 100% exact. If this is an
issue, consider scheduling state changes from within a processing callback. An idea might be to
have some kind of passthrough trigger node that is used specifically for tracking time and handling
events.



7.2. Thread Safety and Locking
------------------------------
When processing audio, it's ideal not to have any kind of locking in the audio thread. Since it's
expected that `ma_node_graph_read_pcm_frames()` would be run on the audio thread, it does so
without the use of any locks. This section discusses the implementation used by miniaudio and goes
over some of the compromises employed by miniaudio to achieve this goal. Note that the current
implementation may not be ideal - feedback and critiques are most welcome.

The node graph API is not *entirely* lock-free. Only `ma_node_graph_read_pcm_frames()` is expected
to be lock-free. Attachment, detachment and uninitialization of nodes use locks to simplify the
implementation, but are crafted in a way such that such locking is not required when reading audio
data from the graph. Locking in these areas are achieved by means of spinlocks.

The main complication with keeping `ma_node_graph_read_pcm_frames()` lock-free stems from the fact
that a node can be uninitialized, and it's memory potentially freed, while in the middle of being
processed on the audio thread. There are times when the audio thread will be referencing a node,
which means the uninitialization process of a node needs to make sure it delays returning until the
audio thread is finished so that control is not handed back to the caller thereby giving them a
chance to free the node's memory.

When the audio thread is processing a node, it does so by reading from each of the output buses of
the node. In order for a node to process data for one of it's output buses, it needs to read from
each of it's input buses, and so on an so forth. It follows that once all output buses of a node
are detached, the node as a whole will be disconnected and no further processing will occur unless

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

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
is not supported. Also, items can only be added to the start of the list.

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

(the `NULL` argument in the example above) which allows you to configure the output format, channel
count, sample rate and channel map:

    ```c
    ma_decoder_config config = ma_decoder_config_init(ma_format_f32, 2, 48000);
    ```

When passing in `NULL` for decoder config in `ma_decoder_init*()`, the output format will be the
same as that defined by the decoding backend.

Data is read from the decoder as PCM frames. This will output the number of PCM frames actually
read. If this is less than the requested number of PCM frames it means you've reached the end. The
return value will be `MA_AT_END` if no samples have been read and the end has been reached.

    ```c
    ma_result result = ma_decoder_read_pcm_frames(pDecoder, pFrames, framesToRead, &framesRead);
    if (framesRead < framesToRead) {
        // Reached the end.
    }
    ```

You can also seek to a specific frame like so:

    ```c
    ma_result result = ma_decoder_seek_to_pcm_frame(pDecoder, targetFrame);
    if (result != MA_SUCCESS) {
        return false;   // An error occurred.
    }
    ```

If you want to loop back to the start, you can simply seek back to the first PCM frame:

    ```c
    ma_decoder_seek_to_pcm_frame(pDecoder, 0);
    ```

When loading a decoder, miniaudio uses a trial and error technique to find the appropriate decoding
backend. This can be unnecessarily inefficient if the type is already known. In this case you can
use `encodingFormat` variable in the device config to specify a specific encoding format you want
to decode:

    ```c
    decoderConfig.encodingFormat = ma_encoding_format_wav;
    ```

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

channel count and output sample rate. The following file types are supported:

    +------------------------+-------------+
    | Enum                   | Description |
    +------------------------+-------------+
    | ma_encoding_format_wav | WAV         |
    +------------------------+-------------+

If the format, channel count or sample rate is not supported by the output file type an error will
be returned. The encoder will not perform data conversion so you will need to convert it before
outputting any audio data. To output audio data, use `ma_encoder_write_pcm_frames()`, like in the
example below:

    ```c
    framesWritten = ma_encoder_write_pcm_frames(&encoder, pPCMFramesToWrite, framesToWrite);
    ```

Encoders must be uninitialized with `ma_encoder_uninit()`.



10. Data Conversion
===================
A data conversion API is included with miniaudio which supports the majority of data conversion
requirements. This supports conversion between sample formats, channel counts (with channel
mapping) and sample rates.


10.1. Sample Format Conversion
------------------------------
Conversion between sample formats is achieved with the `ma_pcm_*_to_*()`, `ma_pcm_convert()` and
`ma_convert_pcm_frames_format()` APIs. Use `ma_pcm_*_to_*()` to convert between two specific
formats. Use `ma_pcm_convert()` to convert based on a `ma_format` variable. Use
`ma_convert_pcm_frames_format()` to convert PCM frames where you want to specify the frame count
and channel count as a variable instead of the total sample count.


10.1.1. Dithering
-----------------
Dithering can be set using the ditherMode parameter.

The different dithering modes include the following, in order of efficiency:

    +-----------+--------------------------+

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

        2,                              // Output channels
        NULL,                           // Output channel map
        ma_channel_mix_mode_default);   // The mixing algorithm to use when combining channels.

    result = ma_channel_converter_init(&config, NULL, &converter);
    if (result != MA_SUCCESS) {
        // Error.
    }
    ```

To perform the conversion simply call `ma_channel_converter_process_pcm_frames()` like so:

    ```c
    ma_result result = ma_channel_converter_process_pcm_frames(&converter, pFramesOut, pFramesIn, frameCount);
    if (result != MA_SUCCESS) {
        // Error.
    }
    ```

It is up to the caller to ensure the output buffer is large enough to accomodate the new PCM
frames.

Input and output PCM frames are always interleaved. Deinterleaved layouts are not supported.


10.2.1. Channel Mapping
-----------------------
In addition to converting from one channel count to another, like the example above, the channel
converter can also be used to rearrange channels. When initializing the channel converter, you can
optionally pass in channel maps for both the input and output frames. If the channel counts are the
same, and each channel map contains the same channel positions with the exception that they're in
a different order, a simple shuffling of the channels will be performed. If, however, there is not
a 1:1 mapping of channel positions, or the channel counts differ, the input channels will be mixed
based on a mixing mode which is specified when initializing the `ma_channel_converter_config`
object.

When converting from mono to multi-channel, the mono channel is simply copied to each output
channel. When going the other way around, the audio of each output channel is simply averaged and
copied to the mono channel.

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


Do the following to uninitialize the resampler:

    ```c
    ma_resampler_uninit(&resampler);
    ```

The following example shows how data can be processed

    ```c
    ma_uint64 frameCountIn  = 1000;
    ma_uint64 frameCountOut = 2000;
    ma_result result = ma_resampler_process_pcm_frames(&resampler, pFramesIn, &frameCountIn, pFramesOut, &frameCountOut);
    if (result != MA_SUCCESS) {
        // An error occurred...
    }

    // At this point, frameCountIn contains the number of input frames that were consumed and frameCountOut contains the
    // number of output frames written.
    ```

To initialize the resampler you first need to set up a config (`ma_resampler_config`) with
`ma_resampler_config_init()`. You need to specify the sample format you want to use, the number of
channels, the input and output sample rate, and the algorithm.

The sample format can be either `ma_format_s16` or `ma_format_f32`. If you need a different format
you will need to perform pre- and post-conversions yourself where necessary. Note that the format
is the same for both input and output. The format cannot be changed after initialization.

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


    +-----------+------------------------------+
    | Algorithm | Enum Token                   |
    +-----------+------------------------------+
    | Linear    | ma_resample_algorithm_linear |
    | Custom    | ma_resample_algorithm_custom |
    +-----------+------------------------------+

The algorithm cannot be changed after initialization.

Processing always happens on a per PCM frame basis and always assumes interleaved input and output.
De-interleaved processing is not supported. To process frames, use
`ma_resampler_process_pcm_frames()`. On input, this function takes the number of output frames you
can fit in the output buffer and the number of input frames contained in the input buffer. On
output these variables contain the number of output frames that were written to the output buffer
and the number of input frames that were consumed in the process. You can pass in NULL for the
input buffer in which case it will be treated as an infinitely large buffer of zeros. The output
buffer can also be NULL, in which case the processing will be treated as seek.

The sample rate can be changed dynamically on the fly. You can change this with explicit sample
rates with `ma_resampler_set_rate()` and also with a decimal ratio with
`ma_resampler_set_rate_ratio()`. The ratio is in/out.

Sometimes it's useful to know exactly how many input frames will be required to output a specific
number of frames. You can calculate this with `ma_resampler_get_required_input_frame_count()`.
Likewise, it's sometimes useful to know exactly how many frames would be output given a certain
number of input frames. You can do this with `ma_resampler_get_expected_output_frame_count()`.

Due to the nature of how resampling works, the resampler introduces some latency. This can be
retrieved in terms of both the input rate and the output rate with
`ma_resampler_get_input_latency()` and `ma_resampler_get_output_latency()`.


10.3.1. Resampling Algorithms
-----------------------------
The choice of resampling algorithm depends on your situation and requirements.

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

functions in the vtable need to be implemented, but if it's possible to implement, they should be.

You can use the `ma_linear_resampler` object for an example on how to implement the vtable. The
`onGetHeapSize` callback is used to calculate the size of any internal heap allocation the custom
resampler will need to make given the supplied config. When you initialize the resampler via the
`onInit` callback, you'll be given a pointer to a heap allocation which is where you should store
the heap allocated data. You should not free this data in `onUninit` because miniaudio will manage
it for you.

The `onProcess` callback is where the actual resampling takes place. On input, `pFrameCountIn`
points to a variable containing the number of frames in the `pFramesIn` buffer and
`pFrameCountOut` points to a variable containing the capacity in frames of the `pFramesOut` buffer.
On output, `pFrameCountIn` should be set to the number of input frames that were fully consumed,
whereas `pFrameCountOut` should be set to the number of frames that were written to `pFramesOut`.

The `onSetRate` callback is optional and is used for dynamically changing the sample rate. If
dynamic rate changes are not supported, you can set this callback to NULL.

The `onGetInputLatency` and `onGetOutputLatency` functions are used for retrieving the latency in
input and output rates respectively. These can be NULL in which case latency calculations will be
assumed to be NULL.

The `onGetRequiredInputFrameCount` callback is used to give miniaudio a hint as to how many input
frames are required to be available to produce the given number of output frames. Likewise, the
`onGetExpectedOutputFrameCount` callback is used to determine how many output frames will be
produced given the specified number of input frames. miniaudio will use these as a hint, but they
are optional and can be set to NULL if you're unable to implement them.



10.4. General Data Conversion
-----------------------------
The `ma_data_converter` API can be used to wrap sample format conversion, channel conversion and
resampling into one operation. This is what miniaudio uses internally to convert between the format
requested when the device was initialized and the format of the backend's native device. The API
for general data conversion is very similar to the resampling API. Create a `ma_data_converter`

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


Do the following to uninitialize the data converter:

    ```c
    ma_data_converter_uninit(&converter, NULL);
    ```

The following example shows how data can be processed

    ```c
    ma_uint64 frameCountIn  = 1000;
    ma_uint64 frameCountOut = 2000;
    ma_result result = ma_data_converter_process_pcm_frames(&converter, pFramesIn, &frameCountIn, pFramesOut, &frameCountOut);
    if (result != MA_SUCCESS) {
        // An error occurred...
    }

    // At this point, frameCountIn contains the number of input frames that were consumed and frameCountOut contains the number
    // of output frames written.
    ```

The data converter supports multiple channels and is always interleaved (both input and output).
The channel count cannot be changed after initialization.

Sample rates can be anything other than zero, and are always specified in hertz. They should be set
to something like 44100, etc. The sample rate is the only configuration property that can be
changed after initialization, but only if the `resampling.allowDynamicSampleRate` member of
`ma_data_converter_config` is set to `MA_TRUE`. To change the sample rate, use
`ma_data_converter_set_rate()` or `ma_data_converter_set_rate_ratio()`. The ratio must be in/out.
The resampling algorithm cannot be changed after initialization.

Processing always happens on a per PCM frame basis and always assumes interleaved input and output.
De-interleaved processing is not supported. To process frames, use
`ma_data_converter_process_pcm_frames()`. On input, this function takes the number of output frames
you can fit in the output buffer and the number of input frames contained in the input buffer. On
output these variables contain the number of output frames that were written to the output buffer
and the number of input frames that were consumed in the process. You can pass in NULL for the
input buffer in which case it will be treated as an infinitely large
buffer of zeros. The output buffer can also be NULL, in which case the processing will be treated
as seek.

Sometimes it's useful to know exactly how many input frames will be required to output a specific
number of frames. You can calculate this with `ma_data_converter_get_required_input_frame_count()`.
Likewise, it's sometimes useful to know exactly how many frames would be output given a certain
number of input frames. You can do this with `ma_data_converter_get_expected_output_frame_count()`.

Due to the nature of how resampling works, the data converter introduces some latency if resampling
is required. This can be retrieved in terms of both the input rate and the output rate with
`ma_data_converter_get_input_latency()` and `ma_data_converter_get_output_latency()`.



11. Filtering
=============

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


    ```c
    ma_biquad_config config = ma_biquad_config_init(ma_format_f32, channels, b0, b1, b2, a0, a1, a2);
    ma_result result = ma_biquad_init(&config, &biquad);
    if (result != MA_SUCCESS) {
        // Error.
    }

    ...

    ma_biquad_process_pcm_frames(&biquad, pFramesOut, pFramesIn, frameCount);
    ```

Biquad filtering is implemented using transposed direct form 2. The numerator coefficients are b0,
b1 and b2, and the denominator coefficients are a0, a1 and a2. The a0 coefficient is required and
coefficients must not be pre-normalized.

Supported formats are `ma_format_s16` and `ma_format_f32`. If you need to use a different format
you need to convert it yourself beforehand. When using `ma_format_s16` the biquad filter will use
fixed point arithmetic. When using `ma_format_f32`, floating point arithmetic will be used.

Input and output frames are always interleaved.

Filtering can be applied in-place by passing in the same pointer for both the input and output
buffers, like so:

    ```c
    ma_biquad_process_pcm_frames(&biquad, pMyData, pMyData, frameCount);
    ```

If you need to change the values of the coefficients, but maintain the values in the registers you
can do so with `ma_biquad_reinit()`. This is useful if you need to change the properties of the
filter while keeping the values of registers valid to avoid glitching. Do not use
`ma_biquad_init()` for this as it will do a full initialization which involves clearing the
registers to 0. Note that changing the format or channel count after initialization is invalid and
will result in an error.


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


    ```c
    ma_lpf_config config = ma_lpf_config_init(ma_format_f32, channels, sampleRate, cutoffFrequency, order);
    ma_result result = ma_lpf_init(&config, &lpf);
    if (result != MA_SUCCESS) {
        // Error.
    }

    ...

    ma_lpf_process_pcm_frames(&lpf, pFramesOut, pFramesIn, frameCount);
    ```

Supported formats are `ma_format_s16` and` ma_format_f32`. If you need to use a different format
you need to convert it yourself beforehand. Input and output frames are always interleaved.

Filtering can be applied in-place by passing in the same pointer for both the input and output
buffers, like so:

    ```c
    ma_lpf_process_pcm_frames(&lpf, pMyData, pMyData, frameCount);
    ```

The maximum filter order is limited to `MA_MAX_FILTER_ORDER` which is set to 8. If you need more,
you can chain first and second order filters together.

    ```c
    for (iFilter = 0; iFilter < filterCount; iFilter += 1) {
        ma_lpf2_process_pcm_frames(&lpf2[iFilter], pMyData, pMyData, frameCount);
    }
    ```

If you need to change the configuration of the filter, but need to maintain the state of internal
registers you can do so with `ma_lpf_reinit()`. This may be useful if you need to change the sample
rate and/or cutoff frequency dynamically while maintaing smooth transitions. Note that changing the
format or channel count after initialization is invalid and will result in an error.

The `ma_lpf` object supports a configurable order, but if you only need a first order filter you
may want to consider using `ma_lpf1`. Likewise, if you only need a second order filter you can use

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

        frequency);

    ma_waveform waveform;
    ma_result result = ma_waveform_init(&config, &waveform);
    if (result != MA_SUCCESS) {
        // Error.
    }

    ...

    ma_waveform_read_pcm_frames(&waveform, pOutput, frameCount);
    ```

The amplitude, frequency, type, and sample rate can be changed dynamically with
`ma_waveform_set_amplitude()`, `ma_waveform_set_frequency()`, `ma_waveform_set_type()`, and
`ma_waveform_set_sample_rate()` respectively.

You can invert the waveform by setting the amplitude to a negative value. You can use this to
control whether or not a sawtooth has a positive or negative ramp, for example.

Below are the supported waveform types:

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

        amplitude);

    ma_noise noise;
    ma_result result = ma_noise_init(&config, &noise);
    if (result != MA_SUCCESS) {
        // Error.
    }

    ...

    ma_noise_read_pcm_frames(&noise, pOutput, frameCount);
    ```

The noise API uses simple LCG random number generation. It supports a custom seed which is useful
for things like automated testing requiring reproducibility. Setting the seed to zero will default
to `MA_DEFAULT_LCG_SEED`.

The amplitude, seed, and type can be changed dynamically with `ma_noise_set_amplitude()`,
`ma_noise_set_seed()`, and `ma_noise_set_type()` respectively.

By default, the noise API will use different values for different channels. So, for example, the

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

    ...

    ma_audio_buffer_uninit_and_free(&buffer);
    ```

If you initialize the buffer with `ma_audio_buffer_alloc_and_init()` you should uninitialize it
with `ma_audio_buffer_uninit_and_free()`. In the example above, the memory pointed to by
`pExistingData` will be copied into the buffer, which is contrary to the behavior of
`ma_audio_buffer_init()`.

An audio buffer has a playback cursor just like a decoder. As you read frames from the buffer, the
cursor moves forward. The last parameter (`loop`) can be used to determine if the buffer should
loop. The return value is the number of frames actually read. If this is less than the number of
frames requested it means the end has been reached. This should never happen if the `loop`
parameter is set to true. If you want to manually loop back to the start, you can do so with with
`ma_audio_buffer_seek_to_pcm_frame(pAudioBuffer, 0)`. Below is an example for reading data from an
audio buffer.

    ```c
    ma_uint64 framesRead = ma_audio_buffer_read_pcm_frames(pAudioBuffer, pFramesOut, desiredFrameCount, isLooping);
    if (framesRead < desiredFrameCount) {
        // If not looping, this means the end has been reached. This should never happen in looping mode with valid input.
    }
    ```

Sometimes you may want to avoid the cost of data movement between the internal buffer and the
output buffer. Instead you can use memory mapping to retrieve a pointer to a segment of data:

    ```c
    void* pMappedFrames;
    ma_uint64 frameCount = frameCountToTryMapping;
    ma_result result = ma_audio_buffer_map(pAudioBuffer, &pMappedFrames, &frameCount);
    if (result == MA_SUCCESS) {
        // Map was successful. The value in frameCount will be how many frames were _actually_ mapped, which may be
        // less due to the end of the buffer being reached.
        ma_copy_pcm_frames(pFramesOut, pMappedFrames, frameCount, pAudioBuffer->format, pAudioBuffer->channels);

        // You must unmap the buffer.
        ma_audio_buffer_unmap(pAudioBuffer, frameCount);
    }
    ```

When you use memory mapping, the read cursor is increment by the frame count passed in to
`ma_audio_buffer_unmap()`. If you decide not to process every frame you can pass in a value smaller
than the value returned by `ma_audio_buffer_map()`. The disadvantage to using memory mapping is
that it does not handle looping for you. You can determine if the buffer is at the end for the
purpose of looping with `ma_audio_buffer_at_end()` or by inspecting the return value of
`ma_audio_buffer_unmap()` and checking if it equals `MA_AT_END`. You should not treat `MA_AT_END`
as an error when returned by `ma_audio_buffer_unmap()`.



14. Ring Buffers
================
miniaudio supports lock free (single producer, single consumer) ring buffers which are exposed via
the `ma_rb` and `ma_pcm_rb` APIs. The `ma_rb` API operates on bytes, whereas the `ma_pcm_rb`
operates on PCM frames. They are otherwise identical as `ma_pcm_rb` is just a wrapper around
`ma_rb`.

Unlike most other APIs in miniaudio, ring buffers support both interleaved and deinterleaved
streams. The caller can also allocate their own backing memory for the ring buffer to use
internally for added flexibility. Otherwise the ring buffer will manage it's internal memory for
you.

The examples below use the PCM frame variant of the ring buffer since that's most likely the one
you will want to use. To initialize a ring buffer, do something like the following:

    ```c
    ma_pcm_rb rb;
    ma_result result = ma_pcm_rb_init(FORMAT, CHANNELS, BUFFER_SIZE_IN_FRAMES, NULL, NULL, &rb);
    if (result != MA_SUCCESS) {
        // Error
    }
    ```

The `ma_pcm_rb_init()` function takes the sample format and channel count as parameters because
it's the PCM varient of the ring buffer API. For the regular ring buffer that operates on bytes you
would call `ma_rb_init()` which leaves these out and just takes the size of the buffer in bytes
instead of frames. The fourth parameter is an optional pre-allocated buffer and the fifth parameter
is a pointer to a `ma_allocation_callbacks` structure for custom memory allocation routines.
Passing in `NULL` for this results in `MA_MALLOC()` and `MA_FREE()` being used.

Use `ma_pcm_rb_init_ex()` if you need a deinterleaved buffer. The data for each sub-buffer is
offset from each other based on the stride. To manage your sub-buffers you can use
`ma_pcm_rb_get_subbuffer_stride()`, `ma_pcm_rb_get_subbuffer_offset()` and
`ma_pcm_rb_get_subbuffer_ptr()`.

Use `ma_pcm_rb_acquire_read()` and `ma_pcm_rb_acquire_write()` to retrieve a pointer to a section
of the ring buffer. You specify the number of frames you need, and on output it will set to what
was actually acquired. If the read or write pointer is positioned such that the number of frames
requested will require a loop, it will be clamped to the end of the buffer. Therefore, the number
of frames you're given may be less than the number you requested.

After calling `ma_pcm_rb_acquire_read()` or `ma_pcm_rb_acquire_write()`, you do your work on the
buffer and then "commit" it with `ma_pcm_rb_commit_read()` or `ma_pcm_rb_commit_write()`. This is
where the read/write pointers are updated. When you commit you need to pass in the buffer that was
returned by the earlier call to `ma_pcm_rb_acquire_read()` or `ma_pcm_rb_acquire_write()` and is
only used for validation. The number of frames passed to `ma_pcm_rb_commit_read()` and
`ma_pcm_rb_commit_write()` is what's used to increment the pointers, and can be less that what was
originally requested.

If you want to correct for drift between the write pointer and the read pointer you can use a
combination of `ma_pcm_rb_pointer_distance()`, `ma_pcm_rb_seek_read()` and
`ma_pcm_rb_seek_write()`. Note that you can only move the pointers forward, and you should only
move the read pointer forward via the consumer thread, and the write pointer forward by the
producer thread. If there is too much space between the pointers, move the read pointer forward. If
there is too little space between the pointers, move the write pointer forward.

You can use a ring buffer at the byte level instead of the PCM frame level by using the `ma_rb`
API. This is exactly the same, only you will use the `ma_rb` functions instead of `ma_pcm_rb` and
instead of frame counts you will pass around byte counts.

The maximum size of the buffer in bytes is `0x7FFFFFFF-(MA_SIMD_ALIGNMENT-1)` due to the most
significant bit being used to encode a loop flag and the internally managed buffers always being
aligned to `MA_SIMD_ALIGNMENT`.

Note that the ring buffer is only thread safe when used by a single consumer thread and single
producer thread.



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

    void* _pHeap;
    ma_bool32 _ownsHeap;
} ma_biquad;

MA_API ma_result ma_biquad_get_heap_size(const ma_biquad_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_biquad_init_preallocated(const ma_biquad_config* pConfig, void* pHeap, ma_biquad* pBQ);
MA_API ma_result ma_biquad_init(const ma_biquad_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_biquad* pBQ);
MA_API void ma_biquad_uninit(ma_biquad* pBQ, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_biquad_reinit(const ma_biquad_config* pConfig, ma_biquad* pBQ);
MA_API ma_result ma_biquad_clear_cache(ma_biquad* pBQ);
MA_API ma_result ma_biquad_process_pcm_frames(ma_biquad* pBQ, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_biquad_get_latency(const ma_biquad* pBQ);


/**************************************************************************************************************************************************************

Low-Pass Filtering

**************************************************************************************************************************************************************/
typedef struct
{

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

    void* _pHeap;
    ma_bool32 _ownsHeap;
} ma_lpf1;

MA_API ma_result ma_lpf1_get_heap_size(const ma_lpf1_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_lpf1_init_preallocated(const ma_lpf1_config* pConfig, void* pHeap, ma_lpf1* pLPF);
MA_API ma_result ma_lpf1_init(const ma_lpf1_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_lpf1* pLPF);
MA_API void ma_lpf1_uninit(ma_lpf1* pLPF, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_lpf1_reinit(const ma_lpf1_config* pConfig, ma_lpf1* pLPF);
MA_API ma_result ma_lpf1_clear_cache(ma_lpf1* pLPF);
MA_API ma_result ma_lpf1_process_pcm_frames(ma_lpf1* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_lpf1_get_latency(const ma_lpf1* pLPF);

typedef struct
{
    ma_biquad bq;   /* The second order low-pass filter is implemented as a biquad filter. */
} ma_lpf2;

MA_API ma_result ma_lpf2_get_heap_size(const ma_lpf2_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_lpf2_init_preallocated(const ma_lpf2_config* pConfig, void* pHeap, ma_lpf2* pHPF);
MA_API ma_result ma_lpf2_init(const ma_lpf2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_lpf2* pLPF);
MA_API void ma_lpf2_uninit(ma_lpf2* pLPF, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_lpf2_reinit(const ma_lpf2_config* pConfig, ma_lpf2* pLPF);
MA_API ma_result ma_lpf2_clear_cache(ma_lpf2* pLPF);
MA_API ma_result ma_lpf2_process_pcm_frames(ma_lpf2* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_lpf2_get_latency(const ma_lpf2* pLPF);


typedef struct
{
    ma_format format;
    ma_uint32 channels;
    ma_uint32 sampleRate;
    double cutoffFrequency;
    ma_uint32 order;    /* If set to 0, will be treated as a passthrough (no filtering will be applied). */

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

    void* _pHeap;
    ma_bool32 _ownsHeap;
} ma_lpf;

MA_API ma_result ma_lpf_get_heap_size(const ma_lpf_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_lpf_init_preallocated(const ma_lpf_config* pConfig, void* pHeap, ma_lpf* pLPF);
MA_API ma_result ma_lpf_init(const ma_lpf_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_lpf* pLPF);
MA_API void ma_lpf_uninit(ma_lpf* pLPF, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_lpf_reinit(const ma_lpf_config* pConfig, ma_lpf* pLPF);
MA_API ma_result ma_lpf_clear_cache(ma_lpf* pLPF);
MA_API ma_result ma_lpf_process_pcm_frames(ma_lpf* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_lpf_get_latency(const ma_lpf* pLPF);


/**************************************************************************************************************************************************************

High-Pass Filtering

**************************************************************************************************************************************************************/
typedef struct
{

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

    /* Memory management. */
    void* _pHeap;
    ma_bool32 _ownsHeap;
} ma_hpf1;

MA_API ma_result ma_hpf1_get_heap_size(const ma_hpf1_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_hpf1_init_preallocated(const ma_hpf1_config* pConfig, void* pHeap, ma_hpf1* pLPF);
MA_API ma_result ma_hpf1_init(const ma_hpf1_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_hpf1* pHPF);
MA_API void ma_hpf1_uninit(ma_hpf1* pHPF, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_hpf1_reinit(const ma_hpf1_config* pConfig, ma_hpf1* pHPF);
MA_API ma_result ma_hpf1_process_pcm_frames(ma_hpf1* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_hpf1_get_latency(const ma_hpf1* pHPF);

typedef struct
{
    ma_biquad bq;   /* The second order high-pass filter is implemented as a biquad filter. */
} ma_hpf2;

MA_API ma_result ma_hpf2_get_heap_size(const ma_hpf2_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_hpf2_init_preallocated(const ma_hpf2_config* pConfig, void* pHeap, ma_hpf2* pHPF);
MA_API ma_result ma_hpf2_init(const ma_hpf2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_hpf2* pHPF);
MA_API void ma_hpf2_uninit(ma_hpf2* pHPF, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_hpf2_reinit(const ma_hpf2_config* pConfig, ma_hpf2* pHPF);
MA_API ma_result ma_hpf2_process_pcm_frames(ma_hpf2* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_hpf2_get_latency(const ma_hpf2* pHPF);


typedef struct
{
    ma_format format;
    ma_uint32 channels;
    ma_uint32 sampleRate;
    double cutoffFrequency;
    ma_uint32 order;    /* If set to 0, will be treated as a passthrough (no filtering will be applied). */

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

    /* Memory management. */
    void* _pHeap;
    ma_bool32 _ownsHeap;
} ma_hpf;

MA_API ma_result ma_hpf_get_heap_size(const ma_hpf_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_hpf_init_preallocated(const ma_hpf_config* pConfig, void* pHeap, ma_hpf* pLPF);
MA_API ma_result ma_hpf_init(const ma_hpf_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_hpf* pHPF);
MA_API void ma_hpf_uninit(ma_hpf* pHPF, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_hpf_reinit(const ma_hpf_config* pConfig, ma_hpf* pHPF);
MA_API ma_result ma_hpf_process_pcm_frames(ma_hpf* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_hpf_get_latency(const ma_hpf* pHPF);


/**************************************************************************************************************************************************************

Band-Pass Filtering

**************************************************************************************************************************************************************/
typedef struct
{

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

typedef struct
{
    ma_biquad bq;   /* The second order band-pass filter is implemented as a biquad filter. */
} ma_bpf2;

MA_API ma_result ma_bpf2_get_heap_size(const ma_bpf2_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_bpf2_init_preallocated(const ma_bpf2_config* pConfig, void* pHeap, ma_bpf2* pBPF);
MA_API ma_result ma_bpf2_init(const ma_bpf2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_bpf2* pBPF);
MA_API void ma_bpf2_uninit(ma_bpf2* pBPF, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_bpf2_reinit(const ma_bpf2_config* pConfig, ma_bpf2* pBPF);
MA_API ma_result ma_bpf2_process_pcm_frames(ma_bpf2* pBPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_bpf2_get_latency(const ma_bpf2* pBPF);


typedef struct
{
    ma_format format;
    ma_uint32 channels;
    ma_uint32 sampleRate;
    double cutoffFrequency;
    ma_uint32 order;    /* If set to 0, will be treated as a passthrough (no filtering will be applied). */

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

    /* Memory management. */
    void* _pHeap;
    ma_bool32 _ownsHeap;
} ma_bpf;

MA_API ma_result ma_bpf_get_heap_size(const ma_bpf_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_bpf_init_preallocated(const ma_bpf_config* pConfig, void* pHeap, ma_bpf* pBPF);
MA_API ma_result ma_bpf_init(const ma_bpf_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_bpf* pBPF);
MA_API void ma_bpf_uninit(ma_bpf* pBPF, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_bpf_reinit(const ma_bpf_config* pConfig, ma_bpf* pBPF);
MA_API ma_result ma_bpf_process_pcm_frames(ma_bpf* pBPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_bpf_get_latency(const ma_bpf* pBPF);


/**************************************************************************************************************************************************************

Notching Filter

**************************************************************************************************************************************************************/
typedef struct
{

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

typedef struct
{
    ma_biquad bq;
} ma_notch2;

MA_API ma_result ma_notch2_get_heap_size(const ma_notch2_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_notch2_init_preallocated(const ma_notch2_config* pConfig, void* pHeap, ma_notch2* pFilter);
MA_API ma_result ma_notch2_init(const ma_notch2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_notch2* pFilter);
MA_API void ma_notch2_uninit(ma_notch2* pFilter, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_notch2_reinit(const ma_notch2_config* pConfig, ma_notch2* pFilter);
MA_API ma_result ma_notch2_process_pcm_frames(ma_notch2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_notch2_get_latency(const ma_notch2* pFilter);


/**************************************************************************************************************************************************************

Peaking EQ Filter

**************************************************************************************************************************************************************/
typedef struct
{

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

typedef struct
{
    ma_biquad bq;
} ma_peak2;

MA_API ma_result ma_peak2_get_heap_size(const ma_peak2_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_peak2_init_preallocated(const ma_peak2_config* pConfig, void* pHeap, ma_peak2* pFilter);
MA_API ma_result ma_peak2_init(const ma_peak2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_peak2* pFilter);
MA_API void ma_peak2_uninit(ma_peak2* pFilter, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_peak2_reinit(const ma_peak2_config* pConfig, ma_peak2* pFilter);
MA_API ma_result ma_peak2_process_pcm_frames(ma_peak2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_peak2_get_latency(const ma_peak2* pFilter);


/**************************************************************************************************************************************************************

Low Shelf Filter

**************************************************************************************************************************************************************/
typedef struct
{

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

typedef struct
{
    ma_biquad bq;
} ma_loshelf2;

MA_API ma_result ma_loshelf2_get_heap_size(const ma_loshelf2_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_loshelf2_init_preallocated(const ma_loshelf2_config* pConfig, void* pHeap, ma_loshelf2* pFilter);
MA_API ma_result ma_loshelf2_init(const ma_loshelf2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_loshelf2* pFilter);
MA_API void ma_loshelf2_uninit(ma_loshelf2* pFilter, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_loshelf2_reinit(const ma_loshelf2_config* pConfig, ma_loshelf2* pFilter);
MA_API ma_result ma_loshelf2_process_pcm_frames(ma_loshelf2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_loshelf2_get_latency(const ma_loshelf2* pFilter);


/**************************************************************************************************************************************************************

High Shelf Filter

**************************************************************************************************************************************************************/
typedef struct
{

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

typedef struct
{
    ma_biquad bq;
} ma_hishelf2;

MA_API ma_result ma_hishelf2_get_heap_size(const ma_hishelf2_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_hishelf2_init_preallocated(const ma_hishelf2_config* pConfig, void* pHeap, ma_hishelf2* pFilter);
MA_API ma_result ma_hishelf2_init(const ma_hishelf2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_hishelf2* pFilter);
MA_API void ma_hishelf2_uninit(ma_hishelf2* pFilter, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_hishelf2_reinit(const ma_hishelf2_config* pConfig, ma_hishelf2* pFilter);
MA_API ma_result ma_hishelf2_process_pcm_frames(ma_hishelf2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_hishelf2_get_latency(const ma_hishelf2* pFilter);



/*
Delay
*/
typedef struct
{
    ma_uint32 channels;

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

typedef struct
{
    ma_delay_config config;
    ma_uint32 cursor;               /* Feedback is written to this cursor. Always equal or in front of the read cursor. */
    ma_uint32 bufferSizeInFrames;   /* The maximum of config.startDelayInFrames and config.feedbackDelayInFrames. */
    float* pBuffer;
} ma_delay;

MA_API ma_result ma_delay_init(const ma_delay_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_delay* pDelay);
MA_API void ma_delay_uninit(ma_delay* pDelay, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_delay_process_pcm_frames(ma_delay* pDelay, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount);
MA_API void ma_delay_set_wet(ma_delay* pDelay, float value);
MA_API float ma_delay_get_wet(const ma_delay* pDelay);
MA_API void ma_delay_set_dry(ma_delay* pDelay, float value);
MA_API float ma_delay_get_dry(const ma_delay* pDelay);
MA_API void ma_delay_set_decay(ma_delay* pDelay, float value);
MA_API float ma_delay_get_decay(const ma_delay* pDelay);


/* Gainer for smooth volume changes. */
typedef struct

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


    /* Memory management. */
    void* _pHeap;
    ma_bool32 _ownsHeap;
} ma_gainer;

MA_API ma_result ma_gainer_get_heap_size(const ma_gainer_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_gainer_init_preallocated(const ma_gainer_config* pConfig, void* pHeap, ma_gainer* pGainer);
MA_API ma_result ma_gainer_init(const ma_gainer_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_gainer* pGainer);
MA_API void ma_gainer_uninit(ma_gainer* pGainer, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_gainer_process_pcm_frames(ma_gainer* pGainer, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_result ma_gainer_set_gain(ma_gainer* pGainer, float newGain);
MA_API ma_result ma_gainer_set_gains(ma_gainer* pGainer, float* pNewGains);



/* Stereo panner. */
typedef enum
{
    ma_pan_mode_balance = 0,    /* Does not blend one side with the other. Technically just a balance. Compatible with other popular audio engines and therefore the default. */
    ma_pan_mode_pan             /* A true pan. The sound from one side will "move" to the other side and blend with it. */

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


typedef struct
{
    ma_format format;
    ma_uint32 channels;
    ma_pan_mode mode;
    float pan;  /* -1..1 where 0 is no pan, -1 is left side, +1 is right side. Defaults to 0. */
} ma_panner;

MA_API ma_result ma_panner_init(const ma_panner_config* pConfig, ma_panner* pPanner);
MA_API ma_result ma_panner_process_pcm_frames(ma_panner* pPanner, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API void ma_panner_set_mode(ma_panner* pPanner, ma_pan_mode mode);
MA_API ma_pan_mode ma_panner_get_mode(const ma_panner* pPanner);
MA_API void ma_panner_set_pan(ma_panner* pPanner, float pan);
MA_API float ma_panner_get_pan(const ma_panner* pPanner);



/* Fader. */
typedef struct
{
    ma_format format;
    ma_uint32 channels;
    ma_uint32 sampleRate;
} ma_fader_config;

MA_API ma_fader_config ma_fader_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate);

typedef struct
{
    ma_fader_config config;
    float volumeBeg;            /* If volumeBeg and volumeEnd is equal to 1, no fading happens (ma_fader_process_pcm_frames() will run as a passthrough). */
    float volumeEnd;
    ma_uint64 lengthInFrames;   /* The total length of the fade. */
    ma_uint64 cursorInFrames;   /* The current time in frames. Incremented by ma_fader_process_pcm_frames(). */
} ma_fader;

MA_API ma_result ma_fader_init(const ma_fader_config* pConfig, ma_fader* pFader);
MA_API ma_result ma_fader_process_pcm_frames(ma_fader* pFader, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API void ma_fader_get_data_format(const ma_fader* pFader, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
MA_API void ma_fader_set_fade(ma_fader* pFader, float volumeBeg, float volumeEnd, ma_uint64 lengthInFrames);
MA_API float ma_fader_get_current_volume(ma_fader* pFader);



/* Spatializer. */
typedef struct
{
    float x;

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

    float minGain;
    float maxGain;
    float minDistance;
    float maxDistance;
    float rolloff;
    float coneInnerAngleInRadians;
    float coneOuterAngleInRadians;
    float coneOuterGain;
    float dopplerFactor;                /* Set to 0 to disable doppler effect. */
    float directionalAttenuationFactor; /* Set to 0 to disable directional attenuation. */
    ma_uint32 gainSmoothTimeInFrames;   /* When the gain of a channel changes during spatialization, the transition will be linearly interpolated over this number of frames. */
} ma_spatializer_config;

MA_API ma_spatializer_config ma_spatializer_config_init(ma_uint32 channelsIn, ma_uint32 channelsOut);


typedef struct
{
    ma_uint32 channelsIn;
    ma_uint32 channelsOut;
    ma_channel* pChannelMapIn;

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

    float minGain;
    float maxGain;
    float minDistance;
    float maxDistance;
    float rolloff;
    float coneInnerAngleInRadians;
    float coneOuterAngleInRadians;
    float coneOuterGain;
    float dopplerFactor;                /* Set to 0 to disable doppler effect. */
    float directionalAttenuationFactor; /* Set to 0 to disable directional attenuation. */
    ma_uint32 gainSmoothTimeInFrames;   /* When the gain of a channel changes during spatialization, the transition will be linearly interpolated over this number of frames. */
    ma_vec3f position;
    ma_vec3f direction;
    ma_vec3f velocity;  /* For doppler effect. */
    float dopplerPitch; /* Will be updated by ma_spatializer_process_pcm_frames() and can be used by higher level functions to apply a pitch shift for doppler effect. */
    ma_gainer gainer;   /* For smooth gain transitions. */
    float* pNewChannelGainsOut; /* An offset of _pHeap. Used by ma_spatializer_process_pcm_frames() to store new channel gains. The number of elements in this array is equal to config.channelsOut. */

    /* Memory management. */
    void* _pHeap;
    ma_bool32 _ownsHeap;
} ma_spatializer;

MA_API ma_result ma_spatializer_get_heap_size(const ma_spatializer_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_spatializer_init_preallocated(const ma_spatializer_config* pConfig, void* pHeap, ma_spatializer* pSpatializer);
MA_API ma_result ma_spatializer_init(const ma_spatializer_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_spatializer* pSpatializer);
MA_API void ma_spatializer_uninit(ma_spatializer* pSpatializer, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_spatializer_process_pcm_frames(ma_spatializer* pSpatializer, ma_spatializer_listener* pListener, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_uint32 ma_spatializer_get_input_channels(const ma_spatializer* pSpatializer);
MA_API ma_uint32 ma_spatializer_get_output_channels(const ma_spatializer* pSpatializer);
MA_API void ma_spatializer_set_attenuation_model(ma_spatializer* pSpatializer, ma_attenuation_model attenuationModel);
MA_API ma_attenuation_model ma_spatializer_get_attenuation_model(const ma_spatializer* pSpatializer);
MA_API void ma_spatializer_set_positioning(ma_spatializer* pSpatializer, ma_positioning positioning);
MA_API ma_positioning ma_spatializer_get_positioning(const ma_spatializer* pSpatializer);
MA_API void ma_spatializer_set_rolloff(ma_spatializer* pSpatializer, float rolloff);
MA_API float ma_spatializer_get_rolloff(const ma_spatializer* pSpatializer);
MA_API void ma_spatializer_set_min_gain(ma_spatializer* pSpatializer, float minGain);
MA_API float ma_spatializer_get_min_gain(const ma_spatializer* pSpatializer);

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

{
    ma_linear_resampler_config config;
    ma_uint32 inAdvanceInt;
    ma_uint32 inAdvanceFrac;
    ma_uint32 inTimeInt;
    ma_uint32 inTimeFrac;
    union
    {
        float* f32;
        ma_int16* s16;
    } x0; /* The previous input frame. */
    union
    {
        float* f32;
        ma_int16* s16;
    } x1; /* The next input frame. */
    ma_lpf lpf;

    /* Memory management. */
    void* _pHeap;
    ma_bool32 _ownsHeap;
} ma_linear_resampler;

MA_API ma_result ma_linear_resampler_get_heap_size(const ma_linear_resampler_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_linear_resampler_init_preallocated(const ma_linear_resampler_config* pConfig, void* pHeap, ma_linear_resampler* pResampler);
MA_API ma_result ma_linear_resampler_init(const ma_linear_resampler_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_linear_resampler* pResampler);
MA_API void ma_linear_resampler_uninit(ma_linear_resampler* pResampler, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_linear_resampler_process_pcm_frames(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut);
MA_API ma_result ma_linear_resampler_set_rate(ma_linear_resampler* pResampler, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);
MA_API ma_result ma_linear_resampler_set_rate_ratio(ma_linear_resampler* pResampler, float ratioInOut);
MA_API ma_uint64 ma_linear_resampler_get_input_latency(const ma_linear_resampler* pResampler);
MA_API ma_uint64 ma_linear_resampler_get_output_latency(const ma_linear_resampler* pResampler);
MA_API ma_result ma_linear_resampler_get_required_input_frame_count(const ma_linear_resampler* pResampler, ma_uint64 outputFrameCount, ma_uint64* pInputFrameCount);
MA_API ma_result ma_linear_resampler_get_expected_output_frame_count(const ma_linear_resampler* pResampler, ma_uint64 inputFrameCount, ma_uint64* pOutputFrameCount);
MA_API ma_result ma_linear_resampler_reset(ma_linear_resampler* pResampler);


typedef struct ma_resampler_config ma_resampler_config;

typedef void ma_resampling_backend;
typedef struct
{
    ma_result (* onGetHeapSize                )(void* pUserData, const ma_resampler_config* pConfig, size_t* pHeapSizeInBytes);
    ma_result (* onInit                       )(void* pUserData, const ma_resampler_config* pConfig, void* pHeap, ma_resampling_backend** ppBackend);

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

MA_API ma_result ma_resampler_init(const ma_resampler_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_resampler* pResampler);

/*
Uninitializes a resampler.
*/
MA_API void ma_resampler_uninit(ma_resampler* pResampler, const ma_allocation_callbacks* pAllocationCallbacks);

/*
Converts the given input data.

Both the input and output frames must be in the format specified in the config when the resampler was initilized.

On input, [pFrameCountOut] contains the number of output frames to process. On output it contains the number of output frames that
were actually processed, which may be less than the requested amount which will happen if there's not enough input data. You can use
ma_resampler_get_expected_output_frame_count() to know how many output frames will be processed for a given number of input frames.

On input, [pFrameCountIn] contains the number of input frames contained in [pFramesIn]. On output it contains the number of whole
input frames that were actually processed. You can use ma_resampler_get_required_input_frame_count() to know how many input frames
you should provide for a given number of output frames. [pFramesIn] can be NULL, in which case zeroes will be used instead.

If [pFramesOut] is NULL, a seek is performed. In this case, if [pFrameCountOut] is not NULL it will seek by the specified number of
output frames. Otherwise, if [pFramesCountOut] is NULL and [pFrameCountIn] is not NULL, it will seek by the specified number of input
frames. When seeking, [pFramesIn] is allowed to NULL, in which case the internal timing state will be updated, but no input will be
processed. In this case, any internal filter state will be updated as if zeroes were passed in.

It is an error for [pFramesOut] to be non-NULL and [pFrameCountOut] to be NULL.

It is an error for both [pFrameCountOut] and [pFrameCountIn] to be NULL.
*/
MA_API ma_result ma_resampler_process_pcm_frames(ma_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut);


/*
Sets the input and output sample sample rate.
*/
MA_API ma_result ma_resampler_set_rate(ma_resampler* pResampler, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);

/*
Sets the input and output sample rate as a ratio.

The ration is in/out.
*/
MA_API ma_result ma_resampler_set_rate_ratio(ma_resampler* pResampler, float ratio);

/*
Retrieves the latency introduced by the resampler in input frames.
*/
MA_API ma_uint64 ma_resampler_get_input_latency(const ma_resampler* pResampler);

/*
Retrieves the latency introduced by the resampler in output frames.
*/
MA_API ma_uint64 ma_resampler_get_output_latency(const ma_resampler* pResampler);

/*
Calculates the number of whole input frames that would need to be read from the client in order to output the specified
number of output frames.

The returned value does not include cached input frames. It only returns the number of extra frames that would need to be
read from the input buffer in order to output the specified number of output frames.
*/
MA_API ma_result ma_resampler_get_required_input_frame_count(const ma_resampler* pResampler, ma_uint64 outputFrameCount, ma_uint64* pInputFrameCount);

/*
Calculates the number of whole output frames that would be output after fully reading and consuming the specified number of
input frames.
*/
MA_API ma_result ma_resampler_get_expected_output_frame_count(const ma_resampler* pResampler, ma_uint64 inputFrameCount, ma_uint64* pOutputFrameCount);

/*
Resets the resampler's timer and clears it's internal cache.
*/
MA_API ma_result ma_resampler_reset(ma_resampler* pResampler);


/**************************************************************************************************************************************************************

Channel Conversion

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


    /* Memory management. */
    void* _pHeap;
    ma_bool32 _ownsHeap;
} ma_channel_converter;

MA_API ma_result ma_channel_converter_get_heap_size(const ma_channel_converter_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_channel_converter_init_preallocated(const ma_channel_converter_config* pConfig, void* pHeap, ma_channel_converter* pConverter);
MA_API ma_result ma_channel_converter_init(const ma_channel_converter_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_channel_converter* pConverter);
MA_API void ma_channel_converter_uninit(ma_channel_converter* pConverter, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_channel_converter_process_pcm_frames(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
MA_API ma_result ma_channel_converter_get_input_channel_map(const ma_channel_converter* pConverter, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_channel_converter_get_output_channel_map(const ma_channel_converter* pConverter, ma_channel* pChannelMap, size_t channelMapCap);


/**************************************************************************************************************************************************************

Data Conversion

**************************************************************************************************************************************************************/
typedef struct

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


    /* Memory management. */
    ma_bool8 _ownsHeap;
    void* _pHeap;
} ma_data_converter;

MA_API ma_result ma_data_converter_get_heap_size(const ma_data_converter_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_data_converter_init_preallocated(const ma_data_converter_config* pConfig, void* pHeap, ma_data_converter* pConverter);
MA_API ma_result ma_data_converter_init(const ma_data_converter_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_converter* pConverter);
MA_API void ma_data_converter_uninit(ma_data_converter* pConverter, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_data_converter_process_pcm_frames(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut);
MA_API ma_result ma_data_converter_set_rate(ma_data_converter* pConverter, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);
MA_API ma_result ma_data_converter_set_rate_ratio(ma_data_converter* pConverter, float ratioInOut);
MA_API ma_uint64 ma_data_converter_get_input_latency(const ma_data_converter* pConverter);
MA_API ma_uint64 ma_data_converter_get_output_latency(const ma_data_converter* pConverter);
MA_API ma_result ma_data_converter_get_required_input_frame_count(const ma_data_converter* pConverter, ma_uint64 outputFrameCount, ma_uint64* pInputFrameCount);
MA_API ma_result ma_data_converter_get_expected_output_frame_count(const ma_data_converter* pConverter, ma_uint64 inputFrameCount, ma_uint64* pOutputFrameCount);
MA_API ma_result ma_data_converter_get_input_channel_map(const ma_data_converter* pConverter, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_data_converter_get_output_channel_map(const ma_data_converter* pConverter, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_data_converter_reset(ma_data_converter* pConverter);


/************************************************************************************************************************************************************

Format Conversion

************************************************************************************************************************************************************/

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

MA_API void ma_pcm_s24_to_f32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_s32_to_u8(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_s32_to_s16(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_s32_to_s24(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_s32_to_f32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_f32_to_u8(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_f32_to_s16(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_f32_to_s24(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_f32_to_s32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
MA_API void ma_pcm_convert(void* pOut, ma_format formatOut, const void* pIn, ma_format formatIn, ma_uint64 sampleCount, ma_dither_mode ditherMode);
MA_API void ma_convert_pcm_frames_format(void* pOut, ma_format formatOut, const void* pIn, ma_format formatIn, ma_uint64 frameCount, ma_uint32 channels, ma_dither_mode ditherMode);

/*
Deinterleaves an interleaved buffer.
*/
MA_API void ma_deinterleave_pcm_frames(ma_format format, ma_uint32 channels, ma_uint64 frameCount, const void* pInterleavedPCMFrames, void** ppDeinterleavedPCMFrames);

/*
Interleaves a group of deinterleaved buffers.
*/
MA_API void ma_interleave_pcm_frames(ma_format format, ma_uint32 channels, ma_uint64 frameCount, const void** ppDeinterleavedPCMFrames, void* pInterleavedPCMFrames);


/************************************************************************************************************************************************************

Channel Maps

************************************************************************************************************************************************************/
/*
This is used in the shuffle table to indicate that the channel index is undefined and should be ignored.
*/

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

MA_API ma_bool32 ma_channel_map_contains_channel_position(ma_uint32 channels, const ma_channel* pChannelMap, ma_channel channelPosition);


/************************************************************************************************************************************************************

Conversion Helpers

************************************************************************************************************************************************************/

/*
High-level helper for doing a full format conversion in one go. Returns the number of output frames. Call this with pOut set to NULL to
determine the required size of the output buffer. frameCountOut should be set to the capacity of pOut. If pOut is NULL, frameCountOut is
ignored.

A return value of 0 indicates an error.

This function is useful for one-off bulk conversions, but if you're streaming data you should use the ma_data_converter APIs instead.
*/
MA_API ma_uint64 ma_convert_frames(void* pOut, ma_uint64 frameCountOut, ma_format formatOut, ma_uint32 channelsOut, ma_uint32 sampleRateOut, const void* pIn, ma_uint64 frameCountIn, ma_format formatIn, ma_uint32 channelsIn, ma_uint32 sampleRateIn);
MA_API ma_uint64 ma_convert_frames_ex(void* pOut, ma_uint64 frameCountOut, const void* pIn, ma_uint64 frameCountIn, const ma_data_converter_config* pConfig);


/************************************************************************************************************************************************************

Ring Buffer

************************************************************************************************************************************************************/
typedef struct
{
    void* pBuffer;

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

MA_API ma_result ma_pcm_rb_init_ex(ma_format format, ma_uint32 channels, ma_uint32 subbufferSizeInFrames, ma_uint32 subbufferCount, ma_uint32 subbufferStrideInFrames, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallba...
MA_API ma_result ma_pcm_rb_init(ma_format format, ma_uint32 channels, ma_uint32 bufferSizeInFrames, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_pcm_rb* pRB);
MA_API void ma_pcm_rb_uninit(ma_pcm_rb* pRB);
MA_API void ma_pcm_rb_reset(ma_pcm_rb* pRB);
MA_API ma_result ma_pcm_rb_acquire_read(ma_pcm_rb* pRB, ma_uint32* pSizeInFrames, void** ppBufferOut);
MA_API ma_result ma_pcm_rb_commit_read(ma_pcm_rb* pRB, ma_uint32 sizeInFrames);
MA_API ma_result ma_pcm_rb_acquire_write(ma_pcm_rb* pRB, ma_uint32* pSizeInFrames, void** ppBufferOut);
MA_API ma_result ma_pcm_rb_commit_write(ma_pcm_rb* pRB, ma_uint32 sizeInFrames);
MA_API ma_result ma_pcm_rb_seek_read(ma_pcm_rb* pRB, ma_uint32 offsetInFrames);
MA_API ma_result ma_pcm_rb_seek_write(ma_pcm_rb* pRB, ma_uint32 offsetInFrames);
MA_API ma_int32 ma_pcm_rb_pointer_distance(ma_pcm_rb* pRB); /* Return value is in frames. */
MA_API ma_uint32 ma_pcm_rb_available_read(ma_pcm_rb* pRB);
MA_API ma_uint32 ma_pcm_rb_available_write(ma_pcm_rb* pRB);
MA_API ma_uint32 ma_pcm_rb_get_subbuffer_size(ma_pcm_rb* pRB);
MA_API ma_uint32 ma_pcm_rb_get_subbuffer_stride(ma_pcm_rb* pRB);
MA_API ma_uint32 ma_pcm_rb_get_subbuffer_offset(ma_pcm_rb* pRB, ma_uint32 subbufferIndex);
MA_API void* ma_pcm_rb_get_subbuffer_ptr(ma_pcm_rb* pRB, ma_uint32 subbufferIndex, void* pBuffer);


/*
The idea of the duplex ring buffer is to act as the intermediary buffer when running two asynchronous devices in a duplex set up. The
capture device writes to it, and then a playback device reads from it.

At the moment this is just a simple naive implementation, but in the future I want to implement some dynamic resampling to seamlessly
handle desyncs. Note that the API is work in progress and may change at any time in any version.

The size of the buffer is based on the capture side since that's what'll be written to the buffer. It is based on the capture period size
in frames. The internal sample rate of the capture device is also needed in order to calculate the size.
*/
typedef struct
{
    ma_pcm_rb rb;
} ma_duplex_rb;

MA_API ma_result ma_duplex_rb_init(ma_format captureFormat, ma_uint32 captureChannels, ma_uint32 sampleRate, ma_uint32 captureInternalSampleRate, ma_uint32 captureInternalPeriodSizeInFrames, const ma_allocation_callbacks* pAllocationCallbacks, ma_dup...
MA_API ma_result ma_duplex_rb_uninit(ma_duplex_rb* pRB);


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

Free's an aligned malloc'd buffer.
*/
MA_API void ma_aligned_free(void* p, const ma_allocation_callbacks* pAllocationCallbacks);

/*
Retrieves a friendly name for a format.
*/
MA_API const char* ma_get_format_name(ma_format format);

/*
Blends two frames in floating point format.
*/
MA_API void ma_blend_f32(float* pOut, float* pInA, float* pInB, float factor, ma_uint32 channels);

/*
Retrieves the size of a sample in bytes for the given format.

This API is efficient and is implemented using a lookup table.

Thread Safety: SAFE
  This API is pure.
*/
MA_API ma_uint32 ma_get_bytes_per_sample(ma_format format);
static MA_INLINE ma_uint32 ma_get_bytes_per_frame(ma_format format, ma_uint32 channels) { return ma_get_bytes_per_sample(format) * channels; }

/*
Converts a log level to a string.
*/
MA_API const char* ma_log_level_to_string(ma_uint32 logLevel);




/************************************************************************************************************************************************************

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

                ma_async_notification* pDoneNotification;
                ma_fence* pDoneFence;
            } freeDataBuffer;

            struct
            {
                /*ma_resource_manager_data_stream**/ void* pDataStream;
                char* pFilePath;                            /* Allocated when the job is posted, freed by the job thread after loading. */
                wchar_t* pFilePathW;                        /* ^ As above ^. Only used if pFilePath is NULL. */
                ma_uint64 initialSeekPoint;
                ma_async_notification* pInitNotification;   /* Signalled after the first two pages have been decoded and frames can be read from the stream. */
                ma_fence* pInitFence;
            } loadDataStream;
            struct
            {
                /*ma_resource_manager_data_stream**/ void* pDataStream;
                ma_async_notification* pDoneNotification;
                ma_fence* pDoneFence;
            } freeDataStream;
            struct
            {
                /*ma_resource_manager_data_stream**/ void* pDataStream;
                ma_uint32 pageIndex;                    /* The index of the page to decode into. */
            } pageDataStream;
            struct
            {
                /*ma_resource_manager_data_stream**/ void* pDataStream;
                ma_uint64 frameIndex;
            } seekDataStream;
        } resourceManager;

        /* Device. */
        union
        {
            union
            {
                struct
                {

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

due to things like an incoming phone call. Currently this is only implemented on iOS. None of the
Android backends will report this notification.
*/
typedef void (* ma_device_notification_proc)(const ma_device_notification* pNotification);


/*
The callback for processing audio data from the device.

The data callback is fired by miniaudio whenever the device needs to have more data delivered to a playback device, or when a capture device has some data
available. This is called as soon as the backend asks for more data which means it may be called with inconsistent frame counts. You cannot assume the
callback will be fired with a consistent frame count.


Parameters
----------
pDevice (in)
    A pointer to the relevant device.

pOutput (out)
    A pointer to the output buffer that will receive audio data that will later be played back through the speakers. This will be non-null for a playback or
    full-duplex device and null for a capture and loopback device.

pInput (in)
    A pointer to the buffer containing input data from a recording device. This will be non-null for a capture, full-duplex or loopback device and null for a
    playback device.

frameCount (in)
    The number of PCM frames to process. Note that this will not necessarily be equal to what you requested when you initialized the device. The
    `periodSizeInFrames` and `periodSizeInMilliseconds` members of the device config are just hints, and are not necessarily exactly what you'll get. You must
    not assume this will always be the same value each time the callback is fired.


Remarks
-------
You cannot stop and start the device from inside the callback or else you'll get a deadlock. You must also not uninitialize the device from inside the
callback. The following APIs cannot be called from inside the callback:

    ma_device_init()
    ma_device_init_ex()
    ma_device_uninit()
    ma_device_start()
    ma_device_stop()

The proper way to stop the device is to call `ma_device_stop()` from a different thread, normally the main application thread.
*/
typedef void (* ma_device_data_proc)(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);




/*
DEPRECATED. Use ma_device_notification_proc instead.

The callback for when the device has been stopped.

This will be called when the device is stopped explicitly with `ma_device_stop()` and also called implicitly when the device is stopped through external forces

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

the data format is set to what the application wants. On output it's set to the native format which should match as closely as possible to
the requested format. The conversion between the format requested by the application and the device's native format will be handled
internally by miniaudio.

On input, if the sample format is set to `ma_format_unknown`, the backend is free to use whatever sample format it desires, so long as it's
supported by miniaudio. When the channel count is set to 0, the backend should use the device's native channel count. The same applies for
sample rate. For the channel map, the default should be used when `ma_channel_map_is_blank()` returns true (all channels set to
`MA_CHANNEL_NONE`). On input, the `periodSizeInFrames` or `periodSizeInMilliseconds` option should always be set. The backend should
inspect both of these variables. If `periodSizeInFrames` is set, it should take priority, otherwise it needs to be derived from the period
size in milliseconds (`periodSizeInMilliseconds`) and the sample rate, keeping in mind that the sample rate may be 0, in which case the
sample rate will need to be determined before calculating the period size in frames. On output, all members of the `ma_device_data_format`
object should be set to a valid value, except for `periodSizeInMilliseconds` which is optional (`periodSizeInFrames` *must* be set).

Starting and stopping of the device is done with `onDeviceStart()` and `onDeviceStop()` and should be self-explanatory. If the backend uses
asynchronous reading and writing, `onDeviceStart()` and `onDeviceStop()` should always be implemented.

The handling of data delivery between the application and the device is the most complicated part of the process. To make this a bit
easier, some helper callbacks are available. If the backend uses a blocking read/write style of API, the `onDeviceRead()` and
`onDeviceWrite()` callbacks can optionally be implemented. These are blocking and work just like reading and writing from a file. If the
backend uses a callback for data delivery, that callback must call `ma_device_handle_backend_data_callback()` from within it's callback.
This allows miniaudio to then process any necessary data conversion and then pass it to the miniaudio data callback.

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

struct ma_backend_callbacks
{
    ma_result (* onContextInit)(ma_context* pContext, const ma_context_config* pConfig, ma_backend_callbacks* pCallbacks);
    ma_result (* onContextUninit)(ma_context* pContext);
    ma_result (* onContextEnumerateDevices)(ma_context* pContext, ma_enum_devices_callback_proc callback, void* pUserData);
    ma_result (* onContextGetDeviceInfo)(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_device_info* pDeviceInfo);
    ma_result (* onDeviceInit)(ma_device* pDevice, const ma_device_config* pConfig, ma_device_descriptor* pDescriptorPlayback, ma_device_descriptor* pDescriptorCapture);
    ma_result (* onDeviceUninit)(ma_device* pDevice);
    ma_result (* onDeviceStart)(ma_device* pDevice);
    ma_result (* onDeviceStop)(ma_device* pDevice);
    ma_result (* onDeviceRead)(ma_device* pDevice, void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesRead);
    ma_result (* onDeviceWrite)(ma_device* pDevice, const void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten);
    ma_result (* onDeviceDataLoop)(ma_device* pDevice);
    ma_result (* onDeviceDataLoopWakeup)(ma_device* pDevice);
    ma_result (* onDeviceGetInfo)(ma_device* pDevice, ma_device_type type, ma_device_info* pDeviceInfo);
};

struct ma_context_config
{
    ma_log* pLog;
    ma_thread_priority threadPriority;
    size_t threadStackSize;

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

        ma_format internalFormat;
        ma_uint32 internalChannels;
        ma_uint32 internalSampleRate;
        ma_channel internalChannelMap[MA_MAX_CHANNELS];
        ma_uint32 internalPeriodSizeInFrames;
        ma_uint32 internalPeriods;
        ma_channel_mix_mode channelMixMode;
        ma_data_converter converter;
        void* pIntermediaryBuffer;          /* For implementing fixed sized buffer callbacks. Will be null if using variable sized callbacks. */
        ma_uint32 intermediaryBufferCap;
        ma_uint32 intermediaryBufferLen;    /* How many valid frames are sitting in the intermediary buffer. */
        void* pInputCache;                  /* In external format. Can be null. */
        ma_uint64 inputCacheCap;
        ma_uint64 inputCacheConsumed;
        ma_uint64 inputCacheRemaining;
    } playback;
    struct
    {
        ma_device_id* pID;                  /* Set to NULL if using default ID, otherwise set to the address of "id". */
        ma_device_id id;                    /* If using an explicit device, will be set to a copy of the ID used for initialization. Otherwise cleared to 0. */
        char name[MA_MAX_DEVICE_NAME_LENGTH + 1];                     /* Maybe temporary. Likely to be replaced with a query API. */

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

        ma_format internalFormat;
        ma_uint32 internalChannels;
        ma_uint32 internalSampleRate;
        ma_channel internalChannelMap[MA_MAX_CHANNELS];
        ma_uint32 internalPeriodSizeInFrames;
        ma_uint32 internalPeriods;
        ma_channel_mix_mode channelMixMode;
        ma_data_converter converter;
        void* pIntermediaryBuffer;          /* For implementing fixed sized buffer callbacks. Will be null if using variable sized callbacks. */
        ma_uint32 intermediaryBufferCap;
        ma_uint32 intermediaryBufferLen;    /* How many valid frames are sitting in the intermediary buffer. */
    } capture;

    union
    {
#ifdef MA_SUPPORT_WASAPI
        struct
        {
            /*IAudioClient**/ ma_ptr pAudioClientPlayback;
            /*IAudioClient**/ ma_ptr pAudioClientCapture;
            /*IAudioRenderClient**/ ma_ptr pRenderClient;

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

#ifdef MA_SUPPORT_WINMM
        struct
        {
            /*HWAVEOUT*/ ma_handle hDevicePlayback;
            /*HWAVEIN*/ ma_handle hDeviceCapture;
            /*HANDLE*/ ma_handle hEventPlayback;
            /*HANDLE*/ ma_handle hEventCapture;
            ma_uint32 fragmentSizeInFrames;
            ma_uint32 iNextHeaderPlayback;             /* [0,periods). Used as an index into pWAVEHDRPlayback. */
            ma_uint32 iNextHeaderCapture;              /* [0,periods). Used as an index into pWAVEHDRCapture. */
            ma_uint32 headerFramesConsumedPlayback;    /* The number of PCM frames consumed in the buffer in pWAVEHEADER[iNextHeader]. */
            ma_uint32 headerFramesConsumedCapture;     /* ^^^ */
            /*WAVEHDR**/ ma_uint8* pWAVEHDRPlayback;   /* One instantiation for each period. */
            /*WAVEHDR**/ ma_uint8* pWAVEHDRCapture;    /* One instantiation for each period. */
            ma_uint8* pIntermediaryBufferPlayback;
            ma_uint8* pIntermediaryBufferCapture;
            ma_uint8* _pHeapData;                      /* Used internally and is used for the heap allocated data for the intermediary buffer and the WAVEHDR structures. */
        } winmm;
#endif
#ifdef MA_SUPPORT_ALSA
        struct

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

        } jack;
#endif
#ifdef MA_SUPPORT_COREAUDIO
        struct
        {
            ma_uint32 deviceObjectIDPlayback;
            ma_uint32 deviceObjectIDCapture;
            /*AudioUnit*/ ma_ptr audioUnitPlayback;
            /*AudioUnit*/ ma_ptr audioUnitCapture;
            /*AudioBufferList**/ ma_ptr pAudioBufferList;   /* Only used for input devices. */
            ma_uint32 audioBufferCapInFrames;               /* Only used for input devices. The capacity in frames of each buffer in pAudioBufferList. */
            ma_event stopEvent;
            ma_uint32 originalPeriodSizeInFrames;
            ma_uint32 originalPeriodSizeInMilliseconds;
            ma_uint32 originalPeriods;
            ma_performance_profile originalPerformanceProfile;
            ma_bool32 isDefaultPlaybackDevice;
            ma_bool32 isDefaultCaptureDevice;
            ma_bool32 isSwitchingPlaybackDevice;   /* <-- Set to true when the default device has changed and miniaudio is in the process of switching. */
            ma_bool32 isSwitchingCaptureDevice;    /* <-- Set to true when the default device has changed and miniaudio is in the process of switching. */
            void* pNotificationHandler;             /* Only used on mobile platforms. Obj-C object for handling route changes. */

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



/*
Initializes a device.

A device represents a physical audio device. The idea is you send or receive audio data from the device to either play it back through a speaker, or capture it
from a microphone. Whether or not you should send or receive data from the device (or both) depends on the type of device you are initializing which can be
playback, capture, full-duplex or loopback. (Note that loopback mode is only supported on select backends.) Sending and receiving audio data to and from the
device is done via a callback which is fired by miniaudio at periodic time intervals.

The frequency at which data is delivered to and from a device depends on the size of it's period. The size of the period can be defined in terms of PCM frames
or milliseconds, whichever is more convenient. Generally speaking, the smaller the period, the lower the latency at the expense of higher CPU usage and
increased risk of glitching due to the more frequent and granular data deliver intervals. The size of a period will depend on your requirements, but
miniaudio's defaults should work fine for most scenarios. If you're building a game you should leave this fairly small, whereas if you're building a simple
media player you can make it larger. Note that the period size you request is actually just a hint - miniaudio will tell the backend what you want, but the
backend is ultimately responsible for what it gives you. You cannot assume you will get exactly what you ask for.

When delivering data to and from a device you need to make sure it's in the correct format which you can set through the device configuration. You just set the
format that you want to use and miniaudio will perform all of the necessary conversion for you internally. When delivering data to and from the callback you
can assume the format is the same as what you requested when you initialized the device. See Remarks for more details on miniaudio's data conversion pipeline.

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

The device can be configured via the `pConfig` argument. The config object is initialized with `ma_device_config_init()`. Individual configuration settings can
then be set directly on the structure. Below are the members of the `ma_device_config` object.

    deviceType
        Must be `ma_device_type_playback`, `ma_device_type_capture`, `ma_device_type_duplex` of `ma_device_type_loopback`.

    sampleRate
        The sample rate, in hertz. The most common sample rates are 48000 and 44100. Setting this to 0 will use the device's native sample rate.

    periodSizeInFrames
        The desired size of a period in PCM frames. If this is 0, `periodSizeInMilliseconds` will be used instead. If both are 0 the default buffer size will
        be used depending on the selected performance profile. This value affects latency. See below for details.

    periodSizeInMilliseconds
        The desired size of a period in milliseconds. If this is 0, `periodSizeInFrames` will be used instead. If both are 0 the default buffer size will be
        used depending on the selected performance profile. The value affects latency. See below for details.

    periods
        The number of periods making up the device's entire buffer. The total buffer size is `periodSizeInFrames` or `periodSizeInMilliseconds` multiplied by
        this value. This is just a hint as backends will be the ones who ultimately decide how your periods will be configured.

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


    noClip
        When set to true, the contents of the output buffer passed into the data callback will be clipped after returning. When set to false (default), the
        contents of the output buffer are left alone after returning and it will be left up to the backend itself to decide whether or not the clip. This only
        applies when the playback sample format is f32.

    noDisableDenormals
        By default, miniaudio will disable denormals when the data callback is called. Setting this to true will prevent the disabling of denormals.

    noFixedSizedCallback
        Allows miniaudio to fire the data callback with any frame count. When this is set to true, the data callback will be fired with a consistent frame
        count as specified by `periodSizeInFrames` or `periodSizeInMilliseconds`. When set to false, miniaudio will fire the callback with whatever the
        backend requests, which could be anything.

    dataCallback
        The callback to fire whenever data is ready to be delivered to or from the device.

    notificationCallback
        The callback to fire when something has changed with the device, such as whether or not it has been started or stopped.

    pUserData

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

/*
Called from the data callback of asynchronous backends to allow miniaudio to process the data and fire the miniaudio data callback.


Parameters
----------
pDevice (in)
    A pointer to device whose processing the data callback.

pOutput (out)
    A pointer to the buffer that will receive the output PCM frame data. On a playback device this must not be NULL. On a duplex device
    this can be NULL, in which case pInput must not be NULL.

pInput (in)
    A pointer to the buffer containing input PCM frame data. On a capture device this must not be NULL. On a duplex device this can be
    NULL, in which case `pOutput` must not be NULL.

frameCount (in)
    The number of frames being processed.


Return Value
------------
MA_SUCCESS if successful; any other result code otherwise.


Thread Safety
-------------
This function should only ever be called from the internal data callback of the backend. It is safe to call this simultaneously between a

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



Remarks
-------
If both `pOutput` and `pInput` are NULL, and error will be returned. In duplex scenarios, both `pOutput` and `pInput` can be non-NULL, in
which case `pInput` will be processed first, followed by `pOutput`.

If you are implementing a custom backend, and that backend uses a callback for data delivery, you'll need to call this from inside that
callback.
*/
MA_API ma_result ma_device_handle_backend_data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);


/*
Calculates an appropriate buffer size from a descriptor, native sample rate and performance profile.

This function is used by backends for helping determine an appropriately sized buffer to use with
the device depending on the values of `periodSizeInFrames` and `periodSizeInMilliseconds` in the
`pDescriptor` object. Since buffer size calculations based on time depends on the sample rate, a
best guess at the device's native sample rate is also required which is where `nativeSampleRate`
comes in. In addition, the performance profile is also needed for cases where both the period size
in frames and milliseconds are both zero.


Parameters
----------
pDescriptor (in)
    A pointer to device descriptor whose `periodSizeInFrames` and `periodSizeInMilliseconds` members
    will be used for the calculation of the buffer size.

nativeSampleRate (in)
    The device's native sample rate. This is only ever used when the `periodSizeInFrames` member of
    `pDescriptor` is zero. In this case, `periodSizeInMilliseconds` will be used instead, in which
    case a sample rate is required to convert to a size in frames.

performanceProfile (in)
    When both the `periodSizeInFrames` and `periodSizeInMilliseconds` members of `pDescriptor` are
    zero, miniaudio will fall back to a buffer size based on the performance profile. The profile
    to use for this calculation is determine by this parameter.


Return Value
------------
The calculated buffer size in frames.


Thread Safety
-------------
This is safe so long as nothing modifies `pDescriptor` at the same time. However, this function
should only ever be called from within the backend's device initialization routine and therefore
shouldn't have any multithreading concerns.


Callback Safety
---------------
This is safe to call within the data callback, but there is no reason to ever do this.


Remarks
-------
If `nativeSampleRate` is zero, this function will fall back to `pDescriptor->sampleRate`. If that
is also zero, `MA_DEFAULT_SAMPLE_RATE` will be used instead.
*/
MA_API ma_uint32 ma_calculate_buffer_size_in_frames_from_descriptor(const ma_device_descriptor* pDescriptor, ma_uint32 nativeSampleRate, ma_performance_profile performanceProfile);



/*
Retrieves a friendly name for a backend.
*/
MA_API const char* ma_get_backend_name(ma_backend backend);

/*
Determines whether or not the given backend is available by the compilation environment.

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




/************************************************************************************************************************************************************

Utiltities

************************************************************************************************************************************************************/

/*
Calculates a buffer size in milliseconds from the specified number of frames and sample rate.
*/
MA_API ma_uint32 ma_calculate_buffer_size_in_milliseconds_from_frames(ma_uint32 bufferSizeInFrames, ma_uint32 sampleRate);

/*
Calculates a buffer size in frames from the specified number of milliseconds and sample rate.
*/
MA_API ma_uint32 ma_calculate_buffer_size_in_frames_from_milliseconds(ma_uint32 bufferSizeInMilliseconds, ma_uint32 sampleRate);

/*
Copies PCM frames from one buffer to another.
*/
MA_API void ma_copy_pcm_frames(void* dst, const void* src, ma_uint64 frameCount, ma_format format, ma_uint32 channels);

/*
Copies silent frames into the given buffer.

Remarks
-------
For all formats except `ma_format_u8`, the output buffer will be filled with 0. For `ma_format_u8` it will be filled with 128. The reason for this is that it
makes more sense for the purpose of mixing to initialize it to the center point.
*/
MA_API void ma_silence_pcm_frames(void* p, ma_uint64 frameCount, ma_format format, ma_uint32 channels);


/*
Offsets a pointer by the specified number of PCM frames.
*/
MA_API void* ma_offset_pcm_frames_ptr(void* p, ma_uint64 offsetInFrames, ma_format format, ma_uint32 channels);
MA_API const void* ma_offset_pcm_frames_const_ptr(const void* p, ma_uint64 offsetInFrames, ma_format format, ma_uint32 channels);
static MA_INLINE float* ma_offset_pcm_frames_ptr_f32(float* p, ma_uint64 offsetInFrames, ma_uint32 channels) { return (float*)ma_offset_pcm_frames_ptr((void*)p, offsetInFrames, ma_format_f32, channels); }
static MA_INLINE const float* ma_offset_pcm_frames_const_ptr_f32(const float* p, ma_uint64 offsetInFrames, ma_uint32 channels) { return (const float*)ma_offset_pcm_frames_const_ptr((const void*)p, offsetInFrames, ma_format_f32, channels); }


/*
Clips samples.
*/
MA_API void ma_clip_samples_u8(ma_uint8* pDst, const ma_int16* pSrc, ma_uint64 count);
MA_API void ma_clip_samples_s16(ma_int16* pDst, const ma_int32* pSrc, ma_uint64 count);
MA_API void ma_clip_samples_s24(ma_uint8* pDst, const ma_int64* pSrc, ma_uint64 count);
MA_API void ma_clip_samples_s32(ma_int32* pDst, const ma_int64* pSrc, ma_uint64 count);
MA_API void ma_clip_samples_f32(float* pDst, const float* pSrc, ma_uint64 count);
MA_API void ma_clip_pcm_frames(void* pDst, const void* pSrc, ma_uint64 frameCount, ma_format format, ma_uint32 channels);

/*
Helper for applying a volume factor to samples.

Note that the source and destination buffers can be the same, in which case it'll perform the operation in-place.
*/
MA_API void ma_copy_and_apply_volume_factor_u8(ma_uint8* pSamplesOut, const ma_uint8* pSamplesIn, ma_uint64 sampleCount, float factor);
MA_API void ma_copy_and_apply_volume_factor_s16(ma_int16* pSamplesOut, const ma_int16* pSamplesIn, ma_uint64 sampleCount, float factor);
MA_API void ma_copy_and_apply_volume_factor_s24(void* pSamplesOut, const void* pSamplesIn, ma_uint64 sampleCount, float factor);
MA_API void ma_copy_and_apply_volume_factor_s32(ma_int32* pSamplesOut, const ma_int32* pSamplesIn, ma_uint64 sampleCount, float factor);
MA_API void ma_copy_and_apply_volume_factor_f32(float* pSamplesOut, const float* pSamplesIn, ma_uint64 sampleCount, float factor);

MA_API void ma_apply_volume_factor_u8(ma_uint8* pSamples, ma_uint64 sampleCount, float factor);
MA_API void ma_apply_volume_factor_s16(ma_int16* pSamples, ma_uint64 sampleCount, float factor);
MA_API void ma_apply_volume_factor_s24(void* pSamples, ma_uint64 sampleCount, float factor);
MA_API void ma_apply_volume_factor_s32(ma_int32* pSamples, ma_uint64 sampleCount, float factor);
MA_API void ma_apply_volume_factor_f32(float* pSamples, ma_uint64 sampleCount, float factor);

MA_API void ma_copy_and_apply_volume_factor_pcm_frames_u8(ma_uint8* pFramesOut, const ma_uint8* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s16(ma_int16* pFramesOut, const ma_int16* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s24(void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s32(ma_int32* pFramesOut, const ma_int32* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_copy_and_apply_volume_factor_pcm_frames_f32(float* pFramesOut, const float* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_copy_and_apply_volume_factor_pcm_frames(void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float factor);

MA_API void ma_apply_volume_factor_pcm_frames_u8(ma_uint8* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_apply_volume_factor_pcm_frames_s16(ma_int16* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_apply_volume_factor_pcm_frames_s24(void* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_apply_volume_factor_pcm_frames_s32(ma_int32* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_apply_volume_factor_pcm_frames_f32(float* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
MA_API void ma_apply_volume_factor_pcm_frames(void* pFrames, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float factor);

MA_API void ma_copy_and_apply_volume_factor_per_channel_f32(float* pFramesOut, const float* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float* pChannelGains);


MA_API void ma_copy_and_apply_volume_and_clip_samples_u8(ma_uint8* pDst, const ma_int16* pSrc, ma_uint64 count, float volume);
MA_API void ma_copy_and_apply_volume_and_clip_samples_s16(ma_int16* pDst, const ma_int32* pSrc, ma_uint64 count, float volume);
MA_API void ma_copy_and_apply_volume_and_clip_samples_s24(ma_uint8* pDst, const ma_int64* pSrc, ma_uint64 count, float volume);
MA_API void ma_copy_and_apply_volume_and_clip_samples_s32(ma_int32* pDst, const ma_int64* pSrc, ma_uint64 count, float volume);
MA_API void ma_copy_and_apply_volume_and_clip_samples_f32(float* pDst, const float* pSrc, ma_uint64 count, float volume);
MA_API void ma_copy_and_apply_volume_and_clip_pcm_frames(void* pDst, const void* pSrc, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float volume);


/*
Helper for converting a linear factor to gain in decibels.
*/
MA_API float ma_volume_linear_to_db(float factor);

/*
Helper for converting gain in decibels to a linear factor.
*/

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


Data Source

**************************************************************************************************/
typedef void ma_data_source;

#define MA_DATA_SOURCE_SELF_MANAGED_RANGE_AND_LOOP_POINT    0x00000001

typedef struct
{
    ma_result (* onRead)(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
    ma_result (* onSeek)(ma_data_source* pDataSource, ma_uint64 frameIndex);
    ma_result (* onGetDataFormat)(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
    ma_result (* onGetCursor)(ma_data_source* pDataSource, ma_uint64* pCursor);
    ma_result (* onGetLength)(ma_data_source* pDataSource, ma_uint64* pLength);
    ma_result (* onSetLooping)(ma_data_source* pDataSource, ma_bool32 isLooping);
    ma_uint32 flags;
} ma_data_source_vtable;

typedef ma_data_source* (* ma_data_source_get_next_proc)(ma_data_source* pDataSource);

typedef struct

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

    ma_uint64 loopBegInFrames;              /* Relative to rangeBegInFrames. */
    ma_uint64 loopEndInFrames;              /* Relative to rangeBegInFrames. Set to -1 for the end of the range. */
    ma_data_source* pCurrent;               /* When non-NULL, the data source being initialized will act as a proxy and will route all operations to pCurrent. Used in conjunction with pNext/onGetNext for seamless chaining. */
    ma_data_source* pNext;                  /* When set to NULL, onGetNext will be used. */
    ma_data_source_get_next_proc onGetNext; /* Will be used when pNext is NULL. If both are NULL, no next will be used. */
    MA_ATOMIC(4, ma_bool32) isLooping;
} ma_data_source_base;

MA_API ma_result ma_data_source_init(const ma_data_source_config* pConfig, ma_data_source* pDataSource);
MA_API void ma_data_source_uninit(ma_data_source* pDataSource);
MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);   /* Must support pFramesOut = NULL in which case a forward seek should be performed. */
MA_API ma_result ma_data_source_seek_pcm_frames(ma_data_source* pDataSource, ma_uint64 frameCount, ma_uint64* pFramesSeeked); /* Can only seek forward. Equivalent to ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount, &framesRead); */
MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, ma_uint64 frameIndex);
MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor);
MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLength);    /* Returns MA_NOT_IMPLEMENTED if the length is unknown or cannot be determined. Decoders can return this. */
MA_API ma_result ma_data_source_get_cursor_in_seconds(ma_data_source* pDataSource, float* pCursor);
MA_API ma_result ma_data_source_get_length_in_seconds(ma_data_source* pDataSource, float* pLength);
MA_API ma_result ma_data_source_set_looping(ma_data_source* pDataSource, ma_bool32 isLooping);
MA_API ma_bool32 ma_data_source_is_looping(const ma_data_source* pDataSource);
MA_API ma_result ma_data_source_set_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 rangeBegInFrames, ma_uint64 rangeEndInFrames);
MA_API void ma_data_source_get_range_in_pcm_frames(const ma_data_source* pDataSource, ma_uint64* pRangeBegInFrames, ma_uint64* pRangeEndInFrames);
MA_API ma_result ma_data_source_set_loop_point_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 loopBegInFrames, ma_uint64 loopEndInFrames);
MA_API void ma_data_source_get_loop_point_in_pcm_frames(const ma_data_source* pDataSource, ma_uint64* pLoopBegInFrames, ma_uint64* pLoopEndInFrames);
MA_API ma_result ma_data_source_set_current(ma_data_source* pDataSource, ma_data_source* pCurrentDataSource);
MA_API ma_data_source* ma_data_source_get_current(const ma_data_source* pDataSource);
MA_API ma_result ma_data_source_set_next(ma_data_source* pDataSource, ma_data_source* pNextDataSource);
MA_API ma_data_source* ma_data_source_get_next(const ma_data_source* pDataSource);
MA_API ma_result ma_data_source_set_next_callback(ma_data_source* pDataSource, ma_data_source_get_next_proc onGetNext);
MA_API ma_data_source_get_next_proc ma_data_source_get_next_callback(const ma_data_source* pDataSource);


typedef struct
{

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

    ma_uint32 channels;
    ma_uint32 sampleRate;
    ma_uint64 cursor;
    ma_uint64 sizeInFrames;
    const void* pData;
} ma_audio_buffer_ref;

MA_API ma_result ma_audio_buffer_ref_init(ma_format format, ma_uint32 channels, const void* pData, ma_uint64 sizeInFrames, ma_audio_buffer_ref* pAudioBufferRef);
MA_API void ma_audio_buffer_ref_uninit(ma_audio_buffer_ref* pAudioBufferRef);
MA_API ma_result ma_audio_buffer_ref_set_data(ma_audio_buffer_ref* pAudioBufferRef, const void* pData, ma_uint64 sizeInFrames);
MA_API ma_uint64 ma_audio_buffer_ref_read_pcm_frames(ma_audio_buffer_ref* pAudioBufferRef, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop);
MA_API ma_result ma_audio_buffer_ref_seek_to_pcm_frame(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameIndex);
MA_API ma_result ma_audio_buffer_ref_map(ma_audio_buffer_ref* pAudioBufferRef, void** ppFramesOut, ma_uint64* pFrameCount);
MA_API ma_result ma_audio_buffer_ref_unmap(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameCount);    /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
MA_API ma_bool32 ma_audio_buffer_ref_at_end(const ma_audio_buffer_ref* pAudioBufferRef);
MA_API ma_result ma_audio_buffer_ref_get_cursor_in_pcm_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pCursor);
MA_API ma_result ma_audio_buffer_ref_get_length_in_pcm_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pLength);
MA_API ma_result ma_audio_buffer_ref_get_available_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pAvailableFrames);



typedef struct
{
    ma_format format;
    ma_uint32 channels;
    ma_uint32 sampleRate;
    ma_uint64 sizeInFrames;
    const void* pData;  /* If set to NULL, will allocate a block of memory for you. */

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

    ma_allocation_callbacks allocationCallbacks;
    ma_bool32 ownsData;             /* Used to control whether or not miniaudio owns the data buffer. If set to true, pData will be freed in ma_audio_buffer_uninit(). */
    ma_uint8 _pExtraData[1];        /* For allocating a buffer with the memory located directly after the other memory of the structure. */
} ma_audio_buffer;

MA_API ma_result ma_audio_buffer_init(const ma_audio_buffer_config* pConfig, ma_audio_buffer* pAudioBuffer);
MA_API ma_result ma_audio_buffer_init_copy(const ma_audio_buffer_config* pConfig, ma_audio_buffer* pAudioBuffer);
MA_API ma_result ma_audio_buffer_alloc_and_init(const ma_audio_buffer_config* pConfig, ma_audio_buffer** ppAudioBuffer);  /* Always copies the data. Doesn't make sense to use this otherwise. Use ma_audio_buffer_uninit_and_free() to uninit. */
MA_API void ma_audio_buffer_uninit(ma_audio_buffer* pAudioBuffer);
MA_API void ma_audio_buffer_uninit_and_free(ma_audio_buffer* pAudioBuffer);
MA_API ma_uint64 ma_audio_buffer_read_pcm_frames(ma_audio_buffer* pAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop);
MA_API ma_result ma_audio_buffer_seek_to_pcm_frame(ma_audio_buffer* pAudioBuffer, ma_uint64 frameIndex);
MA_API ma_result ma_audio_buffer_map(ma_audio_buffer* pAudioBuffer, void** ppFramesOut, ma_uint64* pFrameCount);
MA_API ma_result ma_audio_buffer_unmap(ma_audio_buffer* pAudioBuffer, ma_uint64 frameCount);    /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
MA_API ma_bool32 ma_audio_buffer_at_end(const ma_audio_buffer* pAudioBuffer);
MA_API ma_result ma_audio_buffer_get_cursor_in_pcm_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pCursor);
MA_API ma_result ma_audio_buffer_get_length_in_pcm_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pLength);
MA_API ma_result ma_audio_buffer_get_available_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pAvailableFrames);


/*
Paged Audio Buffer
==================
A paged audio buffer is made up of a linked list of pages. It's expandable, but not shrinkable. It
can be used for cases where audio data is streamed in asynchronously while allowing data to be read
at the same time.

This is lock-free, but not 100% thread safe. You can append a page and read from the buffer across

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

    ma_format format;
    ma_uint32 channels;
    ma_paged_audio_buffer_page head;                                /* Dummy head for the lock-free algorithm. Always has a size of 0. */
    MA_ATOMIC(MA_SIZEOF_PTR, ma_paged_audio_buffer_page*) pTail;    /* Never null. Initially set to &head. */
} ma_paged_audio_buffer_data;

MA_API ma_result ma_paged_audio_buffer_data_init(ma_format format, ma_uint32 channels, ma_paged_audio_buffer_data* pData);
MA_API void ma_paged_audio_buffer_data_uninit(ma_paged_audio_buffer_data* pData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_paged_audio_buffer_page* ma_paged_audio_buffer_data_get_head(ma_paged_audio_buffer_data* pData);
MA_API ma_paged_audio_buffer_page* ma_paged_audio_buffer_data_get_tail(ma_paged_audio_buffer_data* pData);
MA_API ma_result ma_paged_audio_buffer_data_get_length_in_pcm_frames(ma_paged_audio_buffer_data* pData, ma_uint64* pLength);
MA_API ma_result ma_paged_audio_buffer_data_allocate_page(ma_paged_audio_buffer_data* pData, ma_uint64 pageSizeInFrames, const void* pInitialData, const ma_allocation_callbacks* pAllocationCallbacks, ma_paged_audio_buffer_page** ppPage);
MA_API ma_result ma_paged_audio_buffer_data_free_page(ma_paged_audio_buffer_data* pData, ma_paged_audio_buffer_page* pPage, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_paged_audio_buffer_data_append_page(ma_paged_audio_buffer_data* pData, ma_paged_audio_buffer_page* pPage);
MA_API ma_result ma_paged_audio_buffer_data_allocate_and_append_page(ma_paged_audio_buffer_data* pData, ma_uint32 pageSizeInFrames, const void* pInitialData, const ma_allocation_callbacks* pAllocationCallbacks);


typedef struct
{
    ma_paged_audio_buffer_data* pData;  /* Must not be null. */
} ma_paged_audio_buffer_config;

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

{
    ma_data_source_base ds;
    ma_paged_audio_buffer_data* pData;              /* Audio data is read from here. Cannot be null. */
    ma_paged_audio_buffer_page* pCurrent;
    ma_uint64 relativeCursor;                       /* Relative to the current page. */
    ma_uint64 absoluteCursor;
} ma_paged_audio_buffer;

MA_API ma_result ma_paged_audio_buffer_init(const ma_paged_audio_buffer_config* pConfig, ma_paged_audio_buffer* pPagedAudioBuffer);
MA_API void ma_paged_audio_buffer_uninit(ma_paged_audio_buffer* pPagedAudioBuffer);
MA_API ma_result ma_paged_audio_buffer_read_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);   /* Returns MA_AT_END if no more pages available. */
MA_API ma_result ma_paged_audio_buffer_seek_to_pcm_frame(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64 frameIndex);
MA_API ma_result ma_paged_audio_buffer_get_cursor_in_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64* pCursor);
MA_API ma_result ma_paged_audio_buffer_get_length_in_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64* pLength);



/************************************************************************************************************************************************************

VFS
===

The VFS object (virtual file system) is what's used to customize file access. This is useful in cases where stdio FILE* based APIs may not be entirely
appropriate for a given situation.

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

struct ma_decoder
{
    ma_data_source_base ds;
    ma_data_source* pBackend;                   /* The decoding backend we'll be pulling data from. */
    const ma_decoding_backend_vtable* pBackendVTable; /* The vtable for the decoding backend. This needs to be stored so we can access the onUninit() callback. */
    void* pBackendUserData;
    ma_decoder_read_proc onRead;
    ma_decoder_seek_proc onSeek;
    ma_decoder_tell_proc onTell;
    void* pUserData;
    ma_uint64 readPointerInPCMFrames;      /* In output sample rate. Used for keeping track of how many frames are available for decoding. */
    ma_format outputFormat;
    ma_uint32 outputChannels;
    ma_uint32 outputSampleRate;
    ma_data_converter converter;    /* Data conversion is achieved by running frames through this. */
    void* pInputCache;              /* In input format. Can be null if it's not needed. */
    ma_uint64 inputCacheCap;        /* The capacity of the input cache. */
    ma_uint64 inputCacheConsumed;   /* The number of frames that have been consumed in the cache. Used for determining the next valid frame. */
    ma_uint64 inputCacheRemaining;  /* The number of valid frames remaining in the cahce. */
    ma_allocation_callbacks allocationCallbacks;
    union
    {
        struct
        {
            ma_vfs* pVFS;
            ma_vfs_file file;
        } vfs;
        struct
        {

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

MA_API ma_result ma_decoder_init_vfs_w(ma_vfs* pVFS, const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
MA_API ma_result ma_decoder_init_file(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
MA_API ma_result ma_decoder_init_file_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);

/*
Uninitializes a decoder.
*/
MA_API ma_result ma_decoder_uninit(ma_decoder* pDecoder);

/*
Reads PCM frames from the given decoder.

This is not thread safe without your own synchronization.
*/
MA_API ma_result ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);

/*
Seeks to a PCM frame based on it's absolute index.

This is not thread safe without your own synchronization.
*/
MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 frameIndex);

/*
Retrieves the decoder's output data format.
*/
MA_API ma_result ma_decoder_get_data_format(ma_decoder* pDecoder, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);

/*
Retrieves the current position of the read cursor in PCM frames.
*/
MA_API ma_result ma_decoder_get_cursor_in_pcm_frames(ma_decoder* pDecoder, ma_uint64* pCursor);

/*
Retrieves the length of the decoder in PCM frames.

Do not call this on streams of an undefined length, such as internet radio.

If the length is unknown or an error occurs, 0 will be returned.

This will always return 0 for Vorbis decoders. This is due to a limitation with stb_vorbis in push mode which is what miniaudio
uses internally.

For MP3's, this will decode the entire file. Do not call this in time critical scenarios.

This function is not thread safe without your own synchronization.
*/
MA_API ma_result ma_decoder_get_length_in_pcm_frames(ma_decoder* pDecoder, ma_uint64* pLength);

/*
Retrieves the number of frames that can be read before reaching the end.

This calls `ma_decoder_get_length_in_pcm_frames()` so you need to be aware of the rules for that function, in
particular ensuring you do not call it on streams of an undefined length, such as internet radio.

If the total length of the decoder cannot be retrieved, such as with Vorbis decoders, `MA_NOT_IMPLEMENTED` will be
returned.
*/
MA_API ma_result ma_decoder_get_available_frames(ma_decoder* pDecoder, ma_uint64* pAvailableFrames);

/*
Helper for opening and decoding a file into a heap allocated block of memory. Free the returned pointer with ma_free(). On input,
pConfig should be set to what you want. On output it will be set to what you got.
*/
MA_API ma_result ma_decode_from_vfs(ma_vfs* pVFS, const char* pFilePath, ma_decoder_config* pConfig, ma_uint64* pFrameCountOut, void** ppPCMFramesOut);
MA_API ma_result ma_decode_file(const char* pFilePath, ma_decoder_config* pConfig, ma_uint64* pFrameCountOut, void** ppPCMFramesOut);
MA_API ma_result ma_decode_memory(const void* pData, size_t dataSize, ma_decoder_config* pConfig, ma_uint64* pFrameCountOut, void** ppPCMFramesOut);

#endif  /* MA_NO_DECODING */

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

Encoders do not perform any format conversion for you. If your target format does not support the format, and error will be returned.

************************************************************************************************************************************************************/
#ifndef MA_NO_ENCODING
typedef struct ma_encoder ma_encoder;

typedef ma_result (* ma_encoder_write_proc)           (ma_encoder* pEncoder, const void* pBufferIn, size_t bytesToWrite, size_t* pBytesWritten);
typedef ma_result (* ma_encoder_seek_proc)            (ma_encoder* pEncoder, ma_int64 offset, ma_seek_origin origin);
typedef ma_result (* ma_encoder_init_proc)            (ma_encoder* pEncoder);
typedef void      (* ma_encoder_uninit_proc)          (ma_encoder* pEncoder);
typedef ma_result (* ma_encoder_write_pcm_frames_proc)(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount, ma_uint64* pFramesWritten);

typedef struct
{
    ma_encoding_format encodingFormat;
    ma_format format;
    ma_uint32 channels;
    ma_uint32 sampleRate;
    ma_allocation_callbacks allocationCallbacks;
} ma_encoder_config;

MA_API ma_encoder_config ma_encoder_config_init(ma_encoding_format encodingFormat, ma_format format, ma_uint32 channels, ma_uint32 sampleRate);

struct ma_encoder
{
    ma_encoder_config config;
    ma_encoder_write_proc onWrite;
    ma_encoder_seek_proc onSeek;
    ma_encoder_init_proc onInit;
    ma_encoder_uninit_proc onUninit;
    ma_encoder_write_pcm_frames_proc onWritePCMFrames;
    void* pUserData;
    void* pInternalEncoder; /* <-- The drwav/drflac/stb_vorbis/etc. objects. */
    union
    {
        struct
        {
            ma_vfs* pVFS;
            ma_vfs_file file;
        } vfs;
    } data;
};

MA_API ma_result ma_encoder_init(ma_encoder_write_proc onWrite, ma_encoder_seek_proc onSeek, void* pUserData, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
MA_API ma_result ma_encoder_init_vfs(ma_vfs* pVFS, const char* pFilePath, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
MA_API ma_result ma_encoder_init_vfs_w(ma_vfs* pVFS, const wchar_t* pFilePath, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
MA_API ma_result ma_encoder_init_file(const char* pFilePath, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
MA_API ma_result ma_encoder_init_file_w(const wchar_t* pFilePath, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
MA_API void ma_encoder_uninit(ma_encoder* pEncoder);
MA_API ma_result ma_encoder_write_pcm_frames(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount, ma_uint64* pFramesWritten);

#endif /* MA_NO_ENCODING */


/************************************************************************************************************************************************************

Generation

************************************************************************************************************************************************************/
#ifndef MA_NO_GENERATION

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

typedef struct
{
    ma_data_source_base ds;
    ma_waveform_config config;
    double advance;
    double time;
} ma_waveform;

MA_API ma_result ma_waveform_init(const ma_waveform_config* pConfig, ma_waveform* pWaveform);
MA_API void ma_waveform_uninit(ma_waveform* pWaveform);
MA_API ma_result ma_waveform_read_pcm_frames(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_waveform_seek_to_pcm_frame(ma_waveform* pWaveform, ma_uint64 frameIndex);
MA_API ma_result ma_waveform_set_amplitude(ma_waveform* pWaveform, double amplitude);
MA_API ma_result ma_waveform_set_frequency(ma_waveform* pWaveform, double frequency);
MA_API ma_result ma_waveform_set_type(ma_waveform* pWaveform, ma_waveform_type type);
MA_API ma_result ma_waveform_set_sample_rate(ma_waveform* pWaveform, ma_uint32 sampleRate);

typedef enum
{
    ma_noise_type_white,
    ma_noise_type_pink,
    ma_noise_type_brownian

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


    /* Memory management. */
    void* _pHeap;
    ma_bool32 _ownsHeap;
} ma_noise;

MA_API ma_result ma_noise_get_heap_size(const ma_noise_config* pConfig, size_t* pHeapSizeInBytes);
MA_API ma_result ma_noise_init_preallocated(const ma_noise_config* pConfig, void* pHeap, ma_noise* pNoise);
MA_API ma_result ma_noise_init(const ma_noise_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_noise* pNoise);
MA_API void ma_noise_uninit(ma_noise* pNoise, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_noise_read_pcm_frames(ma_noise* pNoise, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_noise_set_amplitude(ma_noise* pNoise, double amplitude);
MA_API ma_result ma_noise_set_seed(ma_noise* pNoise, ma_int32 seed);
MA_API ma_result ma_noise_set_type(ma_noise* pNoise, ma_noise_type type);

#endif  /* MA_NO_GENERATION */



/************************************************************************************************************************************************************

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

typedef struct ma_resource_manager_data_buffer      ma_resource_manager_data_buffer;
typedef struct ma_resource_manager_data_stream      ma_resource_manager_data_stream;
typedef struct ma_resource_manager_data_source      ma_resource_manager_data_source;

typedef enum
{
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM         = 0x00000001,   /* When set, does not load the entire data source in memory. Disk I/O will happen on job threads. */
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE         = 0x00000002,   /* Decode data before storing in memory. When set, decoding is done at the resource manager level rather than the mixing thread. Results in faster mixing, but higher memory usage...
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC          = 0x00000004,   /* When set, the resource manager will load the data source asynchronously. */
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT      = 0x00000008,   /* When set, waits for initialization of the underlying data source before returning from ma_resource_manager_data_source_init(). */
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH = 0x00000010    /* Gives the resource manager a hint that the length of the data source is unknown and calling `ma_data_source_get_length_in_pcm_frames()` should be avoided. */
} ma_resource_manager_data_source_flags;


/*
Pipeline notifications used by the resource manager. Made up of both an async notification and a fence, both of which are optional.
*/
typedef struct
{
    ma_async_notification* pNotification;
    ma_fence* pFence;

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


struct ma_resource_manager_data_buffer
{
    ma_data_source_base ds;                         /* Base data source. A data buffer is a data source. */
    ma_resource_manager* pResourceManager;          /* A pointer to the resource manager that owns this buffer. */
    ma_resource_manager_data_buffer_node* pNode;    /* The data node. This is reference counted and is what supplies the data. */
    ma_uint32 flags;                                /* The flags that were passed used to initialize the buffer. */
    MA_ATOMIC(4, ma_uint32) executionCounter;       /* For allocating execution orders for jobs. */
    MA_ATOMIC(4, ma_uint32) executionPointer;       /* For managing the order of execution for asynchronous jobs relating to this object. Incremented as jobs complete processing. */
    ma_uint64 seekTargetInPCMFrames;                /* Only updated by the public API. Never written nor read from the job thread. */
    ma_bool32 seekToCursorOnNextRead;               /* On the next read we need to seek to the frame cursor. */
    MA_ATOMIC(4, ma_result) result;                 /* Keeps track of a result of decoding. Set to MA_BUSY while the buffer is still loading. Set to MA_SUCCESS when loading is finished successfully. Otherwise set to some other code. */
    MA_ATOMIC(4, ma_bool32) isLooping;              /* Can be read and written by different threads at the same time. Must be used atomically. */
    ma_bool32 isConnectorInitialized;               /* Used for asynchronous loading to ensure we don't try to initialize the connector multiple times while waiting for the node to fully load. */
    union
    {
        ma_decoder decoder;                 /* Supply type is ma_resource_manager_data_supply_type_encoded */
        ma_audio_buffer buffer;             /* Supply type is ma_resource_manager_data_supply_type_decoded */
        ma_paged_audio_buffer pagedBuffer;  /* Supply type is ma_resource_manager_data_supply_type_decoded_paged */
    } connector;    /* Connects this object to the node's data supply. */
};

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

    MA_ATOMIC(8, ma_uint64) absoluteCursor;     /* The playback cursor, in absolute position starting from the start of the file. */
    ma_uint32 currentPageIndex;                 /* Toggles between 0 and 1. Index 0 is the first half of pPageData. Index 1 is the second half. Only ever accessed by the public API. Never accessed by the job thread. */
    MA_ATOMIC(4, ma_uint32) executionCounter;   /* For allocating execution orders for jobs. */
    MA_ATOMIC(4, ma_uint32) executionPointer;   /* For managing the order of execution for asynchronous jobs relating to this object. Incremented as jobs complete processing. */

    /* Written by the public API, read by the job thread. */
    MA_ATOMIC(4, ma_bool32) isLooping;          /* Whether or not the stream is looping. It's important to set the looping flag at the data stream level for smooth loop transitions. */

    /* Written by the job thread, read by the public API. */
    void* pPageData;                            /* Buffer containing the decoded data of each page. Allocated once at initialization time. */
    MA_ATOMIC(4, ma_uint32) pageFrameCount[2];  /* The number of valid PCM frames in each page. Used to determine the last valid frame. */

    /* Written and read by both the public API and the job thread. These must be atomic. */
    MA_ATOMIC(4, ma_result) result;             /* Result from asynchronous loading. When loading set to MA_BUSY. When initialized set to MA_SUCCESS. When deleting set to MA_UNAVAILABLE. If an error occurs when loading, set to an error code. */
    MA_ATOMIC(4, ma_bool32) isDecoderAtEnd;     /* Whether or not the decoder has reached the end. */
    MA_ATOMIC(4, ma_bool32) isPageValid[2];     /* Booleans to indicate whether or not a page is valid. Set to false by the public API, set to true by the job thread. Set to false as the pages are consumed, true when they are filled. */
    MA_ATOMIC(4, ma_bool32) seekCounter;        /* When 0, no seeking is being performed. When > 0, a seek is being performed and reading should be delayed with MA_BUSY. */
};

struct ma_resource_manager_data_source
{

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

};

/* Init. */
MA_API ma_result ma_resource_manager_init(const ma_resource_manager_config* pConfig, ma_resource_manager* pResourceManager);
MA_API void ma_resource_manager_uninit(ma_resource_manager* pResourceManager);
MA_API ma_log* ma_resource_manager_get_log(ma_resource_manager* pResourceManager);

/* Registration. */
MA_API ma_result ma_resource_manager_register_file(ma_resource_manager* pResourceManager, const char* pFilePath, ma_uint32 flags);
MA_API ma_result ma_resource_manager_register_file_w(ma_resource_manager* pResourceManager, const wchar_t* pFilePath, ma_uint32 flags);
MA_API ma_result ma_resource_manager_register_decoded_data(ma_resource_manager* pResourceManager, const char* pName, const void* pData, ma_uint64 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate);  /* Does not copy. Increments t...
MA_API ma_result ma_resource_manager_register_decoded_data_w(ma_resource_manager* pResourceManager, const wchar_t* pName, const void* pData, ma_uint64 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate);
MA_API ma_result ma_resource_manager_register_encoded_data(ma_resource_manager* pResourceManager, const char* pName, const void* pData, size_t sizeInBytes);    /* Does not copy. Increments the reference count if already exists and returns MA_SUCCESS....
MA_API ma_result ma_resource_manager_register_encoded_data_w(ma_resource_manager* pResourceManager, const wchar_t* pName, const void* pData, size_t sizeInBytes);
MA_API ma_result ma_resource_manager_unregister_file(ma_resource_manager* pResourceManager, const char* pFilePath);
MA_API ma_result ma_resource_manager_unregister_file_w(ma_resource_manager* pResourceManager, const wchar_t* pFilePath);
MA_API ma_result ma_resource_manager_unregister_data(ma_resource_manager* pResourceManager, const char* pName);
MA_API ma_result ma_resource_manager_unregister_data_w(ma_resource_manager* pResourceManager, const wchar_t* pName);

/* Data Buffers. */
MA_API ma_result ma_resource_manager_data_buffer_init_ex(ma_resource_manager* pResourceManager, const ma_resource_manager_data_source_config* pConfig, ma_resource_manager_data_buffer* pDataBuffer);
MA_API ma_result ma_resource_manager_data_buffer_init(ma_resource_manager* pResourceManager, const char* pFilePath, ma_uint32 flags, const ma_resource_manager_pipeline_notifications* pNotifications, ma_resource_manager_data_buffer* pDataBuffer);
MA_API ma_result ma_resource_manager_data_buffer_init_w(ma_resource_manager* pResourceManager, const wchar_t* pFilePath, ma_uint32 flags, const ma_resource_manager_pipeline_notifications* pNotifications, ma_resource_manager_data_buffer* pDataBuffer);
MA_API ma_result ma_resource_manager_data_buffer_init_copy(ma_resource_manager* pResourceManager, const ma_resource_manager_data_buffer* pExistingDataBuffer, ma_resource_manager_data_buffer* pDataBuffer);
MA_API ma_result ma_resource_manager_data_buffer_uninit(ma_resource_manager_data_buffer* pDataBuffer);
MA_API ma_result ma_resource_manager_data_buffer_read_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_resource_manager_data_buffer_seek_to_pcm_frame(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64 frameIndex);
MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_manager_data_buffer* pDataBuffer, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pCursor);
MA_API ma_result ma_resource_manager_data_buffer_get_length_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pLength);
MA_API ma_result ma_resource_manager_data_buffer_result(const ma_resource_manager_data_buffer* pDataBuffer);
MA_API ma_result ma_resource_manager_data_buffer_set_looping(ma_resource_manager_data_buffer* pDataBuffer, ma_bool32 isLooping);
MA_API ma_bool32 ma_resource_manager_data_buffer_is_looping(const ma_resource_manager_data_buffer* pDataBuffer);
MA_API ma_result ma_resource_manager_data_buffer_get_available_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pAvailableFrames);

/* Data Streams. */
MA_API ma_result ma_resource_manager_data_stream_init_ex(ma_resource_manager* pResourceManager, const ma_resource_manager_data_source_config* pConfig, ma_resource_manager_data_stream* pDataStream);
MA_API ma_result ma_resource_manager_data_stream_init(ma_resource_manager* pResourceManager, const char* pFilePath, ma_uint32 flags, const ma_resource_manager_pipeline_notifications* pNotifications, ma_resource_manager_data_stream* pDataStream);
MA_API ma_result ma_resource_manager_data_stream_init_w(ma_resource_manager* pResourceManager, const wchar_t* pFilePath, ma_uint32 flags, const ma_resource_manager_pipeline_notifications* pNotifications, ma_resource_manager_data_stream* pDataStream);
MA_API ma_result ma_resource_manager_data_stream_uninit(ma_resource_manager_data_stream* pDataStream);
MA_API ma_result ma_resource_manager_data_stream_read_pcm_frames(ma_resource_manager_data_stream* pDataStream, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_resource_manager_data_stream_seek_to_pcm_frame(ma_resource_manager_data_stream* pDataStream, ma_uint64 frameIndex);
MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_manager_data_stream* pDataStream, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_resource_manager_data_stream_get_cursor_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pCursor);
MA_API ma_result ma_resource_manager_data_stream_get_length_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pLength);
MA_API ma_result ma_resource_manager_data_stream_result(const ma_resource_manager_data_stream* pDataStream);
MA_API ma_result ma_resource_manager_data_stream_set_looping(ma_resource_manager_data_stream* pDataStream, ma_bool32 isLooping);
MA_API ma_bool32 ma_resource_manager_data_stream_is_looping(const ma_resource_manager_data_stream* pDataStream);
MA_API ma_result ma_resource_manager_data_stream_get_available_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pAvailableFrames);

/* Data Sources. */
MA_API ma_result ma_resource_manager_data_source_init_ex(ma_resource_manager* pResourceManager, const ma_resource_manager_data_source_config* pConfig, ma_resource_manager_data_source* pDataSource);
MA_API ma_result ma_resource_manager_data_source_init(ma_resource_manager* pResourceManager, const char* pName, ma_uint32 flags, const ma_resource_manager_pipeline_notifications* pNotifications, ma_resource_manager_data_source* pDataSource);
MA_API ma_result ma_resource_manager_data_source_init_w(ma_resource_manager* pResourceManager, const wchar_t* pName, ma_uint32 flags, const ma_resource_manager_pipeline_notifications* pNotifications, ma_resource_manager_data_source* pDataSource);
MA_API ma_result ma_resource_manager_data_source_init_copy(ma_resource_manager* pResourceManager, const ma_resource_manager_data_source* pExistingDataSource, ma_resource_manager_data_source* pDataSource);
MA_API ma_result ma_resource_manager_data_source_uninit(ma_resource_manager_data_source* pDataSource);
MA_API ma_result ma_resource_manager_data_source_read_pcm_frames(ma_resource_manager_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_resource_manager_data_source_seek_to_pcm_frame(ma_resource_manager_data_source* pDataSource, ma_uint64 frameIndex);
MA_API ma_result ma_resource_manager_data_source_get_data_format(ma_resource_manager_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_resource_manager_data_source_get_cursor_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pCursor);
MA_API ma_result ma_resource_manager_data_source_get_length_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pLength);
MA_API ma_result ma_resource_manager_data_source_result(const ma_resource_manager_data_source* pDataSource);
MA_API ma_result ma_resource_manager_data_source_set_looping(ma_resource_manager_data_source* pDataSource, ma_bool32 isLooping);
MA_API ma_bool32 ma_resource_manager_data_source_is_looping(const ma_resource_manager_data_source* pDataSource);
MA_API ma_result ma_resource_manager_data_source_get_available_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pAvailableFrames);

/* Job management. */
MA_API ma_result ma_resource_manager_post_job(ma_resource_manager* pResourceManager, const ma_job* pJob);
MA_API ma_result ma_resource_manager_post_job_quit(ma_resource_manager* pResourceManager);  /* Helper for posting a quit job. */
MA_API ma_result ma_resource_manager_next_job(ma_resource_manager* pResourceManager, ma_job* pJob);
MA_API ma_result ma_resource_manager_process_job(ma_resource_manager* pResourceManager, ma_job* pJob);  /* DEPRECATED. Use ma_job_process(). Will be removed in version 0.12. */
MA_API ma_result ma_resource_manager_process_next_job(ma_resource_manager* pResourceManager);   /* Returns MA_CANCELLED if a MA_JOB_TYPE_QUIT job is found. In non-blocking mode, returns MA_NO_DATA_AVAILABLE if no jobs are available. */
#endif  /* MA_NO_RESOURCE_MANAGER */


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

    ma_node_state_started = 0,
    ma_node_state_stopped = 1
} ma_node_state;


typedef struct
{
    /*
    Extended processing callback. This callback is used for effects that process input and output
    at different rates (i.e. they perform resampling). This is similar to the simple version, only
    they take two seperate frame counts: one for input, and one for output.

    On input, `pFrameCountOut` is equal to the capacity of the output buffer for each bus, whereas
    `pFrameCountIn` will be equal to the number of PCM frames in each of the buffers in `ppFramesIn`.

    On output, set `pFrameCountOut` to the number of PCM frames that were actually output and set
    `pFrameCountIn` to the number of input frames that were consumed.
    */
    void (* onProcess)(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut);

    /*
    A callback for retrieving the number of a input frames that are required to output the
    specified number of output frames. You would only want to implement this when the node performs
    resampling. This is optional, even for nodes that perform resampling, but it does offer a
    small reduction in latency as it allows miniaudio to calculate the exact number of input frames
    to read at a time instead of having to estimate.
    */
    ma_result (* onGetRequiredInputFrameCount)(ma_node* pNode, ma_uint32 outputFrameCount, ma_uint32* pInputFrameCount);

    /*
    The number of input buses. This is how many sub-buffers will be contained in the `ppFramesIn`
    parameters of the callbacks above.
    */
    ma_uint8 inputBusCount;

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

};


typedef struct ma_node_base ma_node_base;
struct ma_node_base
{
    /* These variables are set once at startup. */
    ma_node_graph* pNodeGraph;  /* The graph this node belongs to. */
    const ma_node_vtable* vtable;
    float* pCachedData;                     /* Allocated on the heap. Fixed size. Needs to be stored on the heap because reading from output buses is done in separate function calls. */
    ma_uint16 cachedDataCapInFramesPerBus;  /* The capacity of the input data cache in frames, per bus. */

    /* These variables are read and written only from the audio thread. */
    ma_uint16 cachedFrameCountOut;
    ma_uint16 cachedFrameCountIn;
    ma_uint16 consumedFrameCountIn;

    /* These variables are read and written between different threads. */
    MA_ATOMIC(4, ma_node_state) state;      /* When set to stopped, nothing will be read, regardless of the times in stateTimes. */
    MA_ATOMIC(8, ma_uint64) stateTimes[2];  /* Indexed by ma_node_state. Specifies the time based on the global clock that a node should be considered to be in the relevant state. */
    MA_ATOMIC(8, ma_uint64) localTime;      /* The node's local clock. This is just a running sum of the number of output frames that have been processed. Can be modified by any thread with `ma_node_set_time()`. */
    ma_uint32 inputBusCount;
    ma_uint32 outputBusCount;
    ma_node_input_bus* pInputBuses;
    ma_node_output_bus* pOutputBuses;

    /* Memory management. */
    ma_node_input_bus _inputBuses[MA_MAX_NODE_LOCAL_BUS_COUNT];
    ma_node_output_bus _outputBuses[MA_MAX_NODE_LOCAL_BUS_COUNT];
    void* _pHeap;   /* A heap allocation for internal use only. pInputBuses and/or pOutputBuses will point to this if the bus count exceeds MA_MAX_NODE_LOCAL_BUS_COUNT. */
    ma_bool32 _ownsHeap;    /* If set to true, the node owns the heap allocation and _pHeap will be freed in ma_node_uninit(). */

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

    ma_uint32 channels;
    ma_uint16 nodeCacheCapInFrames;
} ma_node_graph_config;

MA_API ma_node_graph_config ma_node_graph_config_init(ma_uint32 channels);


struct ma_node_graph
{
    /* Immutable. */
    ma_node_base base;                  /* The node graph itself is a node so it can be connected as an input to different node graph. This has zero inputs and calls ma_node_graph_read_pcm_frames() to generate it's output. */
    ma_node_base endpoint;              /* Special node that all nodes eventually connect to. Data is read from this node in ma_node_graph_read_pcm_frames(). */
    ma_uint16 nodeCacheCapInFrames;

    /* Read and written by multiple threads. */
    MA_ATOMIC(4, ma_bool32) isReading;
};

MA_API ma_result ma_node_graph_init(const ma_node_graph_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_node_graph* pNodeGraph);
MA_API void ma_node_graph_uninit(ma_node_graph* pNodeGraph, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_node* ma_node_graph_get_endpoint(ma_node_graph* pNodeGraph);
MA_API ma_result ma_node_graph_read_pcm_frames(ma_node_graph* pNodeGraph, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_uint32 ma_node_graph_get_channels(const ma_node_graph* pNodeGraph);
MA_API ma_uint64 ma_node_graph_get_time(const ma_node_graph* pNodeGraph);
MA_API ma_result ma_node_graph_set_time(ma_node_graph* pNodeGraph, ma_uint64 globalTime);



/* Data source node. 0 input buses, 1 output bus. Used for reading from a data source. */
typedef struct
{
    ma_node_config nodeConfig;

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

    ma_bool32 isLooping;
    ma_fence* pDoneFence;                       /* Released when the resource manager has finished decoding the entire sound. Not used with streams. */
} ma_sound_config;

MA_API ma_sound_config ma_sound_config_init(void);

struct ma_sound
{
    ma_engine_node engineNode;          /* Must be the first member for compatibility with the ma_node API. */
    ma_data_source* pDataSource;
    MA_ATOMIC(8, ma_uint64) seekTarget; /* The PCM frame index to seek to in the mixing thread. Set to (~(ma_uint64)0) to not perform any seeking. */
    MA_ATOMIC(4, ma_bool32) atEnd;
    ma_bool8 ownsDataSource;

    /*
    We're declaring a resource manager data source object here to save us a malloc when loading a
    sound via the resource manager, which I *think* will be the most common scenario.
    */
#ifndef MA_NO_RESOURCE_MANAGER
    ma_resource_manager_data_source* pResourceManagerDataSource;
#endif

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

    ma_context* pContext;
    ma_device* pDevice;                         /* If set, the caller is responsible for calling ma_engine_data_callback() in the device's data callback. */
    ma_device_id* pPlaybackDeviceID;            /* The ID of the playback device to use with the default listener. */
#endif
    ma_log* pLog;                               /* When set to NULL, will use the context's log. */
    ma_uint32 listenerCount;                    /* Must be between 1 and MA_ENGINE_MAX_LISTENERS. */
    ma_uint32 channels;                         /* The number of channels to use when mixing and spatializing. When set to 0, will use the native channel count of the device. */
    ma_uint32 sampleRate;                       /* The sample rate. When set to 0 will use the native channel count of the device. */
    ma_uint32 periodSizeInFrames;               /* If set to something other than 0, updates will always be exactly this size. The underlying device may be a different size, but from the perspective of the mixer that won't matter.*/
    ma_uint32 periodSizeInMilliseconds;         /* Used if periodSizeInFrames is unset. */
    ma_uint32 gainSmoothTimeInFrames;           /* The number of frames to interpolate the gain of spatialized sounds across. If set to 0, will use gainSmoothTimeInMilliseconds. */
    ma_uint32 gainSmoothTimeInMilliseconds;     /* When set to 0, gainSmoothTimeInFrames will be used. If both are set to 0, a default value will be used. */
    ma_allocation_callbacks allocationCallbacks;
    ma_bool32 noAutoStart;                      /* When set to true, requires an explicit call to ma_engine_start(). This is false by default, meaning the engine will be started automatically in ma_engine_init(). */
    ma_bool32 noDevice;                         /* When set to true, don't create a default device. ma_engine_read_pcm_frames() can be called manually to read data. */
    ma_mono_expansion_mode monoExpansionMode;   /* Controls how the mono channel should be expanded to other channels when spatialization is disabled on a sound. */
    ma_vfs* pResourceManagerVFS;                /* A pointer to a pre-allocated VFS object to use with the resource manager. This is ignored if pResourceManager is not NULL. */
} ma_engine_config;

MA_API ma_engine_config ma_engine_config_init(void);


struct ma_engine
{
    ma_node_graph nodeGraph;                /* An engine is a node graph. It should be able to be plugged into any ma_node_graph API (with a cast) which means this must be the first member of this struct. */

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

    ma_log* pLog;
    ma_uint32 sampleRate;
    ma_uint32 listenerCount;
    ma_spatializer_listener listeners[MA_ENGINE_MAX_LISTENERS];
    ma_allocation_callbacks allocationCallbacks;
    ma_bool8 ownsResourceManager;
    ma_bool8 ownsDevice;
    ma_spinlock inlinedSoundLock;               /* For synchronizing access so the inlined sound list. */
    ma_sound_inlined* pInlinedSoundHead;        /* The first inlined sound. Inlined sounds are tracked in a linked list. */
    MA_ATOMIC(4, ma_uint32) inlinedSoundCount;  /* The total number of allocated inlined sound objects. Used for debugging. */
    ma_uint32 gainSmoothTimeInFrames;           /* The number of frames to interpolate the gain of spatialized sounds across. */
    ma_mono_expansion_mode monoExpansionMode;
};

MA_API ma_result ma_engine_init(const ma_engine_config* pConfig, ma_engine* pEngine);
MA_API void ma_engine_uninit(ma_engine* pEngine);
MA_API ma_result ma_engine_read_pcm_frames(ma_engine* pEngine, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_node_graph* ma_engine_get_node_graph(ma_engine* pEngine);
#if !defined(MA_NO_RESOURCE_MANAGER)
MA_API ma_resource_manager* ma_engine_get_resource_manager(ma_engine* pEngine);
#endif
MA_API ma_device* ma_engine_get_device(ma_engine* pEngine);
MA_API ma_log* ma_engine_get_log(ma_engine* pEngine);
MA_API ma_node* ma_engine_get_endpoint(ma_engine* pEngine);
MA_API ma_uint64 ma_engine_get_time(const ma_engine* pEngine);
MA_API ma_result ma_engine_set_time(ma_engine* pEngine, ma_uint64 globalTime);
MA_API ma_uint32 ma_engine_get_channels(const ma_engine* pEngine);

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

MA_API void ma_sound_set_min_distance(ma_sound* pSound, float minDistance);
MA_API float ma_sound_get_min_distance(const ma_sound* pSound);
MA_API void ma_sound_set_max_distance(ma_sound* pSound, float maxDistance);
MA_API float ma_sound_get_max_distance(const ma_sound* pSound);
MA_API void ma_sound_set_cone(ma_sound* pSound, float innerAngleInRadians, float outerAngleInRadians, float outerGain);
MA_API void ma_sound_get_cone(const ma_sound* pSound, float* pInnerAngleInRadians, float* pOuterAngleInRadians, float* pOuterGain);
MA_API void ma_sound_set_doppler_factor(ma_sound* pSound, float dopplerFactor);
MA_API float ma_sound_get_doppler_factor(const ma_sound* pSound);
MA_API void ma_sound_set_directional_attenuation_factor(ma_sound* pSound, float directionalAttenuationFactor);
MA_API float ma_sound_get_directional_attenuation_factor(const ma_sound* pSound);
MA_API void ma_sound_set_fade_in_pcm_frames(ma_sound* pSound, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInFrames);
MA_API void ma_sound_set_fade_in_milliseconds(ma_sound* pSound, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInMilliseconds);
MA_API float ma_sound_get_current_fade_volume(ma_sound* pSound);
MA_API void ma_sound_set_start_time_in_pcm_frames(ma_sound* pSound, ma_uint64 absoluteGlobalTimeInFrames);
MA_API void ma_sound_set_start_time_in_milliseconds(ma_sound* pSound, ma_uint64 absoluteGlobalTimeInMilliseconds);
MA_API void ma_sound_set_stop_time_in_pcm_frames(ma_sound* pSound, ma_uint64 absoluteGlobalTimeInFrames);
MA_API void ma_sound_set_stop_time_in_milliseconds(ma_sound* pSound, ma_uint64 absoluteGlobalTimeInMilliseconds);
MA_API ma_bool32 ma_sound_is_playing(const ma_sound* pSound);
MA_API ma_uint64 ma_sound_get_time_in_pcm_frames(const ma_sound* pSound);
MA_API void ma_sound_set_looping(ma_sound* pSound, ma_bool32 isLooping);
MA_API ma_bool32 ma_sound_is_looping(const ma_sound* pSound);
MA_API ma_bool32 ma_sound_at_end(const ma_sound* pSound);
MA_API ma_result ma_sound_seek_to_pcm_frame(ma_sound* pSound, ma_uint64 frameIndex); /* Just a wrapper around ma_data_source_seek_to_pcm_frame(). */
MA_API ma_result ma_sound_get_data_format(ma_sound* pSound, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_sound_get_cursor_in_pcm_frames(ma_sound* pSound, ma_uint64* pCursor);
MA_API ma_result ma_sound_get_length_in_pcm_frames(ma_sound* pSound, ma_uint64* pLength);
MA_API ma_result ma_sound_get_cursor_in_seconds(ma_sound* pSound, float* pCursor);
MA_API ma_result ma_sound_get_length_in_seconds(ma_sound* pSound, float* pLength);

MA_API ma_result ma_sound_group_init(ma_engine* pEngine, ma_uint32 flags, ma_sound_group* pParentGroup, ma_sound_group* pGroup);
MA_API ma_result ma_sound_group_init_ex(ma_engine* pEngine, const ma_sound_group_config* pConfig, ma_sound_group* pGroup);
MA_API void ma_sound_group_uninit(ma_sound_group* pGroup);
MA_API ma_engine* ma_sound_group_get_engine(const ma_sound_group* pGroup);
MA_API ma_result ma_sound_group_start(ma_sound_group* pGroup);
MA_API ma_result ma_sound_group_stop(ma_sound_group* pGroup);
MA_API void ma_sound_group_set_volume(ma_sound_group* pGroup, float volume);

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

MA_API void ma_sound_group_set_min_distance(ma_sound_group* pGroup, float minDistance);
MA_API float ma_sound_group_get_min_distance(const ma_sound_group* pGroup);
MA_API void ma_sound_group_set_max_distance(ma_sound_group* pGroup, float maxDistance);
MA_API float ma_sound_group_get_max_distance(const ma_sound_group* pGroup);
MA_API void ma_sound_group_set_cone(ma_sound_group* pGroup, float innerAngleInRadians, float outerAngleInRadians, float outerGain);
MA_API void ma_sound_group_get_cone(const ma_sound_group* pGroup, float* pInnerAngleInRadians, float* pOuterAngleInRadians, float* pOuterGain);
MA_API void ma_sound_group_set_doppler_factor(ma_sound_group* pGroup, float dopplerFactor);
MA_API float ma_sound_group_get_doppler_factor(const ma_sound_group* pGroup);
MA_API void ma_sound_group_set_directional_attenuation_factor(ma_sound_group* pGroup, float directionalAttenuationFactor);
MA_API float ma_sound_group_get_directional_attenuation_factor(const ma_sound_group* pGroup);
MA_API void ma_sound_group_set_fade_in_pcm_frames(ma_sound_group* pGroup, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInFrames);
MA_API void ma_sound_group_set_fade_in_milliseconds(ma_sound_group* pGroup, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInMilliseconds);
MA_API float ma_sound_group_get_current_fade_volume(ma_sound_group* pGroup);
MA_API void ma_sound_group_set_start_time_in_pcm_frames(ma_sound_group* pGroup, ma_uint64 absoluteGlobalTimeInFrames);
MA_API void ma_sound_group_set_start_time_in_milliseconds(ma_sound_group* pGroup, ma_uint64 absoluteGlobalTimeInMilliseconds);
MA_API void ma_sound_group_set_stop_time_in_pcm_frames(ma_sound_group* pGroup, ma_uint64 absoluteGlobalTimeInFrames);
MA_API void ma_sound_group_set_stop_time_in_milliseconds(ma_sound_group* pGroup, ma_uint64 absoluteGlobalTimeInMilliseconds);
MA_API ma_bool32 ma_sound_group_is_playing(const ma_sound_group* pGroup);
MA_API ma_uint64 ma_sound_group_get_time_in_pcm_frames(const ma_sound_group* pGroup);
#endif  /* MA_NO_ENGINE */

#ifdef __cplusplus
}
#endif
#endif  /* miniaudio_h */


/*
This is for preventing greying out of the implementation section.

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


#define ma_countof(x)               (sizeof(x) / sizeof(x[0]))
#define ma_max(x, y)                (((x) > (y)) ? (x) : (y))
#define ma_min(x, y)                (((x) < (y)) ? (x) : (y))
#define ma_abs(x)                   (((x) > 0) ? (x) : -(x))
#define ma_clamp(x, lo, hi)         (ma_max(lo, ma_min(x, hi)))
#define ma_offset_ptr(p, offset)    (((ma_uint8*)(p)) + (offset))
#define ma_align(x, a)              ((x + (a-1)) & ~(a-1))
#define ma_align_64(x)              ma_align(x, 8)

#define ma_buffer_frame_capacity(buffer, channels, format) (sizeof(buffer) / ma_get_bytes_per_sample(format) / (channels))

static MA_INLINE double ma_sind(double x)
{
    /* TODO: Implement custom sin(x). */
    return sin(x);
}

static MA_INLINE double ma_expd(double x)
{
    /* TODO: Implement custom exp(x). */

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

    c89atomic_flag_clear_explicit(pSpinlock, c89atomic_memory_order_release);
}
#if defined(__cplusplus)
}
#endif
#endif
/* c89atomic.h end */



MA_API ma_uint64 ma_calculate_frame_count_after_resampling(ma_uint32 sampleRateOut, ma_uint32 sampleRateIn, ma_uint64 frameCountIn)
{
    /* This is based on the calculation in ma_linear_resampler_get_expected_output_frame_count(). */
    ma_uint64 outputFrameCount;
    ma_uint64 preliminaryInputFrameCountFromFrac;
    ma_uint64 preliminaryInputFrameCount;

    if (sampleRateIn == 0 || sampleRateOut == 0 || frameCountIn == 0) {
        return 0;
    }

    if (sampleRateOut == sampleRateIn) {
        return frameCountIn;
    }

    outputFrameCount = (frameCountIn * sampleRateOut) / sampleRateIn;

    preliminaryInputFrameCountFromFrac = (outputFrameCount * (sampleRateIn / sampleRateOut)) / sampleRateOut;
    preliminaryInputFrameCount         = (outputFrameCount * (sampleRateIn % sampleRateOut)) + preliminaryInputFrameCountFromFrac;

    if (preliminaryInputFrameCount <= frameCountIn) {
        outputFrameCount += 1;
    }

    return outputFrameCount;
}

#ifndef MA_DATA_CONVERTER_STACK_BUFFER_SIZE
#define MA_DATA_CONVERTER_STACK_BUFFER_SIZE     4096
#endif

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

{
    ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_began));
}

void ma_device__on_notification_interruption_ended(ma_device* pDevice)
{
    ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_ended));
}


static void ma_device__on_data_inner(ma_device* pDevice, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount)
{
    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pDevice->onData != NULL);

    if (!pDevice->noPreSilencedOutputBuffer && pFramesOut != NULL) {
        ma_silence_pcm_frames(pFramesOut, frameCount, pDevice->playback.format, pDevice->playback.channels);
    }

    pDevice->onData(pDevice, pFramesOut, pFramesIn, frameCount);
}

static void ma_device__on_data(ma_device* pDevice, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount)
{
    MA_ASSERT(pDevice != NULL);

    if (pDevice->noFixedSizedCallback) {
        /* Fast path. Not using a fixed sized callback. Process directly from the specified buffers. */
        ma_device__on_data_inner(pDevice, pFramesOut, pFramesIn, frameCount);
    } else {
        /* Slow path. Using a fixed sized callback. Need to use the intermediary buffer. */
        ma_uint32 totalFramesProcessed = 0;

        while (totalFramesProcessed < frameCount) {
            ma_uint32 totalFramesRemaining = frameCount - totalFramesProcessed;
            ma_uint32 framesToProcessThisIteration = 0;

            if (pFramesIn != NULL) {
                /* Capturing. Write to the intermediary buffer. If there's no room, fire the callback to empty it. */
                if (pDevice->capture.intermediaryBufferLen < pDevice->capture.intermediaryBufferCap) {
                    /* There's some room left in the intermediary buffer. Write to it without firing the callback. */
                    framesToProcessThisIteration = totalFramesRemaining;
                    if (framesToProcessThisIteration > pDevice->capture.intermediaryBufferCap - pDevice->capture.intermediaryBufferLen) {
                        framesToProcessThisIteration = pDevice->capture.intermediaryBufferCap - pDevice->capture.intermediaryBufferLen;
                    }

                    ma_copy_pcm_frames(
                        ma_offset_pcm_frames_ptr(pDevice->capture.pIntermediaryBuffer, pDevice->capture.intermediaryBufferLen, pDevice->capture.format, pDevice->capture.channels),
                        ma_offset_pcm_frames_const_ptr(pFramesIn, totalFramesProcessed, pDevice->capture.format, pDevice->capture.channels),
                        framesToProcessThisIteration,
                        pDevice->capture.format, pDevice->capture.channels);

                    pDevice->capture.intermediaryBufferLen += framesToProcessThisIteration;
                }

                if (pDevice->capture.intermediaryBufferLen == pDevice->capture.intermediaryBufferCap) {
                    /* No room left in the intermediary buffer. Fire the data callback. */
                    if (pDevice->type == ma_device_type_duplex) {
                        /* We'll do the duplex data callback later after we've processed the playback data. */
                    } else {
                        ma_device__on_data_inner(pDevice, NULL, pDevice->capture.pIntermediaryBuffer, pDevice->capture.intermediaryBufferCap);

                        /* The intermediary buffer has just been drained. */
                        pDevice->capture.intermediaryBufferLen = 0;
                    }
                }
            }

            if (pFramesOut != NULL) {
                /* Playing back. Read from the intermediary buffer. If there's nothing in it, fire the callback to fill it. */
                if (pDevice->playback.intermediaryBufferLen > 0) {
                    /* There's some content in the intermediary buffer. Read from that without firing the callback. */
                    if (pDevice->type == ma_device_type_duplex) {
                        /* The frames processed this iteration for a duplex device will always be based on the capture side. Leave it unmodified. */
                    } else {
                        framesToProcessThisIteration = totalFramesRemaining;
                        if (framesToProcessThisIteration > pDevice->playback.intermediaryBufferLen) {
                            framesToProcessThisIteration = pDevice->playback.intermediaryBufferLen;
                        }
                    }

                    ma_copy_pcm_frames(
                        ma_offset_pcm_frames_ptr(pFramesOut, totalFramesProcessed, pDevice->playback.format, pDevice->playback.channels),
                        ma_offset_pcm_frames_ptr(pDevice->playback.pIntermediaryBuffer, pDevice->playback.intermediaryBufferCap - pDevice->playback.intermediaryBufferLen, pDevice->playback.format, pDevice->playback.channels),
                        framesToProcessThisIteration,
                        pDevice->playback.format, pDevice->playback.channels);

                    pDevice->playback.intermediaryBufferLen -= framesToProcessThisIteration;
                }

                if (pDevice->playback.intermediaryBufferLen == 0) {
                    /* There's nothing in the intermediary buffer. Fire the data callback to fill it. */
                    if (pDevice->type == ma_device_type_duplex) {
                        /* In duplex mode, the data callback will be fired later. Nothing to do here. */
                    } else {
                        ma_device__on_data_inner(pDevice, pDevice->playback.pIntermediaryBuffer, NULL, pDevice->playback.intermediaryBufferCap);

                        /* The intermediary buffer has just been filled. */

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

            if (pDevice->type == ma_device_type_duplex) {
                if (pDevice->capture.intermediaryBufferLen == pDevice->capture.intermediaryBufferCap) {
                    ma_device__on_data_inner(pDevice, pDevice->playback.pIntermediaryBuffer, pDevice->capture.pIntermediaryBuffer, pDevice->capture.intermediaryBufferCap);

                    pDevice->playback.intermediaryBufferLen = pDevice->playback.intermediaryBufferCap;  /* The playback buffer will have just been filled. */
                    pDevice->capture.intermediaryBufferLen  = 0;                                        /* The intermediary buffer has just been drained. */
                }
            }

            /* Make sure this is only incremented once in the duplex case. */
            totalFramesProcessed += framesToProcessThisIteration;
        }
    }
}

static void ma_device__handle_data_callback(ma_device* pDevice, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount)
{
    float masterVolumeFactor;

    ma_device_get_master_volume(pDevice, &masterVolumeFactor);  /* Use ma_device_get_master_volume() to ensure the volume is loaded atomically. */

    if (pDevice->onData) {
        unsigned int prevDenormalState = ma_device_disable_denormals(pDevice);
        {
            /* Volume control of input makes things a bit awkward because the input buffer is read-only. We'll need to use a temp buffer and loop in this case. */
            if (pFramesIn != NULL && masterVolumeFactor < 1) {
                ma_uint8 tempFramesIn[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                ma_uint32 bpfCapture  = ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
                ma_uint32 bpfPlayback = ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
                ma_uint32 totalFramesProcessed = 0;
                while (totalFramesProcessed < frameCount) {
                    ma_uint32 framesToProcessThisIteration = frameCount - totalFramesProcessed;
                    if (framesToProcessThisIteration > sizeof(tempFramesIn)/bpfCapture) {
                        framesToProcessThisIteration = sizeof(tempFramesIn)/bpfCapture;
                    }

                    ma_copy_and_apply_volume_factor_pcm_frames(tempFramesIn, ma_offset_ptr(pFramesIn, totalFramesProcessed*bpfCapture), framesToProcessThisIteration, pDevice->capture.format, pDevice->capture.channels, masterVolumeFactor);

                    ma_device__on_data(pDevice, ma_offset_ptr(pFramesOut, totalFramesProcessed*bpfPlayback), tempFramesIn, framesToProcessThisIteration);

                    totalFramesProcessed += framesToProcessThisIteration;
                }
            } else {
                ma_device__on_data(pDevice, pFramesOut, pFramesIn, frameCount);
            }

            /* Volume control and clipping for playback devices. */
            if (pFramesOut != NULL) {
                if (masterVolumeFactor < 1) {
                    if (pFramesIn == NULL) {    /* <-- In full-duplex situations, the volume will have been applied to the input samples before the data callback. Applying it again post-callback will incorrectly compound it. */
                        ma_apply_volume_factor_pcm_frames(pFramesOut, frameCount, pDevice->playback.format, pDevice->playback.channels, masterVolumeFactor);
                    }
                }

                if (!pDevice->noClip && pDevice->playback.format == ma_format_f32) {
                    ma_clip_samples_f32((float*)pFramesOut, (const float*)pFramesOut, frameCount * pDevice->playback.channels);   /* Intentionally specifying the same pointer for both input and output for in-place processing. */
                }
            }
        }
        ma_device_restore_denormals(pDevice, prevDenormalState);
    }
}



/* A helper function for reading sample data from the client. */
static void ma_device__read_frames_from_client(ma_device* pDevice, ma_uint32 frameCount, void* pFramesOut)
{
    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(frameCount > 0);
    MA_ASSERT(pFramesOut != NULL);

    if (pDevice->playback.converter.isPassthrough) {
        ma_device__handle_data_callback(pDevice, pFramesOut, NULL, frameCount);
    } else {
        ma_result result;
        ma_uint64 totalFramesReadOut;
        void* pRunningFramesOut;

        totalFramesReadOut = 0;
        pRunningFramesOut  = pFramesOut;

        /*
        We run slightly different logic depending on whether or not we're using a heap-allocated
        buffer for caching input data. This will be the case if the data converter does not have
        the ability to retrieve the required input frame count for a given output frame count.
        */
        if (pDevice->playback.pInputCache != NULL) {
            while (totalFramesReadOut < frameCount) {
                ma_uint64 framesToReadThisIterationIn;
                ma_uint64 framesToReadThisIterationOut;

                /* If there's any data available in the cache, that needs to get processed first. */
                if (pDevice->playback.inputCacheRemaining > 0) {
                    framesToReadThisIterationOut = (frameCount - totalFramesReadOut);
                    framesToReadThisIterationIn  = framesToReadThisIterationOut;
                    if (framesToReadThisIterationIn > pDevice->playback.inputCacheRemaining) {
                        framesToReadThisIterationIn = pDevice->playback.inputCacheRemaining;
                    }

                    result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, ma_offset_pcm_frames_ptr(pDevice->playback.pInputCache, pDevice->playback.inputCacheConsumed, pDevice->playback.format, pDevice->playback.channels), &fram...
                    if (result != MA_SUCCESS) {
                        break;
                    }

                    pDevice->playback.inputCacheConsumed  += framesToReadThisIterationIn;
                    pDevice->playback.inputCacheRemaining -= framesToReadThisIterationIn;

                    totalFramesReadOut += framesToReadThisIterationOut;
                    pRunningFramesOut   = ma_offset_ptr(pRunningFramesOut, framesToReadThisIterationOut * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));

                    if (framesToReadThisIterationIn == 0 && framesToReadThisIterationOut == 0) {
                        break;  /* We're done. */
                    }
                }

                /* Getting here means there's no data in the cache and we need to fill it up with data from the client. */
                if (pDevice->playback.inputCacheRemaining == 0) {
                    ma_device__handle_data_callback(pDevice, pDevice->playback.pInputCache, NULL, (ma_uint32)pDevice->playback.inputCacheCap);

                    pDevice->playback.inputCacheConsumed  = 0;
                    pDevice->playback.inputCacheRemaining = pDevice->playback.inputCacheCap;
                }
            }
        } else {
            while (totalFramesReadOut < frameCount) {
                ma_uint8 pIntermediaryBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];  /* In client format. */
                ma_uint64 intermediaryBufferCap = sizeof(pIntermediaryBuffer) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
                ma_uint64 framesToReadThisIterationIn;
                ma_uint64 framesReadThisIterationIn;
                ma_uint64 framesToReadThisIterationOut;
                ma_uint64 framesReadThisIterationOut;
                ma_uint64 requiredInputFrameCount;

                framesToReadThisIterationOut = (frameCount - totalFramesReadOut);
                framesToReadThisIterationIn = framesToReadThisIterationOut;
                if (framesToReadThisIterationIn > intermediaryBufferCap) {
                    framesToReadThisIterationIn = intermediaryBufferCap;
                }

                ma_data_converter_get_required_input_frame_count(&pDevice->playback.converter, framesToReadThisIterationOut, &requiredInputFrameCount);
                if (framesToReadThisIterationIn > requiredInputFrameCount) {
                    framesToReadThisIterationIn = requiredInputFrameCount;
                }

                if (framesToReadThisIterationIn > 0) {
                    ma_device__handle_data_callback(pDevice, pIntermediaryBuffer, NULL, (ma_uint32)framesToReadThisIterationIn);
                }

                /*
                At this point we have our decoded data in input format and now we need to convert to output format. Note that even if we didn't read any
                input frames, we still want to try processing frames because there may some output frames generated from cached input data.
                */
                framesReadThisIterationIn  = framesToReadThisIterationIn;
                framesReadThisIterationOut = framesToReadThisIterationOut;
                result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, pIntermediaryBuffer, &framesReadThisIterationIn, pRunningFramesOut, &framesReadThisIterationOut);
                if (result != MA_SUCCESS) {
                    break;
                }

                totalFramesReadOut += framesReadThisIterationOut;
                pRunningFramesOut   = ma_offset_ptr(pRunningFramesOut, framesReadThisIterationOut * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));

                if (framesReadThisIterationIn == 0 && framesReadThisIterationOut == 0) {
                    break;  /* We're done. */
                }
            }
        }
    }
}

/* A helper for sending sample data to the client. */
static void ma_device__send_frames_to_client(ma_device* pDevice, ma_uint32 frameCountInDeviceFormat, const void* pFramesInDeviceFormat)
{
    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(frameCountInDeviceFormat > 0);
    MA_ASSERT(pFramesInDeviceFormat != NULL);

    if (pDevice->capture.converter.isPassthrough) {
        ma_device__handle_data_callback(pDevice, NULL, pFramesInDeviceFormat, frameCountInDeviceFormat);
    } else {
        ma_result result;
        ma_uint8 pFramesInClientFormat[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
        ma_uint64 framesInClientFormatCap = sizeof(pFramesInClientFormat) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
        ma_uint64 totalDeviceFramesProcessed = 0;
        ma_uint64 totalClientFramesProcessed = 0;
        const void* pRunningFramesInDeviceFormat = pFramesInDeviceFormat;

        /* We just keep going until we've exhaused all of our input frames and cannot generate any more output frames. */
        for (;;) {
            ma_uint64 deviceFramesProcessedThisIteration;
            ma_uint64 clientFramesProcessedThisIteration;

            deviceFramesProcessedThisIteration = (frameCountInDeviceFormat - totalDeviceFramesProcessed);
            clientFramesProcessedThisIteration = framesInClientFormatCap;

            result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningFramesInDeviceFormat, &deviceFramesProcessedThisIteration, pFramesInClientFormat, &clientFramesProcessedThisIteration);
            if (result != MA_SUCCESS) {
                break;
            }

            if (clientFramesProcessedThisIteration > 0) {
                ma_device__handle_data_callback(pDevice, NULL, pFramesInClientFormat, (ma_uint32)clientFramesProcessedThisIteration);    /* Safe cast. */
            }

            pRunningFramesInDeviceFormat = ma_offset_ptr(pRunningFramesInDeviceFormat, deviceFramesProcessedThisIteration * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));
            totalDeviceFramesProcessed  += deviceFramesProcessedThisIteration;
            totalClientFramesProcessed  += clientFramesProcessedThisIteration;

            if (deviceFramesProcessedThisIteration == 0 && clientFramesProcessedThisIteration == 0) {
                break;  /* We're done. */
            }
        }
    }
}

static ma_result ma_device__handle_duplex_callback_capture(ma_device* pDevice, ma_uint32 frameCountInDeviceFormat, const void* pFramesInDeviceFormat, ma_pcm_rb* pRB)
{
    ma_result result;
    ma_uint32 totalDeviceFramesProcessed = 0;
    const void* pRunningFramesInDeviceFormat = pFramesInDeviceFormat;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(frameCountInDeviceFormat > 0);
    MA_ASSERT(pFramesInDeviceFormat != NULL);
    MA_ASSERT(pRB != NULL);

    /* Write to the ring buffer. The ring buffer is in the client format which means we need to convert. */
    for (;;) {
        ma_uint32 framesToProcessInDeviceFormat = (frameCountInDeviceFormat - totalDeviceFramesProcessed);
        ma_uint32 framesToProcessInClientFormat = MA_DATA_CONVERTER_STACK_BUFFER_SIZE / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
        ma_uint64 framesProcessedInDeviceFormat;
        ma_uint64 framesProcessedInClientFormat;
        void* pFramesInClientFormat;

        result = ma_pcm_rb_acquire_write(pRB, &framesToProcessInClientFormat, &pFramesInClientFormat);
        if (result != MA_SUCCESS) {
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "Failed to acquire capture PCM frames from ring buffer.");
            break;
        }

        if (framesToProcessInClientFormat == 0) {
            if (ma_pcm_rb_pointer_distance(pRB) == (ma_int32)ma_pcm_rb_get_subbuffer_size(pRB)) {
                break;  /* Overrun. Not enough room in the ring buffer for input frame. Excess frames are dropped. */
            }
        }

        /* Convert. */
        framesProcessedInDeviceFormat = framesToProcessInDeviceFormat;
        framesProcessedInClientFormat = framesToProcessInClientFormat;
        result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningFramesInDeviceFormat, &framesProcessedInDeviceFormat, pFramesInClientFormat, &framesProcessedInClientFormat);
        if (result != MA_SUCCESS) {
            break;
        }

        result = ma_pcm_rb_commit_write(pRB, (ma_uint32)framesProcessedInClientFormat);  /* Safe cast. */
        if (result != MA_SUCCESS) {
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "Failed to commit capture PCM frames to ring buffer.");
            break;
        }

        pRunningFramesInDeviceFormat = ma_offset_ptr(pRunningFramesInDeviceFormat, framesProcessedInDeviceFormat * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));
        totalDeviceFramesProcessed += (ma_uint32)framesProcessedInDeviceFormat; /* Safe cast. */

        /* We're done when we're unable to process any client nor device frames. */
        if (framesProcessedInClientFormat == 0 && framesProcessedInDeviceFormat == 0) {
            break;  /* Done. */
        }
    }

    return MA_SUCCESS;
}

static ma_result ma_device__handle_duplex_callback_playback(ma_device* pDevice, ma_uint32 frameCount, void* pFramesInInternalFormat, ma_pcm_rb* pRB)
{
    ma_result result;
    ma_uint8 silentInputFrames[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
    ma_uint32 totalFramesReadOut = 0;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(frameCount > 0);
    MA_ASSERT(pFramesInInternalFormat != NULL);
    MA_ASSERT(pRB != NULL);
    MA_ASSERT(pDevice->playback.pInputCache != NULL);

    /*
    Sitting in the ring buffer should be captured data from the capture callback in external format. If there's not enough data in there for
    the whole frameCount frames we just use silence instead for the input data.
    */
    MA_ZERO_MEMORY(silentInputFrames, sizeof(silentInputFrames));

    while (totalFramesReadOut < frameCount && ma_device_is_started(pDevice)) {
        /*
        We should have a buffer allocated on the heap. Any playback frames still sitting in there
        need to be sent to the internal device before we process any more data from the client.
        */
        if (pDevice->playback.inputCacheRemaining > 0) {
            ma_uint64 framesConvertedIn  = pDevice->playback.inputCacheRemaining;
            ma_uint64 framesConvertedOut = (frameCount - totalFramesReadOut);
            ma_data_converter_process_pcm_frames(&pDevice->playback.converter, ma_offset_pcm_frames_ptr(pDevice->playback.pInputCache, pDevice->playback.inputCacheConsumed, pDevice->playback.format, pDevice->playback.channels), &framesConvertedIn, pF...

            pDevice->playback.inputCacheConsumed  += framesConvertedIn;
            pDevice->playback.inputCacheRemaining -= framesConvertedIn;

            totalFramesReadOut        += (ma_uint32)framesConvertedOut; /* Safe cast. */
            pFramesInInternalFormat    = ma_offset_ptr(pFramesInInternalFormat, framesConvertedOut * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
        }

        /* If there's no more data in the cache we'll need to fill it with some. */
        if (totalFramesReadOut < frameCount && pDevice->playback.inputCacheRemaining == 0) {
            ma_uint32 inputFrameCount;
            void* pInputFrames;

            inputFrameCount = (ma_uint32)pDevice->playback.inputCacheCap;
            result = ma_pcm_rb_acquire_read(pRB, &inputFrameCount, &pInputFrames);
            if (result == MA_SUCCESS) {
                if (inputFrameCount > 0) {
                    ma_device__handle_data_callback(pDevice, pDevice->playback.pInputCache, pInputFrames, inputFrameCount);
                } else {
                    if (ma_pcm_rb_pointer_distance(pRB) == 0) {
                        break;  /* Underrun. */
                    }
                }
            } else {
                /* No capture data available. Feed in silence. */
                inputFrameCount = (ma_uint32)ma_min(pDevice->playback.inputCacheCap, sizeof(silentInputFrames) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels));
                ma_device__handle_data_callback(pDevice, pDevice->playback.pInputCache, silentInputFrames, inputFrameCount);
            }

            pDevice->playback.inputCacheConsumed  = 0;
            pDevice->playback.inputCacheRemaining = inputFrameCount;

            result = ma_pcm_rb_commit_read(pRB, inputFrameCount);
            if (result != MA_SUCCESS) {
                return result;  /* Should never happen. */
            }

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

    ma_uint32 playbackDeviceDataCapInFrames = 0;

    MA_ASSERT(pDevice != NULL);

    /* Just some quick validation on the device type and the available callbacks. */
    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex || pDevice->type == ma_device_type_loopback) {
        if (pDevice->pContext->callbacks.onDeviceRead == NULL) {
            return MA_NOT_IMPLEMENTED;
        }

        capturedDeviceDataCapInFrames = sizeof(capturedDeviceData) / ma_get_bytes_per_frame(pDevice->capture.internalFormat,  pDevice->capture.internalChannels);
    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        if (pDevice->pContext->callbacks.onDeviceWrite == NULL) {
            return MA_NOT_IMPLEMENTED;
        }

        playbackDeviceDataCapInFrames = sizeof(playbackDeviceData) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    }

    /* NOTE: The device was started outside of this function, in the worker thread. */

    while (ma_device_get_state(pDevice) == ma_device_state_started && !exitLoop) {
        switch (pDevice->type) {
            case ma_device_type_duplex:
            {
                /* The process is: onDeviceRead() -> convert -> callback -> convert -> onDeviceWrite() */
                ma_uint32 totalCapturedDeviceFramesProcessed = 0;

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

                        break;
                    }

                    capturedDeviceFramesRemaining = capturedDeviceFramesToProcess;
                    capturedDeviceFramesProcessed = 0;

                    /* At this point we have our captured data in device format and we now need to convert it to client format. */
                    for (;;) {
                        ma_uint8  capturedClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint8  playbackClientData[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                        ma_uint32 capturedClientDataCapInFrames = sizeof(capturedClientData) / ma_get_bytes_per_frame(pDevice->capture.format,  pDevice->capture.channels);
                        ma_uint32 playbackClientDataCapInFrames = sizeof(playbackClientData) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
                        ma_uint64 capturedClientFramesToProcessThisIteration = ma_min(capturedClientDataCapInFrames, playbackClientDataCapInFrames);
                        ma_uint64 capturedDeviceFramesToProcessThisIteration = capturedDeviceFramesRemaining;
                        ma_uint8* pRunningCapturedDeviceFrames = ma_offset_ptr(capturedDeviceData, capturedDeviceFramesProcessed * ma_get_bytes_per_frame(pDevice->capture.internalFormat,  pDevice->capture.internalChannels));

                        /* Convert capture data from device format to client format. */
                        result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningCapturedDeviceFrames, &capturedDeviceFramesToProcessThisIteration, capturedClientData, &capturedClientFramesToProcessThisIteration);
                        if (result != MA_SUCCESS) {
                            break;
                        }

                        /*
                        If we weren't able to generate any output frames it must mean we've exhaused all of our input. The only time this would not be the case is if capturedClientData was too small
                        which should never be the case when it's of the size MA_DATA_CONVERTER_STACK_BUFFER_SIZE.
                        */
                        if (capturedClientFramesToProcessThisIteration == 0) {
                            break;
                        }

                        ma_device__handle_data_callback(pDevice, playbackClientData, capturedClientData, (ma_uint32)capturedClientFramesToProcessThisIteration);    /* Safe cast .*/

                        capturedDeviceFramesProcessed += (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */
                        capturedDeviceFramesRemaining -= (ma_uint32)capturedDeviceFramesToProcessThisIteration; /* Safe cast. */

                        /* At this point the playbackClientData buffer should be holding data that needs to be written to the device. */
                        for (;;) {
                            ma_uint64 convertedClientFrameCount = capturedClientFramesToProcessThisIteration;
                            ma_uint64 convertedDeviceFrameCount = playbackDeviceDataCapInFrames;
                            result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, playbackClientData, &convertedClientFrameCount, playbackDeviceData, &convertedDeviceFrameCount);
                            if (result != MA_SUCCESS) {
                                break;
                            }

                            result = pDevice->pContext->callbacks.onDeviceWrite(pDevice, playbackDeviceData, (ma_uint32)convertedDeviceFrameCount, NULL);   /* Safe cast. */
                            if (result != MA_SUCCESS) {
                                exitLoop = MA_TRUE;
                                break;
                            }

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

                    }

                    totalCapturedDeviceFramesProcessed += capturedDeviceFramesProcessed;
                }
            } break;

            case ma_device_type_capture:
            case ma_device_type_loopback:
            {
                ma_uint32 periodSizeInFrames = pDevice->capture.internalPeriodSizeInFrames;
                ma_uint32 framesReadThisPeriod = 0;
                while (framesReadThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesReadThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToReadThisIteration = framesRemainingInPeriod;
                    if (framesToReadThisIteration > capturedDeviceDataCapInFrames) {
                        framesToReadThisIteration = capturedDeviceDataCapInFrames;
                    }

                    result = pDevice->pContext->callbacks.onDeviceRead(pDevice, capturedDeviceData, framesToReadThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    /* Make sure we don't get stuck in the inner loop. */
                    if (framesProcessed == 0) {
                        break;
                    }

                    ma_device__send_frames_to_client(pDevice, framesProcessed, capturedDeviceData);

                    framesReadThisPeriod += framesProcessed;
                }
            } break;

            case ma_device_type_playback:
            {
                /* We write in chunks of the period size, but use a stack allocated buffer for the intermediary. */
                ma_uint32 periodSizeInFrames = pDevice->playback.internalPeriodSizeInFrames;
                ma_uint32 framesWrittenThisPeriod = 0;
                while (framesWrittenThisPeriod < periodSizeInFrames) {
                    ma_uint32 framesRemainingInPeriod = periodSizeInFrames - framesWrittenThisPeriod;
                    ma_uint32 framesProcessed;
                    ma_uint32 framesToWriteThisIteration = framesRemainingInPeriod;
                    if (framesToWriteThisIteration > playbackDeviceDataCapInFrames) {
                        framesToWriteThisIteration = playbackDeviceDataCapInFrames;
                    }

                    ma_device__read_frames_from_client(pDevice, framesToWriteThisIteration, playbackDeviceData);

                    result = pDevice->pContext->callbacks.onDeviceWrite(pDevice, playbackDeviceData, framesToWriteThisIteration, &framesProcessed);
                    if (result != MA_SUCCESS) {
                        exitLoop = MA_TRUE;
                        break;
                    }

                    /* Make sure we don't get stuck in the inner loop. */
                    if (framesProcessed == 0) {
                        break;
                    }

                    framesWrittenThisPeriod += framesProcessed;
                }
            } break;

            /* Should never get here. */
            default: break;
        }
    }

    return result;
}

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

    }

    /* We want everything to be synchronous so we're going to wait for the worker thread to complete it's operation. */
    if (ma_event_wait(&pDevice->null_device.operationCompletionEvent) != MA_SUCCESS) {
        return MA_ERROR;
    }

    return pDevice->null_device.operationResult;
}

static ma_uint64 ma_device_get_total_run_time_in_frames__null(ma_device* pDevice)
{
    ma_uint32 internalSampleRate;
    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        internalSampleRate = pDevice->capture.internalSampleRate;
    } else {
        internalSampleRate = pDevice->playback.internalSampleRate;
    }

    return (ma_uint64)((pDevice->null_device.priorRunTime + ma_timer_get_time_in_seconds(&pDevice->null_device.timer)) * internalSampleRate);
}

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

    /* The null backend supports everything exactly as we specify it. */
    if (pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) {
        pDescriptorCapture->format     = (pDescriptorCapture->format     != ma_format_unknown) ? pDescriptorCapture->format     : MA_DEFAULT_FORMAT;
        pDescriptorCapture->channels   = (pDescriptorCapture->channels   != 0)                 ? pDescriptorCapture->channels   : MA_DEFAULT_CHANNELS;
        pDescriptorCapture->sampleRate = (pDescriptorCapture->sampleRate != 0)                 ? pDescriptorCapture->sampleRate : MA_DEFAULT_SAMPLE_RATE;

        if (pDescriptorCapture->channelMap[0] == MA_CHANNEL_NONE) {
            ma_channel_map_init_standard(ma_standard_channel_map_default, pDescriptorCapture->channelMap, ma_countof(pDescriptorCapture->channelMap), pDescriptorCapture->channels);
        }

        pDescriptorCapture->periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptorCapture, pDescriptorCapture->sampleRate, pConfig->performanceProfile);
    }

    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        pDescriptorPlayback->format     = (pDescriptorPlayback->format     != ma_format_unknown) ? pDescriptorPlayback->format     : MA_DEFAULT_FORMAT;
        pDescriptorPlayback->channels   = (pDescriptorPlayback->channels   != 0)                 ? pDescriptorPlayback->channels   : MA_DEFAULT_CHANNELS;
        pDescriptorPlayback->sampleRate = (pDescriptorPlayback->sampleRate != 0)                 ? pDescriptorPlayback->sampleRate : MA_DEFAULT_SAMPLE_RATE;

        if (pDescriptorPlayback->channelMap[0] == MA_CHANNEL_NONE) {
            ma_channel_map_init_standard(ma_standard_channel_map_default, pDescriptorPlayback->channelMap, ma_countof(pDescriptorCapture->channelMap), pDescriptorPlayback->channels);
        }

        pDescriptorPlayback->periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptorPlayback, pDescriptorPlayback->sampleRate, pConfig->performanceProfile);
    }

    /*
    In order to get timing right, we need to create a thread that does nothing but keeps track of the timer. This timer is started when the
    first period is "written" to it, and then stopped in ma_device_stop__null().
    */
    result = ma_event_init(&pDevice->null_device.operationEvent);
    if (result != MA_SUCCESS) {
        return result;
    }

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

static ma_result ma_device_stop__null(ma_device* pDevice)
{
    MA_ASSERT(pDevice != NULL);

    ma_device_do_operation__null(pDevice, MA_DEVICE_OP_SUSPEND__NULL);

    c89atomic_exchange_32(&pDevice->null_device.isStarted, MA_FALSE);
    return MA_SUCCESS;
}

static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    ma_result result = MA_SUCCESS;
    ma_uint32 totalPCMFramesProcessed;
    ma_bool32 wasStartedOnEntry;

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

    wasStartedOnEntry = c89atomic_load_32(&pDevice->null_device.isStarted);

    /* Keep going until everything has been read. */
    totalPCMFramesProcessed = 0;
    while (totalPCMFramesProcessed < frameCount) {
        ma_uint64 targetFrame;

        /* If there are any frames remaining in the current period, consume those first. */
        if (pDevice->null_device.currentPeriodFramesRemainingPlayback > 0) {
            ma_uint32 framesRemaining = (frameCount - totalPCMFramesProcessed);
            ma_uint32 framesToProcess = pDevice->null_device.currentPeriodFramesRemainingPlayback;
            if (framesToProcess > framesRemaining) {
                framesToProcess = framesRemaining;
            }

            /* We don't actually do anything with pPCMFrames, so just mark it as unused to prevent a warning. */
            (void)pPCMFrames;

            pDevice->null_device.currentPeriodFramesRemainingPlayback -= framesToProcess;
            totalPCMFramesProcessed += framesToProcess;
        }

        /* If we've consumed the current period we'll need to mark it as such an ensure the device is started if it's not already. */
        if (pDevice->null_device.currentPeriodFramesRemainingPlayback == 0) {
            pDevice->null_device.currentPeriodFramesRemainingPlayback = 0;

            if (!c89atomic_load_32(&pDevice->null_device.isStarted) && !wasStartedOnEntry) {
                result = ma_device_start__null(pDevice);
                if (result != MA_SUCCESS) {
                    break;
                }
            }
        }

        /* If we've consumed the whole buffer we can return now. */
        MA_ASSERT(totalPCMFramesProcessed <= frameCount);
        if (totalPCMFramesProcessed == frameCount) {
            break;
        }

        /* Getting here means we've still got more frames to consume, we but need to wait for it to become available. */
        targetFrame = pDevice->null_device.lastProcessedFramePlayback;
        for (;;) {
            ma_uint64 currentFrame;

            /* Stop waiting if the device has been stopped. */
            if (!c89atomic_load_32(&pDevice->null_device.isStarted)) {
                break;
            }

            currentFrame = ma_device_get_total_run_time_in_frames__null(pDevice);
            if (currentFrame >= targetFrame) {
                break;
            }

            /* Getting here means we haven't yet reached the target sample, so continue waiting. */
            ma_sleep(10);
        }

        pDevice->null_device.lastProcessedFramePlayback          += pDevice->playback.internalPeriodSizeInFrames;
        pDevice->null_device.currentPeriodFramesRemainingPlayback = pDevice->playback.internalPeriodSizeInFrames;
    }

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

    return result;
}

static ma_result ma_device_read__null(ma_device* pDevice, void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    ma_result result = MA_SUCCESS;
    ma_uint32 totalPCMFramesProcessed;

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

    /* Keep going until everything has been read. */
    totalPCMFramesProcessed = 0;
    while (totalPCMFramesProcessed < frameCount) {
        ma_uint64 targetFrame;

        /* If there are any frames remaining in the current period, consume those first. */
        if (pDevice->null_device.currentPeriodFramesRemainingCapture > 0) {
            ma_uint32 bpf = ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
            ma_uint32 framesRemaining = (frameCount - totalPCMFramesProcessed);
            ma_uint32 framesToProcess = pDevice->null_device.currentPeriodFramesRemainingCapture;
            if (framesToProcess > framesRemaining) {
                framesToProcess = framesRemaining;
            }

            /* We need to ensure the output buffer is zeroed. */
            MA_ZERO_MEMORY(ma_offset_ptr(pPCMFrames, totalPCMFramesProcessed*bpf), framesToProcess*bpf);

            pDevice->null_device.currentPeriodFramesRemainingCapture -= framesToProcess;
            totalPCMFramesProcessed += framesToProcess;
        }

        /* If we've consumed the current period we'll need to mark it as such an ensure the device is started if it's not already. */
        if (pDevice->null_device.currentPeriodFramesRemainingCapture == 0) {
            pDevice->null_device.currentPeriodFramesRemainingCapture = 0;
        }

        /* If we've consumed the whole buffer we can return now. */
        MA_ASSERT(totalPCMFramesProcessed <= frameCount);
        if (totalPCMFramesProcessed == frameCount) {
            break;
        }

        /* Getting here means we've still got more frames to consume, we but need to wait for it to become available. */
        targetFrame = pDevice->null_device.lastProcessedFrameCapture + pDevice->capture.internalPeriodSizeInFrames;
        for (;;) {
            ma_uint64 currentFrame;

            /* Stop waiting if the device has been stopped. */
            if (!c89atomic_load_32(&pDevice->null_device.isStarted)) {
                break;
            }

            currentFrame = ma_device_get_total_run_time_in_frames__null(pDevice);
            if (currentFrame >= targetFrame) {
                break;
            }

            /* Getting here means we haven't yet reached the target sample, so continue waiting. */
            ma_sleep(10);
        }

        pDevice->null_device.lastProcessedFrameCapture          += pDevice->capture.internalPeriodSizeInFrames;
        pDevice->null_device.currentPeriodFramesRemainingCapture = pDevice->capture.internalPeriodSizeInFrames;

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


    /* Get the internal channel map based on the channel mask. */
    ma_channel_mask_to_channel_map__win32(wf.dwChannelMask, pData->channelsOut, pData->channelMapOut);

    /* Period size. */
    pData->periodsOut = (pData->periodsIn != 0) ? pData->periodsIn : MA_DEFAULT_PERIODS;
    pData->periodSizeInFramesOut = pData->periodSizeInFramesIn;
    if (pData->periodSizeInFramesOut == 0) {
        if (pData->periodSizeInMillisecondsIn == 0) {
            if (pData->performanceProfile == ma_performance_profile_low_latency) {
                pData->periodSizeInFramesOut = ma_calculate_buffer_size_in_frames_from_milliseconds(MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_LOW_LATENCY, wf.Format.nSamplesPerSec);
            } else {
                pData->periodSizeInFramesOut = ma_calculate_buffer_size_in_frames_from_milliseconds(MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_CONSERVATIVE, wf.Format.nSamplesPerSec);
            }
        } else {
            pData->periodSizeInFramesOut = ma_calculate_buffer_size_in_frames_from_milliseconds(pData->periodSizeInMillisecondsIn, wf.Format.nSamplesPerSec);
        }
    }

    periodDurationInMicroseconds = ((ma_uint64)pData->periodSizeInFramesOut * 1000 * 1000) / wf.Format.nSamplesPerSec;


    /* Slightly different initialization for shared and exclusive modes. We try exclusive mode first, and if it fails, fall back to shared mode. */
    if (shareMode == MA_AUDCLNT_SHAREMODE_EXCLUSIVE) {
        MA_REFERENCE_TIME bufferDuration = periodDurationInMicroseconds * pData->periodsOut * 10;

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

        ma_IMMDeviceEnumerator_Release(pDeviceEnumerator);
    }
#endif

    c89atomic_exchange_32(&pDevice->wasapi.isStartedCapture,  MA_FALSE);
    c89atomic_exchange_32(&pDevice->wasapi.isStartedPlayback, MA_FALSE);

    return MA_SUCCESS;
}

static ma_result ma_device__get_available_frames__wasapi(ma_device* pDevice, ma_IAudioClient* pAudioClient, ma_uint32* pFrameCount)
{
    ma_uint32 paddingFramesCount;
    HRESULT hr;
    ma_share_mode shareMode;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pFrameCount != NULL);

    *pFrameCount = 0;

    if ((ma_ptr)pAudioClient != pDevice->wasapi.pAudioClientPlayback && (ma_ptr)pAudioClient != pDevice->wasapi.pAudioClientCapture) {
        return MA_INVALID_OPERATION;
    }

    /*
    I've had a report that GetCurrentPadding() is returning a frame count of 0 which is preventing
    higher level function calls from doing anything because it thinks nothing is available. I have
    taken a look at the documentation and it looks like this is unnecessary in exclusive mode.

    From Microsoft's documentation:

        For an exclusive-mode rendering or capture stream that was initialized with the
        AUDCLNT_STREAMFLAGS_EVENTCALLBACK flag, the client typically has no use for the padding
        value reported by GetCurrentPadding. Instead, the client accesses an entire buffer during
        each processing pass.

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

            pDevice->wasapi.pMappedBufferCapture   = NULL;
            pDevice->wasapi.mappedBufferCaptureCap = 0;
            pDevice->wasapi.mappedBufferCaptureLen = 0;
        }

        c89atomic_exchange_32(&pDevice->wasapi.isStartedCapture, MA_FALSE);
    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        /*
        The buffer needs to be drained before stopping the device. Not doing this will result in the last few frames not getting output to
        the speakers. This is a problem for very short sounds because it'll result in a significant portion of it not getting played.
        */
        if (c89atomic_load_32(&pDevice->wasapi.isStartedPlayback)) {
            /* We need to make sure we put a timeout here or else we'll risk getting stuck in a deadlock in some cases. */
            DWORD waitTime = pDevice->wasapi.actualBufferSizeInFramesPlayback / pDevice->playback.internalSampleRate;

            if (pDevice->playback.shareMode == ma_share_mode_exclusive) {
                WaitForSingleObject(pDevice->wasapi.hEventPlayback, waitTime);
            } else {
                ma_uint32 prevFramesAvaialablePlayback = (ma_uint32)-1;
                ma_uint32 framesAvailablePlayback;
                for (;;) {
                    result = ma_device__get_available_frames__wasapi(pDevice, (ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback, &framesAvailablePlayback);
                    if (result != MA_SUCCESS) {
                        break;
                    }

                    if (framesAvailablePlayback >= pDevice->wasapi.actualBufferSizeInFramesPlayback) {
                        break;
                    }

                    /*
                    Just a safety check to avoid an infinite loop. If this iteration results in a situation where the number of available frames
                    has not changed, get out of the loop. I don't think this should ever happen, but I think it's nice to have just in case.
                    */
                    if (framesAvailablePlayback == prevFramesAvaialablePlayback) {
                        break;
                    }
                    prevFramesAvaialablePlayback = framesAvailablePlayback;

                    WaitForSingleObject(pDevice->wasapi.hEventPlayback, waitTime);
                    ResetEvent(pDevice->wasapi.hEventPlayback); /* Manual reset. */
                }
            }
        }

        hr = ma_IAudioClient_Stop((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback);
        if (FAILED(hr)) {
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to stop internal playback device.");

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

    }

    return MA_SUCCESS;
}


#ifndef MA_WASAPI_WAIT_TIMEOUT_MILLISECONDS
#define MA_WASAPI_WAIT_TIMEOUT_MILLISECONDS 5000
#endif

static ma_result ma_device_read__wasapi(ma_device* pDevice, void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    ma_result result = MA_SUCCESS;
    ma_uint32 totalFramesProcessed = 0;

    /*
    When reading, we need to get a buffer and process all of it before releasing it. Because the
    frame count (frameCount) can be different to the size of the buffer, we'll need to cache the
    pointer to the buffer.
    */

    /* Keep running until we've processed the requested number of frames. */
    while (ma_device_get_state(pDevice) == ma_device_state_started && totalFramesProcessed < frameCount) {
        ma_uint32 framesRemaining = frameCount - totalFramesProcessed;

        /* If we have a mapped data buffer, consume that first. */
        if (pDevice->wasapi.pMappedBufferCapture != NULL) {
            /* We have a cached data pointer so consume that before grabbing another one from WASAPI. */
            ma_uint32 framesToProcessNow = framesRemaining;
            if (framesToProcessNow > pDevice->wasapi.mappedBufferCaptureLen) {
                framesToProcessNow = pDevice->wasapi.mappedBufferCaptureLen;
            }

            /* Now just copy the data over to the output buffer. */
            ma_copy_pcm_frames(
                ma_offset_pcm_frames_ptr(pFrames, totalFramesProcessed, pDevice->capture.internalFormat, pDevice->capture.internalChannels),
                ma_offset_pcm_frames_const_ptr(pDevice->wasapi.pMappedBufferCapture, pDevice->wasapi.mappedBufferCaptureCap - pDevice->wasapi.mappedBufferCaptureLen, pDevice->capture.internalFormat, pDevice->capture.internalChannels),
                framesToProcessNow,
                pDevice->capture.internalFormat, pDevice->capture.internalChannels
            );

            totalFramesProcessed                   += framesToProcessNow;
            pDevice->wasapi.mappedBufferCaptureLen -= framesToProcessNow;

            /* If the data buffer has been fully consumed we need to release it. */
            if (pDevice->wasapi.mappedBufferCaptureLen == 0) {
                ma_IAudioCaptureClient_ReleaseBuffer((ma_IAudioCaptureClient*)pDevice->wasapi.pCaptureClient, pDevice->wasapi.mappedBufferCaptureCap);
                pDevice->wasapi.pMappedBufferCapture   = NULL;
                pDevice->wasapi.mappedBufferCaptureCap = 0;
            }
        } else {
            /* We don't have any cached data pointer, so grab another one. */
            HRESULT hr;

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

                    /* An error occured and we need to abort. */
                    ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to retrieve internal buffer from capture device in preparation for reading from the device. HRESULT = %d. Stopping device.\n", (int)hr);
                    result = ma_result_from_HRESULT(hr);
                    break;
                }
            }
        }
    }

    /*
    If we were unable to process the entire requested frame count, but we still have a mapped buffer,
    there's a good chance either an error occurred or the device was stopped mid-read. In this case
    we'll need to make sure the buffer is released.
    */
    if (totalFramesProcessed < frameCount && pDevice->wasapi.pMappedBufferCapture != NULL) {
        ma_IAudioCaptureClient_ReleaseBuffer((ma_IAudioCaptureClient*)pDevice->wasapi.pCaptureClient, pDevice->wasapi.mappedBufferCaptureCap);
        pDevice->wasapi.pMappedBufferCapture   = NULL;
        pDevice->wasapi.mappedBufferCaptureCap = 0;
        pDevice->wasapi.mappedBufferCaptureLen = 0;
    }

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

    return result;
}

static ma_result ma_device_write__wasapi(ma_device* pDevice, const void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    ma_result result = MA_SUCCESS;
    ma_uint32 totalFramesProcessed = 0;

    /* Keep writing to the device until it's stopped or we've consumed all of our input. */
    while (ma_device_get_state(pDevice) == ma_device_state_started && totalFramesProcessed < frameCount) {
        ma_uint32 framesRemaining = frameCount - totalFramesProcessed;

        /*
        We're going to do this in a similar way to capture. We'll first check if the cached data pointer
        is valid, and if so, read from that. Otherwise We will call IAudioRenderClient_GetBuffer() with
        a requested buffer size equal to our actual period size. If it returns AUDCLNT_E_BUFFER_TOO_LARGE
        it means we need to wait for some data to become available.
        */
        if (pDevice->wasapi.pMappedBufferPlayback != NULL) {
            /* We still have some space available in the mapped data buffer. Write to it. */
            ma_uint32 framesToProcessNow = framesRemaining;
            if (framesToProcessNow > (pDevice->wasapi.mappedBufferPlaybackCap - pDevice->wasapi.mappedBufferPlaybackLen)) {
                framesToProcessNow = (pDevice->wasapi.mappedBufferPlaybackCap - pDevice->wasapi.mappedBufferPlaybackLen);
            }

            /* Now just copy the data over to the output buffer. */
            ma_copy_pcm_frames(
                ma_offset_pcm_frames_ptr(pDevice->wasapi.pMappedBufferPlayback, pDevice->wasapi.mappedBufferPlaybackLen, pDevice->playback.internalFormat, pDevice->playback.internalChannels),
                ma_offset_pcm_frames_const_ptr(pFrames, totalFramesProcessed, pDevice->playback.internalFormat, pDevice->playback.internalChannels),
                framesToProcessNow,
                pDevice->playback.internalFormat, pDevice->playback.internalChannels
            );

            totalFramesProcessed                    += framesToProcessNow;
            pDevice->wasapi.mappedBufferPlaybackLen += framesToProcessNow;

            /* If the data buffer has been fully consumed we need to release it. */
            if (pDevice->wasapi.mappedBufferPlaybackLen == pDevice->wasapi.mappedBufferPlaybackCap) {
                ma_IAudioRenderClient_ReleaseBuffer((ma_IAudioRenderClient*)pDevice->wasapi.pRenderClient, pDevice->wasapi.mappedBufferPlaybackCap, 0);
                pDevice->wasapi.pMappedBufferPlayback   = NULL;
                pDevice->wasapi.mappedBufferPlaybackCap = 0;
                pDevice->wasapi.mappedBufferPlaybackLen = 0;

                /*
                In exclusive mode we need to wait here. Exclusive mode is weird because GetBuffer() never

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

    pWF->Format.wBitsPerSample       = (WORD)(ma_get_bytes_per_sample(format)*8);
    pWF->Format.nBlockAlign          = (WORD)(pWF->Format.nChannels * pWF->Format.wBitsPerSample / 8);
    pWF->Format.nAvgBytesPerSec      = pWF->Format.nBlockAlign * pWF->Format.nSamplesPerSec;
    pWF->Samples.wValidBitsPerSample = pWF->Format.wBitsPerSample;
    pWF->dwChannelMask               = ma_channel_map_to_channel_mask__win32(pChannelMap, channels);
    pWF->SubFormat                   = subformat;

    return MA_SUCCESS;
}

static ma_uint32 ma_calculate_period_size_in_frames_from_descriptor__dsound(const ma_device_descriptor* pDescriptor, ma_uint32 nativeSampleRate, ma_performance_profile performanceProfile)
{
    /*
    DirectSound has a minimum period size of 20ms. In practice, this doesn't seem to be enough for
    reliable glitch-free processing so going to use 30ms instead.
    */
    ma_uint32 minPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(30, nativeSampleRate);
    ma_uint32 periodSizeInFrames;

    periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptor, nativeSampleRate, performanceProfile);
    if (periodSizeInFrames < minPeriodSizeInFrames) {
        periodSizeInFrames = minPeriodSizeInFrames;
    }

    return periodSizeInFrames;
}

static ma_result ma_device_init__dsound(ma_device* pDevice, const ma_device_config* pConfig, ma_device_descriptor* pDescriptorPlayback, ma_device_descriptor* pDescriptorCapture)
{
    ma_result result;

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

            ma_device_uninit__dsound(pDevice);
            return result;
        }

        wf.Format.nBlockAlign          = (WORD)(wf.Format.nChannels * wf.Format.wBitsPerSample / 8);
        wf.Format.nAvgBytesPerSec      = wf.Format.nBlockAlign * wf.Format.nSamplesPerSec;
        wf.Samples.wValidBitsPerSample = wf.Format.wBitsPerSample;
        wf.SubFormat                   = MA_GUID_KSDATAFORMAT_SUBTYPE_PCM;

        /* The size of the buffer must be a clean multiple of the period count. */
        periodSizeInFrames = ma_calculate_period_size_in_frames_from_descriptor__dsound(pDescriptorCapture, wf.Format.nSamplesPerSec, pConfig->performanceProfile);
        periodCount = (pDescriptorCapture->periodCount > 0) ? pDescriptorCapture->periodCount : MA_DEFAULT_PERIODS;

        MA_ZERO_OBJECT(&descDS);
        descDS.dwSize        = sizeof(descDS);
        descDS.dwFlags       = 0;
        descDS.dwBufferBytes = periodSizeInFrames * periodCount * wf.Format.nBlockAlign;
        descDS.lpwfxFormat   = (WAVEFORMATEX*)&wf;
        hr = ma_IDirectSoundCapture_CreateCaptureBuffer((ma_IDirectSoundCapture*)pDevice->dsound.pCapture, &descDS, (ma_IDirectSoundCaptureBuffer**)&pDevice->dsound.pCaptureBuffer, NULL);
        if (FAILED(hr)) {
            ma_device_uninit__dsound(pDevice);

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

        pDescriptorCapture->sampleRate = pActualFormat->Format.nSamplesPerSec;

        /* Get the native channel map based on the channel mask. */
        if (pActualFormat->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
            ma_channel_mask_to_channel_map__win32(pActualFormat->dwChannelMask, pDescriptorCapture->channels, pDescriptorCapture->channelMap);
        } else {
            ma_channel_mask_to_channel_map__win32(wf.dwChannelMask, pDescriptorCapture->channels, pDescriptorCapture->channelMap);
        }

        /*
        After getting the actual format the size of the buffer in frames may have actually changed. However, we want this to be as close to what the
        user has asked for as possible, so let's go ahead and release the old capture buffer and create a new one in this case.
        */
        if (periodSizeInFrames != (descDS.dwBufferBytes / ma_get_bytes_per_frame(pDescriptorCapture->format, pDescriptorCapture->channels) / periodCount)) {
            descDS.dwBufferBytes = periodSizeInFrames * ma_get_bytes_per_frame(pDescriptorCapture->format, pDescriptorCapture->channels) * periodCount;
            ma_IDirectSoundCaptureBuffer_Release((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer);

            hr = ma_IDirectSoundCapture_CreateCaptureBuffer((ma_IDirectSoundCapture*)pDevice->dsound.pCapture, &descDS, (ma_IDirectSoundCaptureBuffer**)&pDevice->dsound.pCaptureBuffer, NULL);
            if (FAILED(hr)) {
                ma_device_uninit__dsound(pDevice);
                ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] Second attempt at IDirectSoundCapture_CreateCaptureBuffer() failed for capture device.");
                return ma_result_from_HRESULT(hr);
            }
        }

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

        pDescriptorPlayback->sampleRate = pActualFormat->Format.nSamplesPerSec;

        /* Get the internal channel map based on the channel mask. */
        if (pActualFormat->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
            ma_channel_mask_to_channel_map__win32(pActualFormat->dwChannelMask, pDescriptorPlayback->channels, pDescriptorPlayback->channelMap);
        } else {
            ma_channel_mask_to_channel_map__win32(wf.dwChannelMask, pDescriptorPlayback->channels, pDescriptorPlayback->channelMap);
        }

        /* The size of the buffer must be a clean multiple of the period count. */
        periodSizeInFrames = ma_calculate_period_size_in_frames_from_descriptor__dsound(pDescriptorPlayback, pDescriptorPlayback->sampleRate, pConfig->performanceProfile);
        periodCount = (pDescriptorPlayback->periodCount > 0) ? pDescriptorPlayback->periodCount : MA_DEFAULT_PERIODS;

        /*
        Meaning of dwFlags (from MSDN):

        DSBCAPS_CTRLPOSITIONNOTIFY
          The buffer has position notification capability.

        DSBCAPS_GLOBALFOCUS
          With this flag set, an application using DirectSound can continue to play its buffers if the user switches focus to
          another application, even if the new application uses DirectSound.

        DSBCAPS_GETCURRENTPOSITION2
          In the first version of DirectSound, the play cursor was significantly ahead of the actual playing sound on emulated
          sound cards; it was directly behind the write cursor. Now, if the DSBCAPS_GETCURRENTPOSITION2 flag is specified, the
          application can get a more accurate play cursor.
        */
        MA_ZERO_OBJECT(&descDS);
        descDS.dwSize = sizeof(descDS);
        descDS.dwFlags = MA_DSBCAPS_CTRLPOSITIONNOTIFY | MA_DSBCAPS_GLOBALFOCUS | MA_DSBCAPS_GETCURRENTPOSITION2;
        descDS.dwBufferBytes = periodSizeInFrames * periodCount * ma_get_bytes_per_frame(pDescriptorPlayback->format, pDescriptorPlayback->channels);
        descDS.lpwfxFormat = (WAVEFORMATEX*)&wf;
        hr = ma_IDirectSound_CreateSoundBuffer((ma_IDirectSound*)pDevice->dsound.pPlayback, &descDS, (ma_IDirectSoundBuffer**)&pDevice->dsound.pPlaybackBuffer, NULL);
        if (FAILED(hr)) {
            ma_device_uninit__dsound(pDevice);
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] IDirectSound_CreateSoundBuffer() failed for playback device's secondary buffer.");
            return ma_result_from_HRESULT(hr);
        }

        /* DirectSound should give us a buffer exactly the size we asked for. */
        pDescriptorPlayback->periodSizeInFrames = periodSizeInFrames;
        pDescriptorPlayback->periodCount        = periodCount;
    }

    return MA_SUCCESS;
}


static ma_result ma_device_data_loop__dsound(ma_device* pDevice)
{
    ma_result result = MA_SUCCESS;
    ma_uint32 bpfDeviceCapture  = ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
    ma_uint32 bpfDevicePlayback = ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    HRESULT hr;
    DWORD lockOffsetInBytesCapture;
    DWORD lockSizeInBytesCapture;
    DWORD mappedSizeInBytesCapture;
    DWORD mappedDeviceFramesProcessedCapture;
    void* pMappedDeviceBufferCapture;
    DWORD lockOffsetInBytesPlayback;
    DWORD lockSizeInBytesPlayback;
    DWORD mappedSizeInBytesPlayback;
    void* pMappedDeviceBufferPlayback;
    DWORD prevReadCursorInBytesCapture = 0;
    DWORD prevPlayCursorInBytesPlayback = 0;
    ma_bool32 physicalPlayCursorLoopFlagPlayback = 0;
    DWORD virtualWriteCursorInBytesPlayback = 0;
    ma_bool32 virtualWriteCursorLoopFlagPlayback = 0;
    ma_bool32 isPlaybackDeviceStarted = MA_FALSE;
    ma_uint32 framesWrittenToPlaybackDevice = 0;   /* For knowing whether or not the playback device needs to be started. */
    ma_uint32 waitTimeInMilliseconds = 1;

    MA_ASSERT(pDevice != NULL);

    /* The first thing to do is start the capture device. The playback device is only started after the first period is written. */
    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        hr = ma_IDirectSoundCaptureBuffer_Start((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, MA_DSCBSTART_LOOPING);
        if (FAILED(hr)) {
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundCaptureBuffer_Start() failed.");
            return ma_result_from_HRESULT(hr);

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

                }

                /* If nothing is available we just sleep for a bit and return from this iteration. */
                if (physicalReadCursorInBytes == prevReadCursorInBytesCapture) {
                    ma_sleep(waitTimeInMilliseconds);
                    continue; /* Nothing is available in the capture buffer. */
                }

                /*
                The current position has moved. We need to map all of the captured samples and write them to the playback device, making sure
                we don't return until every frame has been copied over.
                */
                if (prevReadCursorInBytesCapture < physicalReadCursorInBytes) {
                    /* The capture position has not looped. This is the simple case. */
                    lockOffsetInBytesCapture = prevReadCursorInBytesCapture;
                    lockSizeInBytesCapture   = (physicalReadCursorInBytes - prevReadCursorInBytesCapture);
                } else {
                    /*
                    The capture position has looped. This is the more complex case. Map to the end of the buffer. If this does not return anything,
                    do it again from the start.
                    */

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

                    continue; /* Nothing is available in the capture buffer. */
                }

                hr = ma_IDirectSoundCaptureBuffer_Lock((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, lockOffsetInBytesCapture, lockSizeInBytesCapture, &pMappedDeviceBufferCapture, &mappedSizeInBytesCapture, NULL, NULL, 0);
                if (FAILED(hr)) {
                    ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to map buffer from capture device in preparation for writing to the device.");
                    return ma_result_from_HRESULT(hr);
                }


                /* At this point we have some input data that we need to output. We do not return until every mapped frame of the input data is written to the playback device. */
                mappedDeviceFramesProcessedCapture = 0;

                for (;;) {  /* Keep writing to the playback device. */
                    ma_uint8  inputFramesInClientFormat[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint32 inputFramesInClientFormatCap = sizeof(inputFramesInClientFormat) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
                    ma_uint8  outputFramesInClientFormat[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                    ma_uint32 outputFramesInClientFormatCap = sizeof(outputFramesInClientFormat) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
                    ma_uint32 outputFramesInClientFormatCount;
                    ma_uint32 outputFramesInClientFormatConsumed = 0;
                    ma_uint64 clientCapturedFramesToProcess = ma_min(inputFramesInClientFormatCap, outputFramesInClientFormatCap);
                    ma_uint64 deviceCapturedFramesToProcess = (mappedSizeInBytesCapture / bpfDeviceCapture) - mappedDeviceFramesProcessedCapture;
                    void* pRunningMappedDeviceBufferCapture = ma_offset_ptr(pMappedDeviceBufferCapture, mappedDeviceFramesProcessedCapture * bpfDeviceCapture);

                    result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningMappedDeviceBufferCapture, &deviceCapturedFramesToProcess, inputFramesInClientFormat, &clientCapturedFramesToProcess);
                    if (result != MA_SUCCESS) {
                        break;
                    }

                    outputFramesInClientFormatCount     = (ma_uint32)clientCapturedFramesToProcess;
                    mappedDeviceFramesProcessedCapture += (ma_uint32)deviceCapturedFramesToProcess;

                    ma_device__handle_data_callback(pDevice, outputFramesInClientFormat, inputFramesInClientFormat, (ma_uint32)clientCapturedFramesToProcess);

                    /* At this point we have input and output data in client format. All we need to do now is convert it to the output device format. This may take a few passes. */
                    for (;;) {
                        ma_uint32 framesWrittenThisIteration;
                        DWORD physicalPlayCursorInBytes;
                        DWORD physicalWriteCursorInBytes;
                        DWORD availableBytesPlayback;
                        DWORD silentPaddingInBytes = 0; /* <-- Must be initialized to 0. */

                        /* We need the physical play and write cursors. */
                        if (FAILED(ma_IDirectSoundBuffer_GetCurrentPosition((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, &physicalPlayCursorInBytes, &physicalWriteCursorInBytes))) {
                            break;
                        }

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

                                    silentPaddingInBytes = lockSizeInBytesPlayback;
                                }

                                ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_WARNING, "[DirectSound] (Duplex/Playback) Playback buffer starved. availableBytesPlayback=%ld, silentPaddingInBytes=%ld\n", availableBytesPlayback, silentPaddingInB...
                            }
                        }

                        /* At this point we have a buffer for output. */
                        if (silentPaddingInBytes > 0) {
                            MA_ZERO_MEMORY(pMappedDeviceBufferPlayback, silentPaddingInBytes);
                            framesWrittenThisIteration = silentPaddingInBytes/bpfDevicePlayback;
                        } else {
                            ma_uint64 convertedFrameCountIn  = (outputFramesInClientFormatCount - outputFramesInClientFormatConsumed);
                            ma_uint64 convertedFrameCountOut = mappedSizeInBytesPlayback/bpfDevicePlayback;
                            void* pConvertedFramesIn  = ma_offset_ptr(outputFramesInClientFormat, outputFramesInClientFormatConsumed * bpfDevicePlayback);
                            void* pConvertedFramesOut = pMappedDeviceBufferPlayback;

                            result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, pConvertedFramesIn, &convertedFrameCountIn, pConvertedFramesOut, &convertedFrameCountOut);
                            if (result != MA_SUCCESS) {
                                break;
                            }

                            outputFramesInClientFormatConsumed += (ma_uint32)convertedFrameCountOut;
                            framesWrittenThisIteration          = (ma_uint32)convertedFrameCountOut;
                        }


                        hr = ma_IDirectSoundBuffer_Unlock((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, pMappedDeviceBufferPlayback, framesWrittenThisIteration*bpfDevicePlayback, NULL, 0);
                        if (FAILED(hr)) {
                            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to unlock internal buffer from playback device after writing to the device.");
                            result = ma_result_from_HRESULT(hr);
                            break;
                        }

                        virtualWriteCursorInBytesPlayback += framesWrittenThisIteration*bpfDevicePlayback;
                        if ((virtualWriteCursorInBytesPlayback/bpfDevicePlayback) == pDevice->playback.internalPeriodSizeInFrames*pDevice->playback.internalPeriods) {
                            virtualWriteCursorInBytesPlayback  = 0;
                            virtualWriteCursorLoopFlagPlayback = !virtualWriteCursorLoopFlagPlayback;
                        }

                        /*
                        We may need to start the device. We want two full periods to be written before starting the playback device. Having an extra period adds
                        a bit of a buffer to prevent the playback buffer from getting starved.
                        */
                        framesWrittenToPlaybackDevice += framesWrittenThisIteration;
                        if (!isPlaybackDeviceStarted && framesWrittenToPlaybackDevice >= (pDevice->playback.internalPeriodSizeInFrames*2)) {
                            hr = ma_IDirectSoundBuffer_Play((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, 0, 0, MA_DSBPLAY_LOOPING);
                            if (FAILED(hr)) {
                                ma_IDirectSoundCaptureBuffer_Stop((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer);
                                ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundBuffer_Play() failed.");
                                return ma_result_from_HRESULT(hr);
                            }
                            isPlaybackDeviceStarted = MA_TRUE;
                        }

                        if (framesWrittenThisIteration < mappedSizeInBytesPlayback/bpfDevicePlayback) {
                            break;  /* We're finished with the output data.*/
                        }
                    }

                    if (clientCapturedFramesToProcess == 0) {
                        break;  /* We just consumed every input sample. */
                    }
                }


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

                hr = ma_IDirectSoundCaptureBuffer_Lock((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, lockOffsetInBytesCapture, lockSizeInBytesCapture, &pMappedDeviceBufferCapture, &mappedSizeInBytesCapture, NULL, NULL, 0);
                if (FAILED(hr)) {
                    ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to map buffer from capture device in preparation for writing to the device.");
                    result = ma_result_from_HRESULT(hr);
                }

                if (lockSizeInBytesCapture != mappedSizeInBytesCapture) {
                    ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[DirectSound] (Capture) lockSizeInBytesCapture=%ld != mappedSizeInBytesCapture=%ld\n", lockSizeInBytesCapture, mappedSizeInBytesCapture);
                }

                ma_device__send_frames_to_client(pDevice, mappedSizeInBytesCapture/bpfDeviceCapture, pMappedDeviceBufferCapture);

                hr = ma_IDirectSoundCaptureBuffer_Unlock((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, pMappedDeviceBufferCapture, mappedSizeInBytesCapture, NULL, 0);
                if (FAILED(hr)) {
                    ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to unlock internal buffer from capture device after reading from the device.");
                    return ma_result_from_HRESULT(hr);
                }
                prevReadCursorInBytesCapture = lockOffsetInBytesCapture + mappedSizeInBytesCapture;

                if (prevReadCursorInBytesCapture == (pDevice->capture.internalPeriodSizeInFrames*pDevice->capture.internalPeriods*bpfDeviceCapture)) {
                    prevReadCursorInBytesCapture = 0;

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

                }

                hr = ma_IDirectSoundBuffer_Lock((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, lockOffsetInBytesPlayback, lockSizeInBytesPlayback, &pMappedDeviceBufferPlayback, &mappedSizeInBytesPlayback, NULL, NULL, 0);
                if (FAILED(hr)) {
                    ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to map buffer from playback device in preparation for writing to the device.");
                    result = ma_result_from_HRESULT(hr);
                    break;
                }

                /* At this point we have a buffer for output. */
                ma_device__read_frames_from_client(pDevice, (mappedSizeInBytesPlayback/bpfDevicePlayback), pMappedDeviceBufferPlayback);

                hr = ma_IDirectSoundBuffer_Unlock((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, pMappedDeviceBufferPlayback, mappedSizeInBytesPlayback, NULL, 0);
                if (FAILED(hr)) {
                    ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to unlock internal buffer from playback device after writing to the device.");
                    result = ma_result_from_HRESULT(hr);
                    break;
                }

                virtualWriteCursorInBytesPlayback += mappedSizeInBytesPlayback;
                if (virtualWriteCursorInBytesPlayback == pDevice->playback.internalPeriodSizeInFrames*pDevice->playback.internalPeriods*bpfDevicePlayback) {
                    virtualWriteCursorInBytesPlayback  = 0;
                    virtualWriteCursorLoopFlagPlayback = !virtualWriteCursorLoopFlagPlayback;
                }

                /*
                We may need to start the device. We want two full periods to be written before starting the playback device. Having an extra period adds
                a bit of a buffer to prevent the playback buffer from getting starved.
                */
                framesWrittenToPlaybackDevice += mappedSizeInBytesPlayback/bpfDevicePlayback;
                if (!isPlaybackDeviceStarted && framesWrittenToPlaybackDevice >= pDevice->playback.internalPeriodSizeInFrames) {
                    hr = ma_IDirectSoundBuffer_Play((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, 0, 0, MA_DSBPLAY_LOOPING);
                    if (FAILED(hr)) {
                        ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundBuffer_Play() failed.");
                        return ma_result_from_HRESULT(hr);
                    }
                    isPlaybackDeviceStarted = MA_TRUE;
                }
            } break;


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

        }

        str += 1;
    }

    return last;
}

static ma_uint32 ma_get_period_size_in_bytes(ma_uint32 periodSizeInFrames, ma_format format, ma_uint32 channels)
{
    return periodSizeInFrames * ma_get_bytes_per_frame(format, channels);
}


/*
Our own "WAVECAPS" structure that contains generic information shared between WAVEOUTCAPS2 and WAVEINCAPS2 so
we can do things generically and typesafely. Names are being kept the same for consistency.
*/
typedef struct
{
    CHAR szPname[MAXPNAMELEN];

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

        CloseHandle((HANDLE)pDevice->winmm.hEventPlayback);
    }

    ma_free(pDevice->winmm._pHeapData, &pDevice->pContext->allocationCallbacks);

    MA_ZERO_OBJECT(&pDevice->winmm);   /* Safety. */

    return MA_SUCCESS;
}

static ma_uint32 ma_calculate_period_size_in_frames_from_descriptor__winmm(const ma_device_descriptor* pDescriptor, ma_uint32 nativeSampleRate, ma_performance_profile performanceProfile)
{
    /* WinMM has a minimum period size of 40ms. */
    ma_uint32 minPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(40, nativeSampleRate);
    ma_uint32 periodSizeInFrames;

    periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptor, nativeSampleRate, performanceProfile);
    if (periodSizeInFrames < minPeriodSizeInFrames) {
        periodSizeInFrames = minPeriodSizeInFrames;
    }

    return periodSizeInFrames;
}

static ma_result ma_device_init__winmm(ma_device* pDevice, const ma_device_config* pConfig, ma_device_descriptor* pDescriptorPlayback, ma_device_descriptor* pDescriptorCapture)
{
    const char* errorMsg = "";

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

        if (resultMM != MMSYSERR_NOERROR) {
            errorMsg = "[WinMM] Failed to open capture device.", errorCode = MA_FAILED_TO_OPEN_BACKEND_DEVICE;
            goto on_error;
        }

        pDescriptorCapture->format             = ma_format_from_WAVEFORMATEX(&wf);
        pDescriptorCapture->channels           = wf.nChannels;
        pDescriptorCapture->sampleRate         = wf.nSamplesPerSec;
        ma_channel_map_init_standard(ma_standard_channel_map_microsoft, pDescriptorCapture->channelMap, ma_countof(pDescriptorCapture->channelMap), pDescriptorCapture->channels);
        pDescriptorCapture->periodCount        = pDescriptorCapture->periodCount;
        pDescriptorCapture->periodSizeInFrames = ma_calculate_period_size_in_frames_from_descriptor__winmm(pDescriptorCapture, pDescriptorCapture->sampleRate, pConfig->performanceProfile);
    }

    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        WAVEOUTCAPSA caps;
        WAVEFORMATEX wf;
        MMRESULT resultMM;

        /* We use an event to know when a new fragment needs to be enqueued. */
        pDevice->winmm.hEventPlayback = (ma_handle)CreateEventW(NULL, TRUE, TRUE, NULL);
        if (pDevice->winmm.hEventPlayback == NULL) {

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

        if (resultMM != MMSYSERR_NOERROR) {
            errorMsg = "[WinMM] Failed to open playback device.", errorCode = MA_FAILED_TO_OPEN_BACKEND_DEVICE;
            goto on_error;
        }

        pDescriptorPlayback->format             = ma_format_from_WAVEFORMATEX(&wf);
        pDescriptorPlayback->channels           = wf.nChannels;
        pDescriptorPlayback->sampleRate         = wf.nSamplesPerSec;
        ma_channel_map_init_standard(ma_standard_channel_map_microsoft, pDescriptorPlayback->channelMap, ma_countof(pDescriptorPlayback->channelMap), pDescriptorPlayback->channels);
        pDescriptorPlayback->periodCount        = pDescriptorPlayback->periodCount;
        pDescriptorPlayback->periodSizeInFrames = ma_calculate_period_size_in_frames_from_descriptor__winmm(pDescriptorPlayback, pDescriptorPlayback->sampleRate, pConfig->performanceProfile);
    }

    /*
    The heap allocated data is allocated like so:

    [Capture WAVEHDRs][Playback WAVEHDRs][Capture Intermediary Buffer][Playback Intermediary Buffer]
    */
    heapSize = 0;
    if (pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) {
        heapSize += sizeof(WAVEHDR)*pDescriptorCapture->periodCount + (pDescriptorCapture->periodSizeInFrames * pDescriptorCapture->periodCount * ma_get_bytes_per_frame(pDescriptorCapture->format, pDescriptorCapture->channels));
    }
    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        heapSize += sizeof(WAVEHDR)*pDescriptorPlayback->periodCount + (pDescriptorPlayback->periodSizeInFrames * pDescriptorPlayback->periodCount * ma_get_bytes_per_frame(pDescriptorPlayback->format, pDescriptorPlayback->channels));
    }

    pDevice->winmm._pHeapData = (ma_uint8*)ma_calloc(heapSize, &pDevice->pContext->allocationCallbacks);
    if (pDevice->winmm._pHeapData == NULL) {
        errorMsg = "[WinMM] Failed to allocate memory for the intermediary buffer.", errorCode = MA_OUT_OF_MEMORY;
        goto on_error;
    }

    MA_ZERO_MEMORY(pDevice->winmm._pHeapData, heapSize);

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

    }

    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)*pDescriptorPlayback->periodCount);
        } else {
            pDevice->winmm.pWAVEHDRPlayback            = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDescriptorCapture->periodCount));
            pDevice->winmm.pIntermediaryBufferPlayback = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDescriptorCapture->periodCount + pDescriptorPlayback->periodCount)) + (pDescriptorCapture->periodSizeInFrames*pDescriptorCapture->periodCount*ma_g...
        }

        /* Prepare headers. */
        for (iPeriod = 0; iPeriod < pDescriptorPlayback->periodCount; ++iPeriod) {
            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;

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


        resultMM = ((MA_PFN_waveOutReset)pDevice->pContext->winmm.waveOutReset)((HWAVEOUT)pDevice->winmm.hDevicePlayback);
        if (resultMM != MMSYSERR_NOERROR) {
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_WARNING, "[WinMM] WARNING: Failed to reset playback device.");
        }
    }

    return MA_SUCCESS;
}

static ma_result ma_device_write__winmm(ma_device* pDevice, const void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    ma_result result = MA_SUCCESS;
    MMRESULT resultMM;
    ma_uint32 totalFramesWritten;
    WAVEHDR* pWAVEHDR;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pPCMFrames != NULL);

    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. */

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

                    ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WinMM] waveOutWrite() failed.");
                    break;
                }

                /* Make sure we move to the next header. */
                pDevice->winmm.iNextHeaderPlayback = (pDevice->winmm.iNextHeaderPlayback + 1) % pDevice->playback.internalPeriods;
                pDevice->winmm.headerFramesConsumedPlayback = 0;
            }

            /* If at this point we have consumed the entire input buffer we can return. */
            MA_ASSERT(totalFramesWritten <= frameCount);
            if (totalFramesWritten == frameCount) {
                break;
            }

            /* Getting here means there's more to process. */
            continue;
        }

        /* 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;

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

        }
    }

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

    return result;
}

static ma_result ma_device_read__winmm(ma_device* pDevice, void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    ma_result result = MA_SUCCESS;
    MMRESULT resultMM;
    ma_uint32 totalFramesRead;
    WAVEHDR* pWAVEHDR;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pPCMFrames != NULL);

    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. */

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

                    ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WinMM] waveInAddBuffer() failed.");
                    break;
                }

                /* Make sure we move to the next header. */
                pDevice->winmm.iNextHeaderCapture = (pDevice->winmm.iNextHeaderCapture + 1) % pDevice->capture.internalPeriods;
                pDevice->winmm.headerFramesConsumedCapture = 0;
            }

            /* If at this point we have filled the entire input buffer we can return. */
            MA_ASSERT(totalFramesRead <= frameCount);
            if (totalFramesRead == frameCount) {
                break;
            }

            /* Getting here means there's more to process. */
            continue;
        }

        /* 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;

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

            #define MA_INLINE_DEFINED
        #endif
    #endif
#endif
#include <alsa/asoundlib.h>
#if defined(MA_INLINE_DEFINED)
    #undef inline
    #undef MA_INLINE_DEFINED
#endif

typedef snd_pcm_uframes_t                       ma_snd_pcm_uframes_t;
typedef snd_pcm_sframes_t                       ma_snd_pcm_sframes_t;
typedef snd_pcm_stream_t                        ma_snd_pcm_stream_t;
typedef snd_pcm_format_t                        ma_snd_pcm_format_t;
typedef snd_pcm_access_t                        ma_snd_pcm_access_t;
typedef snd_pcm_t                               ma_snd_pcm_t;
typedef snd_pcm_hw_params_t                     ma_snd_pcm_hw_params_t;
typedef snd_pcm_sw_params_t                     ma_snd_pcm_sw_params_t;
typedef snd_pcm_format_mask_t                   ma_snd_pcm_format_mask_t;
typedef snd_pcm_info_t                          ma_snd_pcm_info_t;
typedef snd_pcm_channel_area_t                  ma_snd_pcm_channel_area_t;
typedef snd_pcm_chmap_t                         ma_snd_pcm_chmap_t;

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

#define MA_SND_CHMAP_BC                         SND_CHMAP_BC
#define MA_SND_CHMAP_BLC                        SND_CHMAP_BLC
#define MA_SND_CHMAP_BRC                        SND_CHMAP_BRC

/* Open mode flags. */
#define MA_SND_PCM_NO_AUTO_RESAMPLE             SND_PCM_NO_AUTO_RESAMPLE
#define MA_SND_PCM_NO_AUTO_CHANNELS             SND_PCM_NO_AUTO_CHANNELS
#define MA_SND_PCM_NO_AUTO_FORMAT               SND_PCM_NO_AUTO_FORMAT
#else
#include <errno.h>  /* For EPIPE, etc. */
typedef unsigned long                           ma_snd_pcm_uframes_t;
typedef long                                    ma_snd_pcm_sframes_t;
typedef int                                     ma_snd_pcm_stream_t;
typedef int                                     ma_snd_pcm_format_t;
typedef int                                     ma_snd_pcm_access_t;
typedef int                                     ma_snd_pcm_state_t;
typedef struct ma_snd_pcm_t                     ma_snd_pcm_t;
typedef struct ma_snd_pcm_hw_params_t           ma_snd_pcm_hw_params_t;
typedef struct ma_snd_pcm_sw_params_t           ma_snd_pcm_sw_params_t;
typedef struct ma_snd_pcm_format_mask_t         ma_snd_pcm_format_mask_t;
typedef struct ma_snd_pcm_info_t                ma_snd_pcm_info_t;
typedef struct

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

typedef int                  (* ma_snd_pcm_hw_params_any_proc)                 (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params);
typedef int                  (* ma_snd_pcm_hw_params_set_format_proc)          (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, ma_snd_pcm_format_t val);
typedef int                  (* ma_snd_pcm_hw_params_set_format_first_proc)    (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, ma_snd_pcm_format_t *format);
typedef void                 (* ma_snd_pcm_hw_params_get_format_mask_proc)     (ma_snd_pcm_hw_params_t *params, ma_snd_pcm_format_mask_t *mask);
typedef int                  (* ma_snd_pcm_hw_params_set_channels_proc)        (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int val);
typedef int                  (* ma_snd_pcm_hw_params_set_channels_near_proc)   (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int *val);
typedef int                  (* ma_snd_pcm_hw_params_set_channels_minmax_proc) (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int *minimum, unsigned int *maximum);
typedef int                  (* ma_snd_pcm_hw_params_set_rate_resample_proc)   (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int val);
typedef int                  (* ma_snd_pcm_hw_params_set_rate_proc)            (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int val, int dir);
typedef int                  (* ma_snd_pcm_hw_params_set_rate_near_proc)       (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
typedef int                  (* ma_snd_pcm_hw_params_set_buffer_size_near_proc)(ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, ma_snd_pcm_uframes_t *val);
typedef int                  (* ma_snd_pcm_hw_params_set_periods_near_proc)    (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
typedef int                  (* ma_snd_pcm_hw_params_set_access_proc)          (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, ma_snd_pcm_access_t _access);
typedef int                  (* ma_snd_pcm_hw_params_get_format_proc)          (const ma_snd_pcm_hw_params_t *params, ma_snd_pcm_format_t *format);
typedef int                  (* ma_snd_pcm_hw_params_get_channels_proc)        (const ma_snd_pcm_hw_params_t *params, unsigned int *val);
typedef int                  (* ma_snd_pcm_hw_params_get_channels_min_proc)    (const ma_snd_pcm_hw_params_t *params, unsigned int *val);
typedef int                  (* ma_snd_pcm_hw_params_get_channels_max_proc)    (const ma_snd_pcm_hw_params_t *params, unsigned int *val);
typedef int                  (* ma_snd_pcm_hw_params_get_rate_proc)            (const ma_snd_pcm_hw_params_t *params, unsigned int *rate, int *dir);
typedef int                  (* ma_snd_pcm_hw_params_get_rate_min_proc)        (const ma_snd_pcm_hw_params_t *params, unsigned int *rate, int *dir);
typedef int                  (* ma_snd_pcm_hw_params_get_rate_max_proc)        (const ma_snd_pcm_hw_params_t *params, unsigned int *rate, int *dir);
typedef int                  (* ma_snd_pcm_hw_params_get_buffer_size_proc)     (const ma_snd_pcm_hw_params_t *params, ma_snd_pcm_uframes_t *val);
typedef int                  (* ma_snd_pcm_hw_params_get_periods_proc)         (const ma_snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
typedef int                  (* ma_snd_pcm_hw_params_get_access_proc)          (const ma_snd_pcm_hw_params_t *params, ma_snd_pcm_access_t *_access);
typedef int                  (* ma_snd_pcm_hw_params_test_format_proc)         (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, ma_snd_pcm_format_t val);
typedef int                  (* ma_snd_pcm_hw_params_test_channels_proc)       (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int val);
typedef int                  (* ma_snd_pcm_hw_params_test_rate_proc)           (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int val, int dir);
typedef int                  (* ma_snd_pcm_hw_params_proc)                     (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params);
typedef size_t               (* ma_snd_pcm_sw_params_sizeof_proc)              (void);
typedef int                  (* ma_snd_pcm_sw_params_current_proc)             (ma_snd_pcm_t *pcm, ma_snd_pcm_sw_params_t *params);
typedef int                  (* ma_snd_pcm_sw_params_get_boundary_proc)        (const ma_snd_pcm_sw_params_t *params, ma_snd_pcm_uframes_t* val);
typedef int                  (* ma_snd_pcm_sw_params_set_avail_min_proc)       (ma_snd_pcm_t *pcm, ma_snd_pcm_sw_params_t *params, ma_snd_pcm_uframes_t val);
typedef int                  (* ma_snd_pcm_sw_params_set_start_threshold_proc) (ma_snd_pcm_t *pcm, ma_snd_pcm_sw_params_t *params, ma_snd_pcm_uframes_t val);
typedef int                  (* ma_snd_pcm_sw_params_set_stop_threshold_proc)  (ma_snd_pcm_t *pcm, ma_snd_pcm_sw_params_t *params, ma_snd_pcm_uframes_t val);
typedef int                  (* ma_snd_pcm_sw_params_proc)                     (ma_snd_pcm_t *pcm, ma_snd_pcm_sw_params_t *params);
typedef size_t               (* ma_snd_pcm_format_mask_sizeof_proc)            (void);
typedef int                  (* ma_snd_pcm_format_mask_test_proc)              (const ma_snd_pcm_format_mask_t *mask, ma_snd_pcm_format_t val);
typedef ma_snd_pcm_chmap_t * (* ma_snd_pcm_get_chmap_proc)                     (ma_snd_pcm_t *pcm);
typedef ma_snd_pcm_state_t   (* ma_snd_pcm_state_proc)                         (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_pcm_prepare_proc)                       (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_pcm_start_proc)                         (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_pcm_drop_proc)                          (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_pcm_drain_proc)                         (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_pcm_reset_proc)                         (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_device_name_hint_proc)                  (int card, const char *iface, void ***hints);
typedef char *               (* ma_snd_device_name_get_hint_proc)              (const void *hint, const char *id);
typedef int                  (* ma_snd_card_get_index_proc)                    (const char *name);
typedef int                  (* ma_snd_device_name_free_hint_proc)             (void **hints);
typedef int                  (* ma_snd_pcm_mmap_begin_proc)                    (ma_snd_pcm_t *pcm, const ma_snd_pcm_channel_area_t **areas, ma_snd_pcm_uframes_t *offset, ma_snd_pcm_uframes_t *frames);
typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_mmap_commit_proc)                   (ma_snd_pcm_t *pcm, ma_snd_pcm_uframes_t offset, ma_snd_pcm_uframes_t frames);
typedef int                  (* ma_snd_pcm_recover_proc)                       (ma_snd_pcm_t *pcm, int err, int silent);
typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_readi_proc)                         (ma_snd_pcm_t *pcm, void *buffer, ma_snd_pcm_uframes_t size);
typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_writei_proc)                        (ma_snd_pcm_t *pcm, const void *buffer, ma_snd_pcm_uframes_t size);
typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_avail_proc)                         (ma_snd_pcm_t *pcm);
typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_avail_update_proc)                  (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_pcm_wait_proc)                          (ma_snd_pcm_t *pcm, int timeout);
typedef int                  (* ma_snd_pcm_nonblock_proc)                      (ma_snd_pcm_t *pcm, int nonblock);
typedef int                  (* ma_snd_pcm_info_proc)                          (ma_snd_pcm_t *pcm, ma_snd_pcm_info_t* info);
typedef size_t               (* ma_snd_pcm_info_sizeof_proc)                   (void);
typedef const char*          (* ma_snd_pcm_info_get_name_proc)                 (const ma_snd_pcm_info_t* info);
typedef int                  (* ma_snd_pcm_poll_descriptors_proc)              (ma_snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space);
typedef int                  (* ma_snd_pcm_poll_descriptors_count_proc)        (ma_snd_pcm_t *pcm);
typedef int                  (* ma_snd_pcm_poll_descriptors_revents_proc)      (ma_snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
typedef int                  (* ma_snd_config_update_free_global_proc)         (void);

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

    ma_snd_pcm_format_t formatALSA;
    ma_format internalFormat;
    ma_uint32 internalChannels;
    ma_uint32 internalSampleRate;
    ma_channel internalChannelMap[MA_MAX_CHANNELS];
    ma_uint32 internalPeriodSizeInFrames;
    ma_uint32 internalPeriods;
    int openMode;
    ma_snd_pcm_hw_params_t* pHWParams;
    ma_snd_pcm_sw_params_t* pSWParams;
    ma_snd_pcm_uframes_t bufferBoundary;
    int pollDescriptorCount;
    struct pollfd* pPollDescriptors;
    int wakeupfd;

    MA_ASSERT(pConfig != NULL);
    MA_ASSERT(deviceType != ma_device_type_duplex); /* This function should only be called for playback _or_ capture, never duplex. */
    MA_ASSERT(pDevice != NULL);

    formatALSA = ma_convert_ma_format_to_alsa_format(pDescriptor->format);

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

            ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set period count. snd_pcm_hw_params_set_periods_near() failed.");
            return ma_result_from_errno(-resultALSA);
        }

        internalPeriods = periods;
    }

    /* Buffer Size */
    {
        ma_snd_pcm_uframes_t actualBufferSizeInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptor, internalSampleRate, pConfig->performanceProfile) * internalPeriods;

        resultALSA = ((ma_snd_pcm_hw_params_set_buffer_size_near_proc)pDevice->pContext->alsa.snd_pcm_hw_params_set_buffer_size_near)(pPCM, pHWParams, &actualBufferSizeInFrames);
        if (resultALSA < 0) {
            ma_free(pHWParams, &pDevice->pContext->allocationCallbacks);
            ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set buffer size for device. snd_pcm_hw_params_set_buffer_size() failed.");
            return ma_result_from_errno(-resultALSA);
        }

        internalPeriodSizeInFrames = actualBufferSizeInFrames / internalPeriods;

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

static ma_result ma_device_wait_read__alsa(ma_device* pDevice)
{
    return ma_device_wait__alsa(pDevice, (ma_snd_pcm_t*)pDevice->alsa.pPCMCapture, (struct pollfd*)pDevice->alsa.pPollDescriptorsCapture, pDevice->alsa.pollDescriptorCountCapture + 1, POLLIN); /* +1 to account for the wakeup descriptor. */
}

static ma_result ma_device_wait_write__alsa(ma_device* pDevice)
{
    return ma_device_wait__alsa(pDevice, (ma_snd_pcm_t*)pDevice->alsa.pPCMPlayback, (struct pollfd*)pDevice->alsa.pPollDescriptorsPlayback, pDevice->alsa.pollDescriptorCountPlayback + 1, POLLOUT); /* +1 to account for the wakeup descriptor. */
}

static ma_result ma_device_read__alsa(ma_device* pDevice, void* pFramesOut, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    ma_snd_pcm_sframes_t resultALSA = 0;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pFramesOut != NULL);

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

    while (ma_device_get_state(pDevice) == ma_device_state_started) {
        ma_result result;

        /* The first thing to do is wait for data to become available for reading. This will return an error code if the device has been stopped. */
        result = ma_device_wait_read__alsa(pDevice);
        if (result != MA_SUCCESS) {
            return result;
        }

        /* Getting here means we should have data available. */
        resultALSA = ((ma_snd_pcm_readi_proc)pDevice->pContext->alsa.snd_pcm_readi)((ma_snd_pcm_t*)pDevice->alsa.pPCMCapture, pFramesOut, frameCount);
        if (resultALSA >= 0) {
            break;  /* Success. */
        } else {
            if (resultALSA == -EAGAIN) {
                /*ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "EGAIN (read)\n");*/
                continue;   /* Try again. */
            } else if (resultALSA == -EPIPE) {
                ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "EPIPE (read)\n");

                /* Overrun. Recover and try again. If this fails we need to return an error. */

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

        }
    }

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

    return MA_SUCCESS;
}

static ma_result ma_device_write__alsa(ma_device* pDevice, const void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    ma_snd_pcm_sframes_t resultALSA = 0;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pFrames != NULL);

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

    while (ma_device_get_state(pDevice) == ma_device_state_started) {
        ma_result result;

        /* The first thing to do is wait for space to become available for writing. This will return an error code if the device has been stopped. */
        result = ma_device_wait_write__alsa(pDevice);
        if (result != MA_SUCCESS) {
            return result;
        }

        resultALSA = ((ma_snd_pcm_writei_proc)pDevice->pContext->alsa.snd_pcm_writei)((ma_snd_pcm_t*)pDevice->alsa.pPCMPlayback, pFrames, frameCount);
        if (resultALSA >= 0) {
            break;  /* Success. */
        } else {
            if (resultALSA == -EAGAIN) {
                /*ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "EGAIN (write)\n");*/
                continue;   /* Try again. */
            } else if (resultALSA == -EPIPE) {
                ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "EPIPE (write)\n");

                /* Underrun. Recover and try again. If this fails we need to return an error. */
                resultALSA = ((ma_snd_pcm_recover_proc)pDevice->pContext->alsa.snd_pcm_recover)((ma_snd_pcm_t*)pDevice->alsa.pPCMPlayback, resultALSA, MA_TRUE);    /* MA_TRUE=silent (don't print anything on error). */
                if (resultALSA < 0) {
                    ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[ALSA] Failed to recover device after underrun.");
                    return ma_result_from_errno((int)-resultALSA);
                }

                /*
                In my testing I have had a situation where writei() does not automatically restart the device even though I've set it
                up as such in the software parameters. What will happen is writei() will block indefinitely even though the number of
                frames is well beyond the auto-start threshold. To work around this I've needed to add an explicit start here. Not sure
                if this is me just being stupid and not recovering the device properly, but this definitely feels like something isn't
                quite right here.
                */
                resultALSA = ((ma_snd_pcm_start_proc)pDevice->pContext->alsa.snd_pcm_start)((ma_snd_pcm_t*)pDevice->alsa.pPCMPlayback);
                if (resultALSA < 0) {
                    ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[ALSA] Failed to start device after underrun.");
                    return ma_result_from_errno((int)-resultALSA);
                }

                continue;   /* Try writing again. */

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

    ((ma_pa_context_disconnect_proc)pContext->pulse.pa_context_disconnect)((ma_pa_context*)pDevice->pulse.pPulseContext);
    ((ma_pa_context_unref_proc)pContext->pulse.pa_context_unref)((ma_pa_context*)pDevice->pulse.pPulseContext);
    ((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)((ma_pa_mainloop*)pDevice->pulse.pMainLoop);

    return MA_SUCCESS;
}

static ma_pa_buffer_attr ma_device__pa_buffer_attr_new(ma_uint32 periodSizeInFrames, ma_uint32 periods, const ma_pa_sample_spec* ss)
{
    ma_pa_buffer_attr attr;
    attr.maxlength = periodSizeInFrames * periods * ma_get_bytes_per_frame(ma_format_from_pulse(ss->format), ss->channels);
    attr.tlength   = attr.maxlength / periods;
    attr.prebuf    = (ma_uint32)-1;
    attr.minreq    = (ma_uint32)-1;
    attr.fragsize  = attr.maxlength / periods;

    return attr;
}

static ma_pa_stream* ma_device__pa_stream_new__pulse(ma_device* pDevice, const char* pStreamName, const ma_pa_sample_spec* ss, const ma_pa_channel_map* cmap)
{

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


    return ((ma_pa_stream_new_proc)pDevice->pContext->pulse.pa_stream_new)((ma_pa_context*)pDevice->pulse.pPulseContext, actualStreamName, ss, cmap);
}


static void ma_device_on_read__pulse(ma_pa_stream* pStream, size_t byteCount, void* pUserData)
{
    ma_device* pDevice = (ma_device*)pUserData;
    ma_uint32 bpf;
    ma_uint32 deviceState;
    ma_uint64 frameCount;
    ma_uint64 framesProcessed;

    MA_ASSERT(pDevice != NULL);

    /*
    Don't do anything if the device isn't initialized yet. Yes, this can happen because PulseAudio
    can fire this callback before the stream has even started. Ridiculous.
    */
    deviceState = ma_device_get_state(pDevice);
    if (deviceState != ma_device_state_starting && deviceState != ma_device_state_started) {
        return;
    }

    bpf = ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
    MA_ASSERT(bpf > 0);

    frameCount = byteCount / bpf;
    framesProcessed = 0;

    while (ma_device_get_state(pDevice) == ma_device_state_started && framesProcessed < frameCount) {
        const void* pMappedPCMFrames;
        size_t bytesMapped;
        ma_uint64 framesMapped;

        int pulseResult = ((ma_pa_stream_peek_proc)pDevice->pContext->pulse.pa_stream_peek)(pStream, &pMappedPCMFrames, &bytesMapped);
        if (pulseResult < 0) {
            break; /* Failed to map. Abort. */
        }

        framesMapped = bytesMapped / bpf;
        if (framesMapped > 0) {
            if (pMappedPCMFrames != NULL) {
                ma_device_handle_backend_data_callback(pDevice, NULL, pMappedPCMFrames, framesMapped);
            } else {
                /* It's a hole. */
                ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[PulseAudio] ma_device_on_read__pulse: Hole.\n");
            }

            pulseResult = ((ma_pa_stream_drop_proc)pDevice->pContext->pulse.pa_stream_drop)(pStream);
            if (pulseResult < 0) {
                break;  /* Failed to drop the buffer. */
            }

            framesProcessed += framesMapped;

        } else {
            /* Nothing was mapped. Just abort. */
            break;
        }
    }
}

static ma_result ma_device_write_to_stream__pulse(ma_device* pDevice, ma_pa_stream* pStream, ma_uint64* pFramesProcessed)
{
    ma_result result = MA_SUCCESS;
    ma_uint64 framesProcessed = 0;
    size_t bytesMapped;
    ma_uint32 bpf;
    ma_uint32 deviceState;

    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(pStream != NULL);

    bpf = ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    MA_ASSERT(bpf > 0);

    deviceState = ma_device_get_state(pDevice);

    bytesMapped = ((ma_pa_stream_writable_size_proc)pDevice->pContext->pulse.pa_stream_writable_size)(pStream);
    if (bytesMapped != (size_t)-1) {
        if (bytesMapped > 0) {
            ma_uint64 framesMapped;
            void* pMappedPCMFrames;
            int pulseResult = ((ma_pa_stream_begin_write_proc)pDevice->pContext->pulse.pa_stream_begin_write)(pStream, &pMappedPCMFrames, &bytesMapped);
            if (pulseResult < 0) {
                result = ma_result_from_pulse(pulseResult);
                goto done;
            }

            framesMapped = bytesMapped / bpf;

            if (deviceState == ma_device_state_started || deviceState == ma_device_state_starting) {  /* Check for starting state just in case this is being used to do the initial fill. */
                ma_device_handle_backend_data_callback(pDevice, pMappedPCMFrames, NULL, framesMapped);
            } else {
                /* Device is not started. Write silence. */
                ma_silence_pcm_frames(pMappedPCMFrames, framesMapped, pDevice->playback.format, pDevice->playback.channels);
            }

            pulseResult = ((ma_pa_stream_write_proc)pDevice->pContext->pulse.pa_stream_write)(pStream, pMappedPCMFrames, bytesMapped, NULL, 0, MA_PA_SEEK_RELATIVE);
            if (pulseResult < 0) {
                result = ma_result_from_pulse(pulseResult);
                goto done;  /* Failed to write data to stream. */
            }

            framesProcessed += framesMapped;
        } else {
            result = MA_SUCCESS;  /* No data available for writing. */
            goto done;
        }
    } else {
        result = MA_ERROR;  /* Failed to retrieve the writable size. Abort. */
        goto done;
    }

done:
    if (pFramesProcessed != NULL) {
        *pFramesProcessed = framesProcessed;
    }

    return result;
}

static void ma_device_on_write__pulse(ma_pa_stream* pStream, size_t byteCount, void* pUserData)
{
    ma_device* pDevice = (ma_device*)pUserData;
    ma_uint32 bpf;
    ma_uint64 frameCount;
    ma_uint64 framesProcessed;
    ma_uint32 deviceState;
    ma_result result;

    MA_ASSERT(pDevice != NULL);

    /*
    Don't do anything if the device isn't initialized yet. Yes, this can happen because PulseAudio
    can fire this callback before the stream has even started. Ridiculous.
    */
    deviceState = ma_device_get_state(pDevice);
    if (deviceState != ma_device_state_starting && deviceState != ma_device_state_started) {
        return;
    }

    bpf = ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    MA_ASSERT(bpf > 0);

    frameCount = byteCount / bpf;
    framesProcessed = 0;

    while (framesProcessed < frameCount) {
        ma_uint64 framesProcessedThisIteration;

        /* Don't keep trying to process frames if the device isn't started. */
        deviceState = ma_device_get_state(pDevice);
        if (deviceState != ma_device_state_starting && deviceState != ma_device_state_started) {
            break;
        }

        result = ma_device_write_to_stream__pulse(pDevice, pStream, &framesProcessedThisIteration);
        if (result != MA_SUCCESS) {
            break;
        }

        framesProcessed += framesProcessedThisIteration;
    }
}

static void ma_device_on_suspended__pulse(ma_pa_stream* pStream, void* pUserData)
{
    ma_device* pDevice = (ma_device*)pUserData;
    int suspended;

    (void)pStream;

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

static void ma_device_on_rerouted__pulse(ma_pa_stream* pStream, void* pUserData)
{
    ma_device* pDevice = (ma_device*)pUserData;

    (void)pStream;
    (void)pUserData;

    ma_device__on_notification_rerouted(pDevice);
}

static ma_uint32 ma_calculate_period_size_in_frames_from_descriptor__pulse(const ma_device_descriptor* pDescriptor, ma_uint32 nativeSampleRate, ma_performance_profile performanceProfile)
{
    /*
    There have been reports from users where buffers of < ~20ms result glitches when running through
    PipeWire. To work around this we're going to have to use a different default buffer size.
    */
    const ma_uint32 defaultPeriodSizeInMilliseconds_LowLatency   = 25;
    const ma_uint32 defaultPeriodSizeInMilliseconds_Conservative = MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_CONSERVATIVE;

    MA_ASSERT(nativeSampleRate != 0);

    if (pDescriptor->periodSizeInFrames == 0) {
        if (pDescriptor->periodSizeInMilliseconds == 0) {
            if (performanceProfile == ma_performance_profile_low_latency) {
                return ma_calculate_buffer_size_in_frames_from_milliseconds(defaultPeriodSizeInMilliseconds_LowLatency, nativeSampleRate);
            } else {
                return ma_calculate_buffer_size_in_frames_from_milliseconds(defaultPeriodSizeInMilliseconds_Conservative, nativeSampleRate);
            }
        } else {
            return ma_calculate_buffer_size_in_frames_from_milliseconds(pDescriptor->periodSizeInMilliseconds, nativeSampleRate);
        }
    } else {
        return pDescriptor->periodSizeInFrames;
    }
}

static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_config* pConfig, ma_device_descriptor* pDescriptorPlayback, ma_device_descriptor* pDescriptorCapture)
{
    /*
    Notes for PulseAudio:

      - We're always using native format/channels/rate regardless of whether or not PulseAudio
        supports the format directly through their own data conversion system. I'm doing this to
        reduce as much variability from the PulseAudio side as possible because it's seems to be
        extremely unreliable at everything it does.

      - When both the period size in frames and milliseconds are 0, we default to miniaudio's
        default buffer sizes rather than leaving it up to PulseAudio because I don't trust
        PulseAudio to give us any kind of reasonable latency by default.

      - Do not ever, *ever* forget to use MA_PA_STREAM_ADJUST_LATENCY. If you don't specify this
        flag, capture mode will just not work properly until you open another PulseAudio app.
    */

    ma_result result = MA_SUCCESS;
    int error = 0;
    const char* devPlayback = NULL;

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

        }
        if (ss.rate == 0) {
            ss.rate = MA_DEFAULT_SAMPLE_RATE;
            ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[PulseAudio] sample_spec.rate = 0. Defaulting to %d.\n", ss.rate);
        }
        if (ss.channels == 0) {
            ss.channels = MA_DEFAULT_CHANNELS;
            ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[PulseAudio] sample_spec.channels = 0. Defaulting to %d.\n", ss.channels);
        }

        /* We now have enough information to calculate our actual period size in frames. */
        pDescriptorCapture->periodSizeInFrames = ma_calculate_period_size_in_frames_from_descriptor__pulse(pDescriptorCapture, ss.rate, pConfig->performanceProfile);

        attr = ma_device__pa_buffer_attr_new(pDescriptorCapture->periodSizeInFrames, pDescriptorCapture->periodCount, &ss);
        ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[PulseAudio] Capture attr: maxlength=%d, tlength=%d, prebuf=%d, minreq=%d, fragsize=%d; periodSizeInFrames=%d\n", attr.maxlength, attr.tlength, attr.prebuf, attr.minreq, attr.fragsi...

        pDevice->pulse.pStreamCapture = ma_device__pa_stream_new__pulse(pDevice, pConfig->pulse.pStreamNameCapture, &ss, &cmap);
        if (pDevice->pulse.pStreamCapture == NULL) {
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to create PulseAudio capture stream.\n");
            result = MA_ERROR;
            goto on_error0;
        }

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

        if (pActualAttr != NULL) {
            attr = *pActualAttr;
        }

        if (attr.fragsize > 0) {
            pDescriptorCapture->periodCount = ma_max(attr.maxlength / attr.fragsize, 1);
        } else {
            pDescriptorCapture->periodCount = 1;
        }

        pDescriptorCapture->periodSizeInFrames = attr.maxlength / ma_get_bytes_per_frame(pDescriptorCapture->format, pDescriptorCapture->channels) / pDescriptorCapture->periodCount;
        ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[PulseAudio] Capture actual attr: maxlength=%d, tlength=%d, prebuf=%d, minreq=%d, fragsize=%d; periodSizeInFrames=%d\n", attr.maxlength, attr.tlength, attr.prebuf, attr.minreq, attr...
    }

    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        result = ma_context_get_sink_info__pulse(pDevice->pContext, devPlayback, &sinkInfo);
        if (result != MA_SUCCESS) {
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to retrieve sink info for playback device.\n");
            goto on_error2;
        }

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

        }
        if (ss.rate == 0) {
            ss.rate = MA_DEFAULT_SAMPLE_RATE;
            ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[PulseAudio] sample_spec.rate = 0. Defaulting to %d.\n", ss.rate);
        }
        if (ss.channels == 0) {
            ss.channels = MA_DEFAULT_CHANNELS;
            ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[PulseAudio] sample_spec.channels = 0. Defaulting to %d.\n", ss.channels);
        }

        /* We now have enough information to calculate the actual buffer size in frames. */
        pDescriptorPlayback->periodSizeInFrames = ma_calculate_period_size_in_frames_from_descriptor__pulse(pDescriptorPlayback, ss.rate, pConfig->performanceProfile);

        attr = ma_device__pa_buffer_attr_new(pDescriptorPlayback->periodSizeInFrames, pDescriptorPlayback->periodCount, &ss);

        ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[PulseAudio] Playback attr: maxlength=%d, tlength=%d, prebuf=%d, minreq=%d, fragsize=%d; periodSizeInFrames=%d\n", attr.maxlength, attr.tlength, attr.prebuf, attr.minreq, attr.frags...

        pDevice->pulse.pStreamPlayback = ma_device__pa_stream_new__pulse(pDevice, pConfig->pulse.pStreamNamePlayback, &ss, &cmap);
        if (pDevice->pulse.pStreamPlayback == NULL) {
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to create PulseAudio playback stream.\n");
            result = MA_ERROR;
            goto on_error2;

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

        if (pActualAttr != NULL) {
            attr = *pActualAttr;
        }

        if (attr.tlength > 0) {
            pDescriptorPlayback->periodCount = ma_max(attr.maxlength / attr.tlength, 1);
        } else {
            pDescriptorPlayback->periodCount = 1;
        }

        pDescriptorPlayback->periodSizeInFrames = attr.maxlength / ma_get_bytes_per_frame(pDescriptorPlayback->format, pDescriptorPlayback->channels) / pDescriptorPlayback->periodCount;
        ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[PulseAudio] Playback actual attr: maxlength=%d, tlength=%d, prebuf=%d, minreq=%d, fragsize=%d; internalPeriodSizeInFrames=%d\n", attr.maxlength, attr.tlength, attr.prebuf, attr.min...
    }


    /*
    We need a ring buffer for handling duplex mode. We can use the main duplex ring buffer in the main
    part of the ma_device struct. We cannot, however, depend on ma_device_init() initializing this for
    us later on because that will only do it if it's a fully asynchronous backend - i.e. the
    onDeviceDataLoop callback is NULL, which is not the case for PulseAudio.
    */

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


JACK Backend

******************************************************************************/
#ifdef MA_HAS_JACK

/* It is assumed jack.h is available when compile-time linking is being used. */
#ifdef MA_NO_RUNTIME_LINKING
#include <jack/jack.h>

typedef jack_nframes_t              ma_jack_nframes_t;
typedef jack_options_t              ma_jack_options_t;
typedef jack_status_t               ma_jack_status_t;
typedef jack_client_t               ma_jack_client_t;
typedef jack_port_t                 ma_jack_port_t;
typedef JackProcessCallback         ma_JackProcessCallback;
typedef JackBufferSizeCallback      ma_JackBufferSizeCallback;
typedef JackShutdownCallback        ma_JackShutdownCallback;
#define MA_JACK_DEFAULT_AUDIO_TYPE  JACK_DEFAULT_AUDIO_TYPE
#define ma_JackNoStartServer        JackNoStartServer
#define ma_JackPortIsInput          JackPortIsInput
#define ma_JackPortIsOutput         JackPortIsOutput
#define ma_JackPortIsPhysical       JackPortIsPhysical
#else
typedef ma_uint32               ma_jack_nframes_t;
typedef int                     ma_jack_options_t;
typedef int                     ma_jack_status_t;
typedef struct ma_jack_client_t ma_jack_client_t;
typedef struct ma_jack_port_t   ma_jack_port_t;
typedef int  (* ma_JackProcessCallback)   (ma_jack_nframes_t nframes, void* arg);
typedef int  (* ma_JackBufferSizeCallback)(ma_jack_nframes_t nframes, void* arg);
typedef void (* ma_JackShutdownCallback)  (void* arg);
#define MA_JACK_DEFAULT_AUDIO_TYPE "32 bit float mono audio"
#define ma_JackNoStartServer       1
#define ma_JackPortIsInput         1
#define ma_JackPortIsOutput        2
#define ma_JackPortIsPhysical      4
#endif

typedef ma_jack_client_t* (* ma_jack_client_open_proc)             (const char* client_name, ma_jack_options_t options, ma_jack_status_t* status, ...);
typedef int               (* ma_jack_client_close_proc)            (ma_jack_client_t* client);
typedef int               (* ma_jack_client_name_size_proc)        (void);
typedef int               (* ma_jack_set_process_callback_proc)    (ma_jack_client_t* client, ma_JackProcessCallback process_callback, void* arg);
typedef int               (* ma_jack_set_buffer_size_callback_proc)(ma_jack_client_t* client, ma_JackBufferSizeCallback bufsize_callback, void* arg);
typedef void              (* ma_jack_on_shutdown_proc)             (ma_jack_client_t* client, ma_JackShutdownCallback function, void* arg);
typedef ma_jack_nframes_t (* ma_jack_get_sample_rate_proc)         (ma_jack_client_t* client);
typedef ma_jack_nframes_t (* ma_jack_get_buffer_size_proc)         (ma_jack_client_t* client);
typedef const char**      (* ma_jack_get_ports_proc)               (ma_jack_client_t* client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags);
typedef int               (* ma_jack_activate_proc)                (ma_jack_client_t* client);
typedef int               (* ma_jack_deactivate_proc)              (ma_jack_client_t* client);
typedef int               (* ma_jack_connect_proc)                 (ma_jack_client_t* client, const char* source_port, const char* destination_port);
typedef ma_jack_port_t*   (* ma_jack_port_register_proc)           (ma_jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size);
typedef const char*       (* ma_jack_port_name_proc)               (const ma_jack_port_t* port);
typedef void*             (* ma_jack_port_get_buffer_proc)         (ma_jack_port_t* port, ma_jack_nframes_t nframes);
typedef void              (* ma_jack_free_proc)                    (void* ptr);

static ma_result ma_context_open_client__jack(ma_context* pContext, ma_jack_client_t** ppClient)
{
    size_t maxClientNameSize;
    char clientName[256];
    ma_jack_status_t status;
    ma_jack_client_t* pClient;

    MA_ASSERT(pContext != NULL);

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


static void ma_device__jack_shutdown_callback(void* pUserData)
{
    /* JACK died. Stop the device. */
    ma_device* pDevice = (ma_device*)pUserData;
    MA_ASSERT(pDevice != NULL);

    ma_device_stop(pDevice);
}

static int ma_device__jack_buffer_size_callback(ma_jack_nframes_t frameCount, void* pUserData)
{
    ma_device* pDevice = (ma_device*)pUserData;
    MA_ASSERT(pDevice != NULL);

    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        size_t newBufferSize = frameCount * (pDevice->capture.internalChannels * ma_get_bytes_per_sample(pDevice->capture.internalFormat));
        float* pNewBuffer = (float*)ma_calloc(newBufferSize, &pDevice->pContext->allocationCallbacks);
        if (pNewBuffer == NULL) {
            return MA_OUT_OF_MEMORY;
        }

        ma_free(pDevice->jack.pIntermediaryBufferCapture, &pDevice->pContext->allocationCallbacks);

        pDevice->jack.pIntermediaryBufferCapture = pNewBuffer;
        pDevice->playback.internalPeriodSizeInFrames = frameCount;
    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        size_t newBufferSize = frameCount * (pDevice->playback.internalChannels * ma_get_bytes_per_sample(pDevice->playback.internalFormat));
        float* pNewBuffer = (float*)ma_calloc(newBufferSize, &pDevice->pContext->allocationCallbacks);
        if (pNewBuffer == NULL) {
            return MA_OUT_OF_MEMORY;
        }

        ma_free(pDevice->jack.pIntermediaryBufferPlayback, &pDevice->pContext->allocationCallbacks);

        pDevice->jack.pIntermediaryBufferPlayback = pNewBuffer;
        pDevice->playback.internalPeriodSizeInFrames = frameCount;
    }

    return 0;
}

static int ma_device__jack_process_callback(ma_jack_nframes_t frameCount, void* pUserData)
{
    ma_device* pDevice;
    ma_context* pContext;
    ma_uint32 iChannel;

    pDevice = (ma_device*)pUserData;
    MA_ASSERT(pDevice != NULL);

    pContext = pDevice->pContext;
    MA_ASSERT(pContext != NULL);

    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        /* Channels need to be interleaved. */
        for (iChannel = 0; iChannel < pDevice->capture.internalChannels; ++iChannel) {
            const float* pSrc = (const float*)((ma_jack_port_get_buffer_proc)pContext->jack.jack_port_get_buffer)((ma_jack_port_t*)pDevice->jack.ppPortsCapture[iChannel], frameCount);
            if (pSrc != NULL) {
                float* pDst = pDevice->jack.pIntermediaryBufferCapture + iChannel;
                ma_jack_nframes_t iFrame;
                for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                    *pDst = *pSrc;

                    pDst += pDevice->capture.internalChannels;
                    pSrc += 1;
                }
            }
        }

        ma_device_handle_backend_data_callback(pDevice, NULL, pDevice->jack.pIntermediaryBufferCapture, frameCount);
    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        ma_device_handle_backend_data_callback(pDevice, pDevice->jack.pIntermediaryBufferPlayback, NULL, frameCount);

        /* Channels need to be deinterleaved. */
        for (iChannel = 0; iChannel < pDevice->playback.internalChannels; ++iChannel) {
            float* pDst = (float*)((ma_jack_port_get_buffer_proc)pContext->jack.jack_port_get_buffer)((ma_jack_port_t*)pDevice->jack.ppPortsPlayback[iChannel], frameCount);
            if (pDst != NULL) {
                const float* pSrc = pDevice->jack.pIntermediaryBufferPlayback + iChannel;
                ma_jack_nframes_t iFrame;
                for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                    *pDst = *pSrc;

                    pDst += 1;
                    pSrc += pDevice->playback.internalChannels;
                }
            }
        }
    }

    return 0;

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

        return MA_FAILED_TO_OPEN_BACKEND_DEVICE;
    }
    if (((ma_jack_set_buffer_size_callback_proc)pDevice->pContext->jack.jack_set_buffer_size_callback)((ma_jack_client_t*)pDevice->jack.pClient, ma_device__jack_buffer_size_callback, pDevice) != 0) {
        ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[JACK] Failed to set buffer size callback.");
        return MA_FAILED_TO_OPEN_BACKEND_DEVICE;
    }

    ((ma_jack_on_shutdown_proc)pDevice->pContext->jack.jack_on_shutdown)((ma_jack_client_t*)pDevice->jack.pClient, ma_device__jack_shutdown_callback, pDevice);


    /* The buffer size in frames can change. */
    periodSizeInFrames = ((ma_jack_get_buffer_size_proc)pDevice->pContext->jack.jack_get_buffer_size)((ma_jack_client_t*)pDevice->jack.pClient);

    if (pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) {
        ma_uint32 iPort;
        const char** ppPorts;

        pDescriptorCapture->format     = ma_format_f32;
        pDescriptorCapture->channels   = 0;
        pDescriptorCapture->sampleRate = ((ma_jack_get_sample_rate_proc)pDevice->pContext->jack.jack_get_sample_rate)((ma_jack_client_t*)pDevice->jack.pClient);
        ma_channel_map_init_standard(ma_standard_channel_map_alsa, pDescriptorCapture->channelMap, ma_countof(pDescriptorCapture->channelMap), pDescriptorCapture->channels);

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

                ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[JACK] Failed to register ports.");
                return MA_FAILED_TO_OPEN_BACKEND_DEVICE;
            }
        }

        ((ma_jack_free_proc)pDevice->pContext->jack.jack_free)((void*)ppPorts);

        pDescriptorCapture->periodSizeInFrames = periodSizeInFrames;
        pDescriptorCapture->periodCount        = 1; /* There's no notion of a period in JACK. Just set to 1. */

        pDevice->jack.pIntermediaryBufferCapture = (float*)ma_calloc(pDescriptorCapture->periodSizeInFrames * ma_get_bytes_per_frame(pDescriptorCapture->format, pDescriptorCapture->channels), &pDevice->pContext->allocationCallbacks);
        if (pDevice->jack.pIntermediaryBufferCapture == NULL) {
            ma_device_uninit__jack(pDevice);
            return MA_OUT_OF_MEMORY;
        }
    }

    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        ma_uint32 iPort;
        const char** ppPorts;

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

                ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[JACK] Failed to register ports.");
                return MA_FAILED_TO_OPEN_BACKEND_DEVICE;
            }
        }

        ((ma_jack_free_proc)pDevice->pContext->jack.jack_free)((void*)ppPorts);

        pDescriptorPlayback->periodSizeInFrames = periodSizeInFrames;
        pDescriptorPlayback->periodCount        = 1;   /* There's no notion of a period in JACK. Just set to 1. */

        pDevice->jack.pIntermediaryBufferPlayback = (float*)ma_calloc(pDescriptorPlayback->periodSizeInFrames * ma_get_bytes_per_frame(pDescriptorPlayback->format, pDescriptorPlayback->channels), &pDevice->pContext->allocationCallbacks);
        if (pDevice->jack.pIntermediaryBufferPlayback == NULL) {
            ma_device_uninit__jack(pDevice);
            return MA_OUT_OF_MEMORY;
        }
    }

    return MA_SUCCESS;
}


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

        ma_free(pSampleRateRanges, &pContext->allocationCallbacks);
        return MA_SUCCESS;
    }

    /* Should never get here, but it would mean we weren't able to find any suitable sample rates. */
    /*ma_free(pSampleRateRanges, &pContext->allocationCallbacks);*/
    /*return MA_ERROR;*/
}
#endif

static ma_result ma_get_AudioObject_closest_buffer_size_in_frames(ma_context* pContext, AudioObjectID deviceObjectID, ma_device_type deviceType, ma_uint32 bufferSizeInFramesIn, ma_uint32* pBufferSizeInFramesOut)
{
    AudioObjectPropertyAddress propAddress;
    AudioValueRange bufferSizeRange;
    UInt32 dataSize;
    OSStatus status;

    MA_ASSERT(pContext != NULL);
    MA_ASSERT(pBufferSizeInFramesOut != NULL);

    *pBufferSizeInFramesOut = 0;    /* Safety. */

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

        *pBufferSizeInFramesOut = (ma_uint32)bufferSizeRange.mMinimum;
    } else if (bufferSizeInFramesIn > bufferSizeRange.mMaximum) {
        *pBufferSizeInFramesOut = (ma_uint32)bufferSizeRange.mMaximum;
    } else {
        *pBufferSizeInFramesOut = bufferSizeInFramesIn;
    }

    return MA_SUCCESS;
}

static ma_result ma_set_AudioObject_buffer_size_in_frames(ma_context* pContext, AudioObjectID deviceObjectID, ma_device_type deviceType, ma_uint32* pPeriodSizeInOut)
{
    ma_result result;
    ma_uint32 chosenBufferSizeInFrames;
    AudioObjectPropertyAddress propAddress;
    UInt32 dataSize;
    OSStatus status;

    MA_ASSERT(pContext != NULL);

    result = ma_get_AudioObject_closest_buffer_size_in_frames(pContext, deviceObjectID, deviceType, *pPeriodSizeInOut, &chosenBufferSizeInFrames);
    if (result != MA_SUCCESS) {
        return result;
    }

    /* Try setting the size of the buffer... If this fails we just use whatever is currently set. */
    propAddress.mSelector = kAudioDevicePropertyBufferFrameSize;
    propAddress.mScope    = (deviceType == ma_device_type_playback) ? kAudioObjectPropertyScopeOutput : kAudioObjectPropertyScopeInput;
    propAddress.mElement  = kAudioObjectPropertyElementMaster;

    ((ma_AudioObjectSetPropertyData_proc)pContext->coreaudio.AudioObjectSetPropertyData)(deviceObjectID, &propAddress, 0, NULL, sizeof(chosenBufferSizeInFrames), &chosenBufferSizeInFrames);

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


    allocationSize = sizeof(AudioBufferList) - sizeof(AudioBuffer);  /* Subtract sizeof(AudioBuffer) because that part is dynamically sized. */
    if (layout == ma_stream_layout_interleaved) {
        /* Interleaved case. This is the simple case because we just have one buffer. */
        allocationSize += sizeof(AudioBuffer) * 1;
    } else {
        /* Non-interleaved case. This is the more complex case because there's more than one buffer. */
        allocationSize += sizeof(AudioBuffer) * channels;
    }

    allocationSize += sizeInFrames * ma_get_bytes_per_frame(format, channels);

    pBufferList = (AudioBufferList*)ma_malloc(allocationSize, pAllocationCallbacks);
    if (pBufferList == NULL) {
        return NULL;
    }

    audioBufferSizeInBytes = (UInt32)(sizeInFrames * ma_get_bytes_per_sample(format));

    if (layout == ma_stream_layout_interleaved) {
        pBufferList->mNumberBuffers = 1;

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

        ma_free(pDevice->coreaudio.pAudioBufferList, &pDevice->pContext->allocationCallbacks);
        pDevice->coreaudio.pAudioBufferList = pNewAudioBufferList;
        pDevice->coreaudio.audioBufferCapInFrames = sizeInFrames;
    }

    /* Getting here means the capacity of the audio is fine. */
    return MA_SUCCESS;
}


static OSStatus ma_on_output__coreaudio(void* pUserData, AudioUnitRenderActionFlags* pActionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufferList)
{
    ma_device* pDevice = (ma_device*)pUserData;
    ma_stream_layout layout;

    MA_ASSERT(pDevice != NULL);

    /*ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "INFO: Output Callback: busNumber=%d, frameCount=%d, mNumberBuffers=%d\n", (int)busNumber, (int)frameCount, (int)pBufferList->mNumberBuffers);*/

    /* We need to check whether or not we are outputting interleaved or non-interleaved samples. The way we do this is slightly different for each type. */
    layout = ma_stream_layout_interleaved;
    if (pBufferList->mBuffers[0].mNumberChannels != pDevice->playback.internalChannels) {
        layout = ma_stream_layout_deinterleaved;
    }

    if (layout == ma_stream_layout_interleaved) {
        /* For now we can assume everything is interleaved. */
        UInt32 iBuffer;
        for (iBuffer = 0; iBuffer < pBufferList->mNumberBuffers; ++iBuffer) {
            if (pBufferList->mBuffers[iBuffer].mNumberChannels == pDevice->playback.internalChannels) {
                ma_uint32 frameCountForThisBuffer = pBufferList->mBuffers[iBuffer].mDataByteSize / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                if (frameCountForThisBuffer > 0) {
                    ma_device_handle_backend_data_callback(pDevice, pBufferList->mBuffers[iBuffer].mData, NULL, frameCountForThisBuffer);
                }

                /*a_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "  frameCount=%d, mNumberChannels=%d, mDataByteSize=%d\n", (int)frameCount, (int)pBufferList->mBuffers[iBuffer].mNumberChannels, (int)pBufferList->mBuffers[iBuffer].mDataBy...
            } else {
                /*
                This case is where the number of channels in the output buffer do not match our internal channels. It could mean that it's
                not interleaved, in which case we can't handle right now since miniaudio does not yet support non-interleaved streams. We just
                output silence here.
                */
                MA_ZERO_MEMORY(pBufferList->mBuffers[iBuffer].mData, pBufferList->mBuffers[iBuffer].mDataByteSize);
                /*ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "  WARNING: Outputting silence. frameCount=%d, mNumberChannels=%d, mDataByteSize=%d\n", (int)frameCount, (int)pBufferList->mBuffers[iBuffer].mNumberChannels, (int)pBufferL...
            }
        }
    } else {
        /* This is the deinterleaved case. We need to update each buffer in groups of internalChannels. This assumes each buffer is the same size. */
        MA_ASSERT(pDevice->playback.internalChannels <= MA_MAX_CHANNELS);   /* This should heve been validated at initialization time. */

        /*
        For safety we'll check that the internal channels is a multiple of the buffer count. If it's not it means something
        very strange has happened and we're not going to support it.
        */
        if ((pBufferList->mNumberBuffers % pDevice->playback.internalChannels) == 0) {
            ma_uint8 tempBuffer[4096];
            UInt32 iBuffer;

            for (iBuffer = 0; iBuffer < pBufferList->mNumberBuffers; iBuffer += pDevice->playback.internalChannels) {
                ma_uint32 frameCountPerBuffer = pBufferList->mBuffers[iBuffer].mDataByteSize / ma_get_bytes_per_sample(pDevice->playback.internalFormat);
                ma_uint32 framesRemaining = frameCountPerBuffer;

                while (framesRemaining > 0) {
                    void* ppDeinterleavedBuffers[MA_MAX_CHANNELS];
                    ma_uint32 iChannel;
                    ma_uint32 framesToRead = sizeof(tempBuffer) / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
                    if (framesToRead > framesRemaining) {
                        framesToRead = framesRemaining;
                    }

                    ma_device_handle_backend_data_callback(pDevice, tempBuffer, NULL, framesToRead);

                    for (iChannel = 0; iChannel < pDevice->playback.internalChannels; ++iChannel) {
                        ppDeinterleavedBuffers[iChannel] = (void*)ma_offset_ptr(pBufferList->mBuffers[iBuffer+iChannel].mData, (frameCountPerBuffer - framesRemaining) * ma_get_bytes_per_sample(pDevice->playback.internalFormat));
                    }

                    ma_deinterleave_pcm_frames(pDevice->playback.internalFormat, pDevice->playback.internalChannels, framesToRead, tempBuffer, ppDeinterleavedBuffers);

                    framesRemaining -= framesToRead;
                }
            }
        }
    }

    (void)pActionFlags;
    (void)pTimeStamp;
    (void)busNumber;
    (void)frameCount;

    return noErr;
}

static OSStatus ma_on_input__coreaudio(void* pUserData, AudioUnitRenderActionFlags* pActionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pUnusedBufferList)
{
    ma_device* pDevice = (ma_device*)pUserData;
    AudioBufferList* pRenderedBufferList;
    ma_result result;
    ma_stream_layout layout;
    ma_uint32 iBuffer;
    OSStatus status;

    MA_ASSERT(pDevice != NULL);

    pRenderedBufferList = (AudioBufferList*)pDevice->coreaudio.pAudioBufferList;
    MA_ASSERT(pRenderedBufferList);

    /* We need to check whether or not we are outputting interleaved or non-interleaved samples. The way we do this is slightly different for each type. */
    layout = ma_stream_layout_interleaved;
    if (pRenderedBufferList->mBuffers[0].mNumberChannels != pDevice->capture.internalChannels) {
        layout = ma_stream_layout_deinterleaved;
    }

    /*ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "INFO: Input Callback: busNumber=%d, frameCount=%d, mNumberBuffers=%d\n", (int)busNumber, (int)frameCount, (int)pRenderedBufferList->mNumberBuffers);*/

    /*
    There has been a situation reported where frame count passed into this function is greater than the capacity of
    our capture buffer. There doesn't seem to be a reliable way to determine what the maximum frame count will be,
    so we need to instead resort to dynamically reallocating our buffer to ensure it's large enough to capture the
    number of frames requested by this callback.
    */
    result = ma_device_realloc_AudioBufferList__coreaudio(pDevice, frameCount, pDevice->capture.internalFormat, pDevice->capture.internalChannels, layout);
    if (result != MA_SUCCESS) {
        ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "Failed to allocate AudioBufferList for capture.\n");
        return noErr;
    }
    
    pRenderedBufferList = (AudioBufferList*)pDevice->coreaudio.pAudioBufferList;
    MA_ASSERT(pRenderedBufferList);

    /*
    When you call AudioUnitRender(), Core Audio tries to be helpful by setting the mDataByteSize to the number of bytes
    that were actually rendered. The problem with this is that the next call can fail with -50 due to the size no longer
    being set to the capacity of the buffer, but instead the size in bytes of the previous render. This will cause a
    problem when a future call to this callback specifies a larger number of frames.

    To work around this we need to explicitly set the size of each buffer to their respective size in bytes.
    */
    for (iBuffer = 0; iBuffer < pRenderedBufferList->mNumberBuffers; ++iBuffer) {
        pRenderedBufferList->mBuffers[iBuffer].mDataByteSize = pDevice->coreaudio.audioBufferCapInFrames * ma_get_bytes_per_sample(pDevice->capture.internalFormat) * pRenderedBufferList->mBuffers[iBuffer].mNumberChannels;
    }

    status = ((ma_AudioUnitRender_proc)pDevice->pContext->coreaudio.AudioUnitRender)((AudioUnit)pDevice->coreaudio.audioUnitCapture, pActionFlags, pTimeStamp, busNumber, frameCount, pRenderedBufferList);
    if (status != noErr) {
        ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "  ERROR: AudioUnitRender() failed with %d.\n", (int)status);
        return status;
    }

    if (layout == ma_stream_layout_interleaved) {
        for (iBuffer = 0; iBuffer < pRenderedBufferList->mNumberBuffers; ++iBuffer) {
            if (pRenderedBufferList->mBuffers[iBuffer].mNumberChannels == pDevice->capture.internalChannels) {
                ma_device_handle_backend_data_callback(pDevice, NULL, pRenderedBufferList->mBuffers[iBuffer].mData, frameCount);
                /*ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "  mDataByteSize=%d.\n", (int)pRenderedBufferList->mBuffers[iBuffer].mDataByteSize);*/
            } else {
                /*
                This case is where the number of channels in the output buffer do not match our internal channels. It could mean that it's
                not interleaved, in which case we can't handle right now since miniaudio does not yet support non-interleaved streams.
                */
                ma_uint8 silentBuffer[4096];
                ma_uint32 framesRemaining;

                MA_ZERO_MEMORY(silentBuffer, sizeof(silentBuffer));

                framesRemaining = frameCount;
                while (framesRemaining > 0) {
                    ma_uint32 framesToSend = sizeof(silentBuffer) / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
                    if (framesToSend > framesRemaining) {
                        framesToSend = framesRemaining;
                    }

                    ma_device_handle_backend_data_callback(pDevice, NULL, silentBuffer, framesToSend);

                    framesRemaining -= framesToSend;
                }

                /*ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "  WARNING: Outputting silence. frameCount=%d, mNumberChannels=%d, mDataByteSize=%d\n", (int)frameCount, (int)pRenderedBufferList->mBuffers[iBuffer].mNumberChannels, (int)...
            }
        }
    } else {
        /* This is the deinterleaved case. We need to interleave the audio data before sending it to the client. This assumes each buffer is the same size. */
        MA_ASSERT(pDevice->capture.internalChannels <= MA_MAX_CHANNELS);    /* This should have been validated at initialization time. */

        /*
        For safety we'll check that the internal channels is a multiple of the buffer count. If it's not it means something
        very strange has happened and we're not going to support it.
        */
        if ((pRenderedBufferList->mNumberBuffers % pDevice->capture.internalChannels) == 0) {
            ma_uint8 tempBuffer[4096];
            for (iBuffer = 0; iBuffer < pRenderedBufferList->mNumberBuffers; iBuffer += pDevice->capture.internalChannels) {
                ma_uint32 framesRemaining = frameCount;
                while (framesRemaining > 0) {
                    void* ppDeinterleavedBuffers[MA_MAX_CHANNELS];
                    ma_uint32 iChannel;
                    ma_uint32 framesToSend = sizeof(tempBuffer) / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
                    if (framesToSend > framesRemaining) {
                        framesToSend = framesRemaining;
                    }

                    for (iChannel = 0; iChannel < pDevice->capture.internalChannels; ++iChannel) {
                        ppDeinterleavedBuffers[iChannel] = (void*)ma_offset_ptr(pRenderedBufferList->mBuffers[iBuffer+iChannel].mData, (frameCount - framesRemaining) * ma_get_bytes_per_sample(pDevice->capture.internalFormat));
                    }

                    ma_interleave_pcm_frames(pDevice->capture.internalFormat, pDevice->capture.internalChannels, framesToSend, (const void**)ppDeinterleavedBuffers, tempBuffer);
                    ma_device_handle_backend_data_callback(pDevice, NULL, tempBuffer, framesToSend);

                    framesRemaining -= framesToSend;
                }
            }
        }
    }

    (void)pActionFlags;
    (void)pTimeStamp;
    (void)busNumber;
    (void)frameCount;
    (void)pUnusedBufferList;

    return noErr;
}

static void on_start_stop__coreaudio(void* pUserData, AudioUnit audioUnit, AudioUnitPropertyID propertyID, AudioUnitScope scope, AudioUnitElement element)
{
    ma_device* pDevice = (ma_device*)pUserData;
    MA_ASSERT(pDevice != NULL);

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

#else
    /* TODO: Figure out how to get the channel map using AVAudioSession. */
    ma_channel_map_init_standard(ma_standard_channel_map_default, pData->channelMapOut, ma_countof(pData->channelMapOut), pData->channelsOut);
#endif


    /* Buffer size. Not allowing this to be configurable on iOS. */
    if (pData->periodSizeInFramesIn == 0) {
        if (pData->periodSizeInMillisecondsIn == 0) {
            if (pData->performanceProfile == ma_performance_profile_low_latency) {
                actualPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_LOW_LATENCY, pData->sampleRateOut);
            } else {
                actualPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_CONSERVATIVE, pData->sampleRateOut);
            }
        } else {
            actualPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(pData->periodSizeInMillisecondsIn, pData->sampleRateOut);
        }
    } else {
        actualPeriodSizeInFrames = pData->periodSizeInFramesIn;
    }

#if defined(MA_APPLE_DESKTOP)
    result = ma_set_AudioObject_buffer_size_in_frames(pContext, deviceObjectID, deviceType, &actualPeriodSizeInFrames);
    if (result != MA_SUCCESS) {
        return result;
    }
#else
    /*
    On iOS, the size of the IO buffer needs to be specified in seconds and is a floating point
    number. I don't trust any potential truncation errors due to converting from float to integer
    so I'm going to explicitly set the actual period size to the next power of 2.
    */
    @autoreleasepool {

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

        if (!pConfig->coreaudio.noAudioSessionActivate) {
            if (![pAudioSession setActive:true error:nil]) {
                ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "Failed to activate audio session.");
                return MA_FAILED_TO_INIT_BACKEND;
            }
        }
    }
#endif

#if !defined(MA_NO_RUNTIME_LINKING) && !defined(MA_APPLE_MOBILE)
    pContext->coreaudio.hCoreFoundation = ma_dlopen(pContext, "CoreFoundation.framework/CoreFoundation");
    if (pContext->coreaudio.hCoreFoundation == NULL) {
        return MA_API_NOT_FOUND;
    }

    pContext->coreaudio.CFStringGetCString = ma_dlsym(pContext, pContext->coreaudio.hCoreFoundation, "CFStringGetCString");
    pContext->coreaudio.CFRelease          = ma_dlsym(pContext, pContext->coreaudio.hCoreFoundation, "CFRelease");


    pContext->coreaudio.hCoreAudio = ma_dlopen(pContext, "CoreAudio.framework/CoreAudio");
    if (pContext->coreaudio.hCoreAudio == NULL) {
        ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
        return MA_API_NOT_FOUND;
    }

    pContext->coreaudio.AudioObjectGetPropertyData        = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyData");
    pContext->coreaudio.AudioObjectGetPropertyDataSize    = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyDataSize");
    pContext->coreaudio.AudioObjectSetPropertyData        = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectSetPropertyData");
    pContext->coreaudio.AudioObjectAddPropertyListener    = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectAddPropertyListener");
    pContext->coreaudio.AudioObjectRemovePropertyListener = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectRemovePropertyListener");

    /*
    It looks like Apple has moved some APIs from AudioUnit into AudioToolbox on more recent versions of macOS. They are still
    defined in AudioUnit, but just in case they decide to remove them from there entirely I'm going to implement a fallback.
    The way it'll work is that it'll first try AudioUnit, and if the required symbols are not present there we'll fall back to
    AudioToolbox.
    */
    pContext->coreaudio.hAudioUnit = ma_dlopen(pContext, "AudioUnit.framework/AudioUnit");
    if (pContext->coreaudio.hAudioUnit == NULL) {
        ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
        ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
        return MA_API_NOT_FOUND;
    }

    if (ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentFindNext") == NULL) {
        /* Couldn't find the required symbols in AudioUnit, so fall back to AudioToolbox. */
        ma_dlclose(pContext, pContext->coreaudio.hAudioUnit);
        pContext->coreaudio.hAudioUnit = ma_dlopen(pContext, "AudioToolbox.framework/AudioToolbox");
        if (pContext->coreaudio.hAudioUnit == NULL) {
            ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
            ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
            return MA_API_NOT_FOUND;
        }
    }

    pContext->coreaudio.AudioComponentFindNext            = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentFindNext");
    pContext->coreaudio.AudioComponentInstanceDispose     = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentInstanceDispose");
    pContext->coreaudio.AudioComponentInstanceNew         = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentInstanceNew");

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

    }

    if (deviceType == ma_device_type_capture) {
        par.rchan = channels;
    } else {
        par.pchan = channels;
    }

    par.rate = sampleRate;

    internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptor, par.rate, pConfig->performanceProfile);

    par.round    = internalPeriodSizeInFrames;
    par.appbufsz = par.round * pDescriptor->periodCount;

    if (((ma_sio_setpar_proc)pDevice->pContext->sndio.sio_setpar)((struct ma_sio_hdl*)handle, &par) == 0) {
        ((ma_sio_close_proc)pDevice->pContext->sndio.sio_close)((struct ma_sio_hdl*)handle);
        ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[sndio] Failed to set buffer size.");
        return MA_ERROR;
    }

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

        ((ma_sio_stop_proc)pDevice->pContext->sndio.sio_stop)((struct ma_sio_hdl*)pDevice->sndio.handleCapture);
    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        ((ma_sio_stop_proc)pDevice->pContext->sndio.sio_stop)((struct ma_sio_hdl*)pDevice->sndio.handlePlayback);
    }

    return MA_SUCCESS;
}

static ma_result ma_device_write__sndio(ma_device* pDevice, const void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    int result;

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

    result = ((ma_sio_write_proc)pDevice->pContext->sndio.sio_write)((struct ma_sio_hdl*)pDevice->sndio.handlePlayback, pPCMFrames, frameCount * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
    if (result == 0) {
        ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[sndio] Failed to send data from the client to the device.");
        return MA_IO_ERROR;
    }

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

    return MA_SUCCESS;
}

static ma_result ma_device_read__sndio(ma_device* pDevice, void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    int result;

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

    result = ((ma_sio_read_proc)pDevice->pContext->sndio.sio_read)((struct ma_sio_hdl*)pDevice->sndio.handleCapture, pPCMFrames, frameCount * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));
    if (result == 0) {
        ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[sndio] Failed to read data from the device to be sent to the device.");
        return MA_IO_ERROR;
    }

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

    return MA_SUCCESS;
}

static ma_result ma_context_uninit__sndio(ma_context* pContext)
{
    MA_ASSERT(pContext != NULL);
    MA_ASSERT(pContext->backend == ma_backend_sndio);

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

        if (internalFormat == ma_format_unknown) {
            close(fd);
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[audio4] The device's internal device format is not supported by miniaudio. The device is unusable.");
            return MA_FORMAT_NOT_SUPPORTED;
        }

        /* Buffer. */
        {
            ma_uint32 internalPeriodSizeInBytes;

            internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptor, internalSampleRate, pConfig->performanceProfile);

            internalPeriodSizeInBytes = internalPeriodSizeInFrames * ma_get_bytes_per_frame(internalFormat, internalChannels);
            if (internalPeriodSizeInBytes < 16) {
                internalPeriodSizeInBytes = 16;
            }

            internalPeriods = pDescriptor->periodCount;
            if (internalPeriods < 2) {
                internalPeriods = 2;
            }

            /* What miniaudio calls a period, audio4 calls a block. */

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

            fdInfo.hiwat     = internalPeriods;
            fdInfo.lowat     = internalPeriods-1;
            fdInfo.blocksize = internalPeriodSizeInBytes;
            if (ioctl(fd, AUDIO_SETINFO, &fdInfo) < 0) {
                close(fd);
                ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[audio4] Failed to set internal buffer size. AUDIO_SETINFO failed.");
                return ma_result_from_errno(errno);
            }

            internalPeriods            = fdInfo.hiwat;
            internalPeriodSizeInFrames = fdInfo.blocksize / ma_get_bytes_per_frame(internalFormat, internalChannels);
        }
    }
    #else
    {
        struct audio_swpar fdPar;

        /* We need to retrieve the format of the device so we can know the channel count and sample rate. Then we can calculate the buffer size. */
        if (ioctl(fd, AUDIO_GETPAR, &fdPar) < 0) {
            close(fd);
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[audio4] Failed to retrieve initial device parameters.");

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

        if (internalFormat == ma_format_unknown) {
            close(fd);
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[audio4] The device's internal device format is not supported by miniaudio. The device is unusable.");
            return MA_FORMAT_NOT_SUPPORTED;
        }

        /* Buffer. */
        {
            ma_uint32 internalPeriodSizeInBytes;

            internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptor, internalSampleRate, pConfig->performanceProfile);

            /* What miniaudio calls a period, audio4 calls a block. */
            internalPeriodSizeInBytes = internalPeriodSizeInFrames * ma_get_bytes_per_frame(internalFormat, internalChannels);
            if (internalPeriodSizeInBytes < 16) {
                internalPeriodSizeInBytes = 16;
            }

            fdPar.nblks = pDescriptor->periodCount;
            fdPar.round = internalPeriodSizeInBytes;

            if (ioctl(fd, AUDIO_SETPAR, &fdPar) < 0) {
                close(fd);
                ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[audio4] Failed to set device parameters.");

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

                close(fd);
                ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[audio4] Failed to retrieve actual device parameters.");
                return ma_result_from_errno(errno);
            }
        }

        internalFormat             = ma_format_from_swpar__audio4(&fdPar);
        internalChannels           = (deviceType == ma_device_type_capture) ? fdPar.rchan : fdPar.pchan;
        internalSampleRate         = fdPar.rate;
        internalPeriods            = fdPar.nblks;
        internalPeriodSizeInFrames = fdPar.round / ma_get_bytes_per_frame(internalFormat, internalChannels);
    }
    #endif

    if (internalFormat == ma_format_unknown) {
        close(fd);
        ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[audio4] The device's internal device format is not supported by miniaudio. The device is unusable.");
        return MA_FORMAT_NOT_SUPPORTED;
    }

    if (deviceType == ma_device_type_capture) {

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

        /* Here is where the device is stopped immediately. */
        result = ma_device_stop_fd__audio4(pDevice, pDevice->audio4.fdPlayback);
        if (result != MA_SUCCESS) {
            return result;
        }
    }

    return MA_SUCCESS;
}

static ma_result ma_device_write__audio4(ma_device* pDevice, const void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    int result;

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

    result = write(pDevice->audio4.fdPlayback, pPCMFrames, frameCount * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
    if (result < 0) {
        ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[audio4] Failed to write data to the device.");
        return ma_result_from_errno(errno);
    }

    if (pFramesWritten != NULL) {
        *pFramesWritten = (ma_uint32)result / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    }

    return MA_SUCCESS;
}

static ma_result ma_device_read__audio4(ma_device* pDevice, void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    int result;

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

    result = read(pDevice->audio4.fdCapture, pPCMFrames, frameCount * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));
    if (result < 0) {
        ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[audio4] Failed to read data from the device.");
        return ma_result_from_errno(errno);
    }

    if (pFramesRead != NULL) {
        *pFramesRead = (ma_uint32)result / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
    }

    return MA_SUCCESS;
}

static ma_result ma_context_uninit__audio4(ma_context* pContext)
{
    MA_ASSERT(pContext != NULL);
    MA_ASSERT(pContext->backend == ma_backend_audio4);

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

    it should be done before or after format/channels/rate.

    OSS wants the fragment size in bytes and a power of 2. When setting, we specify the power, not the actual
    value.
    */
    {
        ma_uint32 periodSizeInFrames;
        ma_uint32 periodSizeInBytes;
        ma_uint32 ossFragmentSizePower;

        periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptor, (ma_uint32)ossSampleRate, pConfig->performanceProfile);

        periodSizeInBytes = ma_round_to_power_of_2(periodSizeInFrames * ma_get_bytes_per_frame(ma_format_from_oss(ossFormat), ossChannels));
        if (periodSizeInBytes < 16) {
            periodSizeInBytes = 16;
        }

        ossFragmentSizePower = 4;
        periodSizeInBytes >>= 4;
        while (periodSizeInBytes >>= 1) {
            ossFragmentSizePower += 1;
        }

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

        pDevice->oss.fdCapture  = fd;
    } else {
        pDevice->oss.fdPlayback = fd;
    }

    pDescriptor->format             = ma_format_from_oss(ossFormat);
    pDescriptor->channels           = ossChannels;
    pDescriptor->sampleRate         = ossSampleRate;
    ma_channel_map_init_standard(ma_standard_channel_map_sound4, pDescriptor->channelMap, ma_countof(pDescriptor->channelMap), pDescriptor->channels);
    pDescriptor->periodCount        = (ma_uint32)(ossFragment >> 16);
    pDescriptor->periodSizeInFrames = (ma_uint32)(1 << (ossFragment & 0xFFFF)) / ma_get_bytes_per_frame(pDescriptor->format, pDescriptor->channels);

    if (pDescriptor->format == ma_format_unknown) {
        ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OSS] The device's internal format is not supported by miniaudio.");
        return MA_FORMAT_NOT_SUPPORTED;
    }

    return MA_SUCCESS;
}

static ma_result ma_device_init__oss(ma_device* pDevice, const ma_device_config* pConfig, ma_device_descriptor* pDescriptorPlayback, ma_device_descriptor* pDescriptorCapture)

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

static ma_result ma_device_stop__oss(ma_device* pDevice)
{
    MA_ASSERT(pDevice != NULL);

    /* See note above on why this is empty. */
    (void)pDevice;

    return MA_SUCCESS;
}

static ma_result ma_device_write__oss(ma_device* pDevice, const void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{
    int resultOSS;
    ma_uint32 deviceState;

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

    /* Don't do any processing if the device is stopped. */
    deviceState = ma_device_get_state(pDevice);
    if (deviceState != ma_device_state_started && deviceState != ma_device_state_starting) {
        return MA_SUCCESS;
    }

    resultOSS = write(pDevice->oss.fdPlayback, pPCMFrames, frameCount * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
    if (resultOSS < 0) {
        ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OSS] Failed to send data from the client to the device.");
        return ma_result_from_errno(errno);
    }

    if (pFramesWritten != NULL) {
        *pFramesWritten = (ma_uint32)resultOSS / ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    }

    return MA_SUCCESS;
}

static ma_result ma_device_read__oss(ma_device* pDevice, void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
    int resultOSS;
    ma_uint32 deviceState;

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

    /* Don't do any processing if the device is stopped. */
    deviceState = ma_device_get_state(pDevice);
    if (deviceState != ma_device_state_started && deviceState != ma_device_state_starting) {
        return MA_SUCCESS;
    }

    resultOSS = read(pDevice->oss.fdCapture, pPCMFrames, frameCount * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));
    if (resultOSS < 0) {
        ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OSS] Failed to read data from the device to be sent to the client.");
        return ma_result_from_errno(errno);
    }

    if (pFramesRead != NULL) {
        *pFramesRead = (ma_uint32)resultOSS / ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
    }

    return MA_SUCCESS;
}

static ma_result ma_context_uninit__oss(ma_context* pContext)
{
    MA_ASSERT(pContext != NULL);
    MA_ASSERT(pContext->backend == ma_backend_oss);

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

        }

        result = ma_device_job_thread_post(&pDevice->pContext->aaudio.jobThread, &job);
        if (result != MA_SUCCESS) {
            ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[AAudio] Device Disconnected. Failed to post job for rerouting.\n");
            return;
        }
    }
}

static ma_aaudio_data_callback_result_t ma_stream_data_callback_capture__aaudio(ma_AAudioStream* pStream, void* pUserData, void* pAudioData, int32_t frameCount)
{
    ma_device* pDevice = (ma_device*)pUserData;
    MA_ASSERT(pDevice != NULL);

    ma_device_handle_backend_data_callback(pDevice, NULL, pAudioData, frameCount);

    (void)pStream;
    return MA_AAUDIO_CALLBACK_RESULT_CONTINUE;
}

static ma_aaudio_data_callback_result_t ma_stream_data_callback_playback__aaudio(ma_AAudioStream* pStream, void* pUserData, void* pAudioData, int32_t frameCount)
{
    ma_device* pDevice = (ma_device*)pUserData;
    MA_ASSERT(pDevice != NULL);

    ma_device_handle_backend_data_callback(pDevice, pAudioData, NULL, frameCount);

    (void)pStream;
    return MA_AAUDIO_CALLBACK_RESULT_CONTINUE;
}

static ma_result ma_create_and_configure_AAudioStreamBuilder__aaudio(ma_context* pContext, const ma_device_id* pDeviceID, ma_device_type deviceType, ma_share_mode shareMode, const ma_device_descriptor* pDescriptor, const ma_device_config* pConfig, ma...
{
    ma_AAudioStreamBuilder* pBuilder;
    ma_aaudio_result_t resultAA;
    ma_uint32 bufferCapacityInFrames;

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

            }
        }

        /*
        AAudio is annoying when it comes to it's buffer calculation stuff because it doesn't let you
        retrieve the actual sample rate until after you've opened the stream. But you need to configure
        the buffer capacity before you open the stream... :/

        To solve, we're just going to assume MA_DEFAULT_SAMPLE_RATE (48000) and move on.
        */
        bufferCapacityInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptor, pDescriptor->sampleRate, pConfig->performanceProfile) * pDescriptor->periodCount;

        ((MA_PFN_AAudioStreamBuilder_setBufferCapacityInFrames)pContext->aaudio.AAudioStreamBuilder_setBufferCapacityInFrames)(pBuilder, bufferCapacityInFrames);
        ((MA_PFN_AAudioStreamBuilder_setFramesPerDataCallback)pContext->aaudio.AAudioStreamBuilder_setFramesPerDataCallback)(pBuilder, bufferCapacityInFrames / pDescriptor->periodCount);

        if (deviceType == ma_device_type_capture) {
            if (pConfig->aaudio.inputPreset != ma_aaudio_input_preset_default && pContext->aaudio.AAudioStreamBuilder_setInputPreset != NULL) {
                ((MA_PFN_AAudioStreamBuilder_setInputPreset)pContext->aaudio.AAudioStreamBuilder_setInputPreset)(pBuilder, ma_to_input_preset__aaudio(pConfig->aaudio.inputPreset));
            }

            ((MA_PFN_AAudioStreamBuilder_setDataCallback)pContext->aaudio.AAudioStreamBuilder_setDataCallback)(pBuilder, ma_stream_data_callback_capture__aaudio, (void*)pDevice);

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

        pDevice->aaudio.pStreamPlayback = NULL;
    }

    return MA_SUCCESS;
}

static ma_result ma_device_init_by_type__aaudio(ma_device* pDevice, const ma_device_config* pConfig, ma_device_type deviceType, ma_device_descriptor* pDescriptor, ma_AAudioStream** ppStream)
{
    ma_result result;
    int32_t bufferCapacityInFrames;
    int32_t framesPerDataCallback;
    ma_AAudioStream* pStream;

    MA_ASSERT(pDevice     != NULL);
    MA_ASSERT(pConfig     != NULL);
    MA_ASSERT(pDescriptor != NULL);

    *ppStream = NULL;   /* Safety. */

    /* First step is to open the stream. From there we'll be able to extract the internal configuration. */
    result = ma_open_stream__aaudio(pDevice, pConfig, deviceType, pDescriptor, &pStream);

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

    pDescriptor->sampleRate = ((MA_PFN_AAudioStream_getSampleRate)pDevice->pContext->aaudio.AAudioStream_getSampleRate)(pStream);

    /* For the channel map we need to be sure we don't overflow any buffers. */
    if (pDescriptor->channels <= MA_MAX_CHANNELS) {
        ma_channel_map_init_standard(ma_standard_channel_map_default, pDescriptor->channelMap, ma_countof(pDescriptor->channelMap), pDescriptor->channels); /* <-- Cannot find info on channel order, so assuming a default. */
    } else {
        ma_channel_map_init_blank(pDescriptor->channelMap, MA_MAX_CHANNELS); /* Too many channels. Use a blank channel map. */
    }

    bufferCapacityInFrames = ((MA_PFN_AAudioStream_getBufferCapacityInFrames)pDevice->pContext->aaudio.AAudioStream_getBufferCapacityInFrames)(pStream);
    framesPerDataCallback = ((MA_PFN_AAudioStream_getFramesPerDataCallback)pDevice->pContext->aaudio.AAudioStream_getFramesPerDataCallback)(pStream);

    if (framesPerDataCallback > 0) {
        pDescriptor->periodSizeInFrames = framesPerDataCallback;
        pDescriptor->periodCount        = bufferCapacityInFrames / framesPerDataCallback;
    } else {
        pDescriptor->periodSizeInFrames = bufferCapacityInFrames;
        pDescriptor->periodCount        = 1;
    }

    *ppStream = pStream;

    return MA_SUCCESS;
}

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

    /* Don't do anything if the device is not started. */
    if (ma_device_get_state(pDevice) != ma_device_state_started) {
        return;
    }

    /* Don't do anything if the device is being drained. */
    if (pDevice->opensl.isDrainingCapture) {
        return;
    }

    periodSizeInBytes = pDevice->capture.internalPeriodSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
    pBuffer = pDevice->opensl.pBufferCapture + (pDevice->opensl.currentBufferIndexCapture * periodSizeInBytes);

    ma_device_handle_backend_data_callback(pDevice, NULL, pBuffer, pDevice->capture.internalPeriodSizeInFrames);

    resultSL = MA_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueueCapture)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueueCapture, pBuffer, periodSizeInBytes);
    if (resultSL != SL_RESULT_SUCCESS) {
        return;
    }

    pDevice->opensl.currentBufferIndexCapture = (pDevice->opensl.currentBufferIndexCapture + 1) % pDevice->capture.internalPeriods;

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

    /* Don't do anything if the device is not started. */
    if (ma_device_get_state(pDevice) != ma_device_state_started) {
        return;
    }

    /* Don't do anything if the device is being drained. */
    if (pDevice->opensl.isDrainingPlayback) {
        return;
    }

    periodSizeInBytes = pDevice->playback.internalPeriodSizeInFrames * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
    pBuffer = pDevice->opensl.pBufferPlayback + (pDevice->opensl.currentBufferIndexPlayback * periodSizeInBytes);

    ma_device_handle_backend_data_callback(pDevice, pBuffer, NULL, pDevice->playback.internalPeriodSizeInFrames);

    resultSL = MA_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueuePlayback)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueuePlayback, pBuffer, periodSizeInBytes);
    if (resultSL != SL_RESULT_SUCCESS) {
        return;
    }

    pDevice->opensl.currentBufferIndexPlayback = (pDevice->opensl.currentBufferIndexPlayback + 1) % pDevice->playback.internalPeriods;

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

        if (resultSL != SL_RESULT_SUCCESS) {
            ma_device_uninit__opensl(pDevice);
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to register buffer queue callback.");
            return ma_result_from_OpenSL(resultSL);
        }

        /* The internal format is determined by the "pcm" object. */
        ma_deconstruct_SLDataFormat_PCM__opensl(&pcm, &pDescriptorCapture->format, &pDescriptorCapture->channels, &pDescriptorCapture->sampleRate, pDescriptorCapture->channelMap, ma_countof(pDescriptorCapture->channelMap));

        /* Buffer. */
        pDescriptorCapture->periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptorCapture, pDescriptorCapture->sampleRate, pConfig->performanceProfile);
        pDevice->opensl.currentBufferIndexCapture = 0;

        bufferSizeInBytes = pDescriptorCapture->periodSizeInFrames * ma_get_bytes_per_frame(pDescriptorCapture->format, pDescriptorCapture->channels) * pDescriptorCapture->periodCount;
        pDevice->opensl.pBufferCapture = (ma_uint8*)ma_calloc(bufferSizeInBytes, &pDevice->pContext->allocationCallbacks);
        if (pDevice->opensl.pBufferCapture == NULL) {
            ma_device_uninit__opensl(pDevice);
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to allocate memory for data buffer.");
            return MA_OUT_OF_MEMORY;
        }
        MA_ZERO_MEMORY(pDevice->opensl.pBufferCapture, bufferSizeInBytes);
    }

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

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

        if (resultSL != SL_RESULT_SUCCESS) {
            ma_device_uninit__opensl(pDevice);
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to register buffer queue callback.");
            return ma_result_from_OpenSL(resultSL);
        }

        /* The internal format is determined by the "pcm" object. */
        ma_deconstruct_SLDataFormat_PCM__opensl(&pcm, &pDescriptorPlayback->format, &pDescriptorPlayback->channels, &pDescriptorPlayback->sampleRate, pDescriptorPlayback->channelMap, ma_countof(pDescriptorPlayback->channelMap));

        /* Buffer. */
        pDescriptorPlayback->periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptorPlayback, pDescriptorPlayback->sampleRate, pConfig->performanceProfile);
        pDevice->opensl.currentBufferIndexPlayback   = 0;

        bufferSizeInBytes = pDescriptorPlayback->periodSizeInFrames * ma_get_bytes_per_frame(pDescriptorPlayback->format, pDescriptorPlayback->channels) * pDescriptorPlayback->periodCount;
        pDevice->opensl.pBufferPlayback = (ma_uint8*)ma_calloc(bufferSizeInBytes, &pDevice->pContext->allocationCallbacks);
        if (pDevice->opensl.pBufferPlayback == NULL) {
            ma_device_uninit__opensl(pDevice);
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to allocate memory for data buffer.");
            return MA_OUT_OF_MEMORY;
        }
        MA_ZERO_MEMORY(pDevice->opensl.pBufferPlayback, bufferSizeInBytes);
    }

    return MA_SUCCESS;

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

        return MA_INVALID_OPERATION;
    }

    if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
        resultSL = MA_OPENSL_RECORD(pDevice->opensl.pAudioRecorder)->SetRecordState((SLRecordItf)pDevice->opensl.pAudioRecorder, SL_RECORDSTATE_RECORDING);
        if (resultSL != SL_RESULT_SUCCESS) {
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to start internal capture device.");
            return ma_result_from_OpenSL(resultSL);
        }

        periodSizeInBytes = pDevice->capture.internalPeriodSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
        for (iPeriod = 0; iPeriod < pDevice->capture.internalPeriods; ++iPeriod) {
            resultSL = MA_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueueCapture)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueueCapture, pDevice->opensl.pBufferCapture + (periodSizeInBytes * iPeriod), periodSizeInBytes);
            if (resultSL != SL_RESULT_SUCCESS) {
                MA_OPENSL_RECORD(pDevice->opensl.pAudioRecorder)->SetRecordState((SLRecordItf)pDevice->opensl.pAudioRecorder, SL_RECORDSTATE_STOPPED);
                ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to enqueue buffer for capture device.");
                return ma_result_from_OpenSL(resultSL);
            }
        }
    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        resultSL = MA_OPENSL_PLAY(pDevice->opensl.pAudioPlayer)->SetPlayState((SLPlayItf)pDevice->opensl.pAudioPlayer, SL_PLAYSTATE_PLAYING);
        if (resultSL != SL_RESULT_SUCCESS) {
            ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to start internal playback device.");
            return ma_result_from_OpenSL(resultSL);
        }

        /* In playback mode (no duplex) we need to load some initial buffers. In duplex mode we need to enqueu silent buffers. */
        if (pDevice->type == ma_device_type_duplex) {
            MA_ZERO_MEMORY(pDevice->opensl.pBufferPlayback, pDevice->playback.internalPeriodSizeInFrames * pDevice->playback.internalPeriods * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
        } else {
            ma_device__read_frames_from_client(pDevice, pDevice->playback.internalPeriodSizeInFrames * pDevice->playback.internalPeriods, pDevice->opensl.pBufferPlayback);
        }

        periodSizeInBytes = pDevice->playback.internalPeriodSizeInFrames * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
        for (iPeriod = 0; iPeriod < pDevice->playback.internalPeriods; ++iPeriod) {
            resultSL = MA_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueuePlayback)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueuePlayback, pDevice->opensl.pBufferPlayback + (periodSizeInBytes * iPeriod), periodSizeInBytes);
            if (resultSL != SL_RESULT_SUCCESS) {
                MA_OPENSL_PLAY(pDevice->opensl.pAudioPlayer)->SetPlayState((SLPlayItf)pDevice->opensl.pAudioPlayer, SL_PLAYSTATE_STOPPED);
                ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to enqueue buffer for playback device.");
                return ma_result_from_OpenSL(resultSL);
            }
        }
    }

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

static ma_bool32 ma_is_capture_supported__webaudio()
{
    return EM_ASM_INT({
        return (navigator.mediaDevices !== undefined && navigator.mediaDevices.getUserMedia !== undefined);
    }, 0) != 0; /* Must pass in a dummy argument for C99 compatibility. */
}

#ifdef __cplusplus
extern "C" {
#endif
void EMSCRIPTEN_KEEPALIVE ma_device_process_pcm_frames_capture__webaudio(ma_device* pDevice, int frameCount, float* pFrames)
{
    ma_device_handle_backend_data_callback(pDevice, NULL, pFrames, (ma_uint32)frameCount);
}

void EMSCRIPTEN_KEEPALIVE ma_device_process_pcm_frames_playback__webaudio(ma_device* pDevice, int frameCount, float* pFrames)
{
    ma_device_handle_backend_data_callback(pDevice, pFrames, NULL, (ma_uint32)frameCount);
}
#ifdef __cplusplus
}
#endif

static ma_result ma_context_enumerate_devices__webaudio(ma_context* pContext, ma_enum_devices_callback_proc callback, void* pUserData)
{
    ma_bool32 cbResult = MA_TRUE;

    MA_ASSERT(pContext != NULL);

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

        ma_device_uninit_by_index__webaudio(pDevice, ma_device_type_capture, pDevice->webaudio.indexCapture);
    }

    if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
        ma_device_uninit_by_index__webaudio(pDevice, ma_device_type_playback, pDevice->webaudio.indexPlayback);
    }

    return MA_SUCCESS;
}

static ma_uint32 ma_calculate_period_size_in_frames_from_descriptor__webaudio(const ma_device_descriptor* pDescriptor, ma_uint32 nativeSampleRate, ma_performance_profile performanceProfile)
{
    /*
    There have been reports of the default buffer size being too small on some browsers. There have been reports of the default buffer
    size being too small on some browsers. If we're using default buffer size, we'll make sure the period size is a big biffer than our
    standard defaults.
    */
    ma_uint32 periodSizeInFrames;

    if (pDescriptor->periodSizeInFrames == 0) {
        if (pDescriptor->periodSizeInMilliseconds == 0) {
            if (performanceProfile == ma_performance_profile_low_latency) {
                periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(33, nativeSampleRate);  /* 1 frame @ 30 FPS */
            } else {
                periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(333, nativeSampleRate);
            }
        } else {
            periodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(pDescriptor->periodSizeInMilliseconds, nativeSampleRate);
        }
    } else {
        periodSizeInFrames = pDescriptor->periodSizeInFrames;
    }

    /* The size of the buffer must be a power of 2 and between 256 and 16384. */
    if (periodSizeInFrames < 256) {
        periodSizeInFrames = 256;
    } else if (periodSizeInFrames > 16384) {
        periodSizeInFrames = 16384;

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

    MA_ASSERT(pConfig    != NULL);
    MA_ASSERT(deviceType != ma_device_type_duplex);

    if (deviceType == ma_device_type_capture && !ma_is_capture_supported__webaudio()) {
        return MA_NO_DEVICE;
    }

    /* We're going to calculate some stuff in C just to simplify the JS code. */
    channels           = (pDescriptor->channels   > 0) ? pDescriptor->channels   : MA_DEFAULT_CHANNELS;
    sampleRate         = (pDescriptor->sampleRate > 0) ? pDescriptor->sampleRate : MA_DEFAULT_SAMPLE_RATE;
    periodSizeInFrames = ma_calculate_period_size_in_frames_from_descriptor__webaudio(pDescriptor, sampleRate, pConfig->performanceProfile);

    ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "periodSizeInFrames = %d\n", (int)periodSizeInFrames);

    /* We create the device on the JavaScript side and reference it using an index. We use this to make it possible to reference the device between JavaScript and C. */
    deviceIndex = EM_ASM_INT({
        var channels   = $0;
        var sampleRate = $1;
        var bufferSize = $2;    /* In PCM frames. */
        var isCapture  = $3;
        var pDevice    = $4;

        if (typeof(window.miniaudio) === 'undefined') {
            return -1;  /* Context not initialized. */
        }

        var device = {};

        /* The AudioContext must be created in a suspended state. */

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


                /* Sanity check. This will never happen, right? */
                if (e.inputBuffer.numberOfChannels != channels) {
                    console.log("Capture: Channel count mismatch. " + e.inputBufer.numberOfChannels + " != " + channels + ". Sending silence.");
                    sendSilence = true;
                }

                /* This looped design guards against the situation where e.inputBuffer is a different size to the original buffer size. Should never happen in practice. */
                var totalFramesProcessed = 0;
                while (totalFramesProcessed < e.inputBuffer.length) {
                    var framesRemaining = e.inputBuffer.length - totalFramesProcessed;
                    var framesToProcess = framesRemaining;
                    if (framesToProcess > (device.intermediaryBufferSizeInBytes/channels/4)) {
                        framesToProcess = (device.intermediaryBufferSizeInBytes/channels/4);
                    }

                    /* We need to do the reverse of the playback case. We need to interleave the input data and copy it into the intermediary buffer. Then we send it to the client. */
                    if (sendSilence) {
                        device.intermediaryBufferView.fill(0.0);
                    } else {
                        for (var iFrame = 0; iFrame < framesToProcess; ++iFrame) {
                            for (var iChannel = 0; iChannel < e.inputBuffer.numberOfChannels; ++iChannel) {
                                device.intermediaryBufferView[iFrame*channels + iChannel] = e.inputBuffer.getChannelData(iChannel)[totalFramesProcessed + iFrame];
                            }
                        }
                    }

                    /* Send data to the client from our intermediary buffer. */
                    ccall("ma_device_process_pcm_frames_capture__webaudio", "undefined", ["number", "number", "number"], [pDevice, framesToProcess, device.intermediaryBuffer]);

                    totalFramesProcessed += framesToProcess;
                }
            };

            navigator.mediaDevices.getUserMedia({audio:true, video:false})
                .then(function(stream) {
                    device.streamNode = device.webaudio.createMediaStreamSource(stream);
                    device.streamNode.connect(device.scriptNode);
                    device.scriptNode.connect(device.webaudio.destination);
                })
                .catch(function(error) {

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

                /* Sanity check. This will never happen, right? */
                if (e.outputBuffer.numberOfChannels != channels) {
                    console.log("Playback: Channel count mismatch. " + e.outputBufer.numberOfChannels + " != " + channels + ". Outputting silence.");
                    outputSilence = true;
                    return;
                }

                /* This looped design guards against the situation where e.outputBuffer is a different size to the original buffer size. Should never happen in practice. */
                var totalFramesProcessed = 0;
                while (totalFramesProcessed < e.outputBuffer.length) {
                    var framesRemaining = e.outputBuffer.length - totalFramesProcessed;
                    var framesToProcess = framesRemaining;
                    if (framesToProcess > (device.intermediaryBufferSizeInBytes/channels/4)) {
                        framesToProcess = (device.intermediaryBufferSizeInBytes/channels/4);
                    }

                    /* Read data from the client into our intermediary buffer. */
                    ccall("ma_device_process_pcm_frames_playback__webaudio", "undefined", ["number", "number", "number"], [pDevice, framesToProcess, device.intermediaryBuffer]);

                    /* At this point we'll have data in our intermediary buffer which we now need to deinterleave and copy over to the output buffers. */
                    if (outputSilence) {
                        for (var iChannel = 0; iChannel < e.outputBuffer.numberOfChannels; ++iChannel) {
                            e.outputBuffer.getChannelData(iChannel).fill(0.0);
                        }
                    } else {
                        for (var iChannel = 0; iChannel < e.outputBuffer.numberOfChannels; ++iChannel) {
                            var outputBuffer = e.outputBuffer.getChannelData(iChannel);
                            var intermediaryBuffer = device.intermediaryBufferView;
                            for (var iFrame = 0; iFrame < framesToProcess; ++iFrame) {
                                outputBuffer[totalFramesProcessed + iFrame] = intermediaryBuffer[iFrame*channels + iChannel];
                            }
                        }
                    }

                    totalFramesProcessed += framesToProcess;
                }
            };

            device.scriptNode.connect(device.webaudio.destination);
        }

        return miniaudio.track_device(device);
    }, channels, sampleRate, periodSizeInFrames, deviceType == ma_device_type_capture, pDevice);

    if (deviceIndex < 0) {

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


        result = ma_data_converter_init(&converterConfig, &pDevice->pContext->allocationCallbacks, &pDevice->playback.converter);
        if (result != MA_SUCCESS) {
            return result;
        }
    }


    /*
    In playback mode, if the data converter does not support retrieval of the required number of
    input frames given a number of output frames, we need to fall back to a heap-allocated cache.
    */
    if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) {
        ma_uint64 unused;

        pDevice->playback.inputCacheConsumed  = 0;
        pDevice->playback.inputCacheRemaining = 0;

        if (deviceType == ma_device_type_duplex || ma_data_converter_get_required_input_frame_count(&pDevice->playback.converter, 1, &unused) != MA_SUCCESS) {
            /* We need a heap allocated cache. We want to size this based on the period size. */
            void* pNewInputCache;
            ma_uint64 newInputCacheCap;
            ma_uint64 newInputCacheSizeInBytes;

            newInputCacheCap = ma_calculate_frame_count_after_resampling(pDevice->playback.internalSampleRate, pDevice->sampleRate, pDevice->playback.internalPeriodSizeInFrames);

            newInputCacheSizeInBytes = newInputCacheCap * ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
            if (newInputCacheSizeInBytes > MA_SIZE_MAX) {
                ma_free(pDevice->playback.pInputCache, &pDevice->pContext->allocationCallbacks);
                pDevice->playback.pInputCache   = NULL;
                pDevice->playback.inputCacheCap = 0;
                return MA_OUT_OF_MEMORY;    /* Allocation too big. Should never hit this, but makes the cast below safer for 32-bit builds. */
            }

            pNewInputCache   = ma_realloc(pDevice->playback.pInputCache, (size_t)newInputCacheSizeInBytes, &pDevice->pContext->allocationCallbacks);
            if (pNewInputCache == NULL) {
                ma_free(pDevice->playback.pInputCache, &pDevice->pContext->allocationCallbacks);

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

        }

        pDevice->capture.internalFormat             = pDescriptorCapture->format;
        pDevice->capture.internalChannels           = pDescriptorCapture->channels;
        pDevice->capture.internalSampleRate         = pDescriptorCapture->sampleRate;
        MA_COPY_MEMORY(pDevice->capture.internalChannelMap, pDescriptorCapture->channelMap, sizeof(pDescriptorCapture->channelMap));
        pDevice->capture.internalPeriodSizeInFrames = pDescriptorCapture->periodSizeInFrames;
        pDevice->capture.internalPeriods            = pDescriptorCapture->periodCount;

        if (pDevice->capture.internalPeriodSizeInFrames == 0) {
            pDevice->capture.internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(pDescriptorCapture->periodSizeInMilliseconds, pDescriptorCapture->sampleRate);
        }
    }

    /* Playback. */
    if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) {
        if (ma_device_descriptor_is_valid(pDescriptorPlayback) == MA_FALSE) {
            return MA_INVALID_ARGS;
        }

        pDevice->playback.internalFormat             = pDescriptorPlayback->format;
        pDevice->playback.internalChannels           = pDescriptorPlayback->channels;
        pDevice->playback.internalSampleRate         = pDescriptorPlayback->sampleRate;
        MA_COPY_MEMORY(pDevice->playback.internalChannelMap, pDescriptorPlayback->channelMap, sizeof(pDescriptorPlayback->channelMap));
        pDevice->playback.internalPeriodSizeInFrames = pDescriptorPlayback->periodSizeInFrames;
        pDevice->playback.internalPeriods            = pDescriptorPlayback->periodCount;

        if (pDevice->playback.internalPeriodSizeInFrames == 0) {
            pDevice->playback.internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(pDescriptorPlayback->periodSizeInMilliseconds, pDescriptorPlayback->sampleRate);
        }
    }

    /*
    The name of the device can be retrieved from device info. This may be temporary and replaced with a `ma_device_get_info(pDevice, deviceType)` instead.
    For loopback devices, we need to retrieve the name of the playback device.
    */
    {
        ma_device_info deviceInfo;

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

        }

        pDevice->capture.internalFormat             = descriptorCapture.format;
        pDevice->capture.internalChannels           = descriptorCapture.channels;
        pDevice->capture.internalSampleRate         = descriptorCapture.sampleRate;
        ma_channel_map_copy(pDevice->capture.internalChannelMap, descriptorCapture.channelMap, descriptorCapture.channels);
        pDevice->capture.internalPeriodSizeInFrames = descriptorCapture.periodSizeInFrames;
        pDevice->capture.internalPeriods            = descriptorCapture.periodCount;

        if (pDevice->capture.internalPeriodSizeInFrames == 0) {
            pDevice->capture.internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(descriptorCapture.periodSizeInMilliseconds, descriptorCapture.sampleRate);
        }
    }

    if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
        if (!ma_device_descriptor_is_valid(&descriptorPlayback)) {
            ma_device_uninit(pDevice);
            return MA_INVALID_ARGS;
        }

        pDevice->playback.internalFormat             = descriptorPlayback.format;
        pDevice->playback.internalChannels           = descriptorPlayback.channels;
        pDevice->playback.internalSampleRate         = descriptorPlayback.sampleRate;
        ma_channel_map_copy(pDevice->playback.internalChannelMap, descriptorPlayback.channelMap, descriptorPlayback.channels);
        pDevice->playback.internalPeriodSizeInFrames = descriptorPlayback.periodSizeInFrames;
        pDevice->playback.internalPeriods            = descriptorPlayback.periodCount;

        if (pDevice->playback.internalPeriodSizeInFrames == 0) {
            pDevice->playback.internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_milliseconds(descriptorPlayback.periodSizeInMilliseconds, descriptorPlayback.sampleRate);
        }
    }


    /*
    The name of the device can be retrieved from device info. This may be temporary and replaced with a `ma_device_get_info(pDevice, deviceType)` instead.
    For loopback devices, we need to retrieve the name of the playback device.
    */
    {
        ma_device_info deviceInfo;

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



    /*
    If we're using fixed sized callbacks we'll need to make use of an intermediary buffer. Needs to
    be done after post_init_setup() because we'll need access to the sample rate.
    */
    if (pConfig->noFixedSizedCallback == MA_FALSE) {
        /* We're using a fixed sized data callback so we'll need an intermediary buffer. */
        ma_uint32 intermediaryBufferCap = pConfig->periodSizeInFrames;
        if (intermediaryBufferCap == 0) {
            intermediaryBufferCap = ma_calculate_buffer_size_in_frames_from_milliseconds(pConfig->periodSizeInMilliseconds, pDevice->sampleRate);
        }

        if (pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex || pConfig->deviceType == ma_device_type_loopback) {
            ma_uint32 intermediaryBufferSizeInBytes;

            pDevice->capture.intermediaryBufferLen = 0;
            pDevice->capture.intermediaryBufferCap = intermediaryBufferCap;
            if (pDevice->capture.intermediaryBufferCap == 0) {
                pDevice->capture.intermediaryBufferCap = pDevice->capture.internalPeriodSizeInFrames;
            }

            intermediaryBufferSizeInBytes = pDevice->capture.intermediaryBufferCap * ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);

            pDevice->capture.pIntermediaryBuffer = ma_malloc((size_t)intermediaryBufferSizeInBytes, &pContext->allocationCallbacks);
            if (pDevice->capture.pIntermediaryBuffer == NULL) {
                ma_device_uninit(pDevice);
                return MA_OUT_OF_MEMORY;
            }

            /* Silence the buffer for safety. */
            ma_silence_pcm_frames(pDevice->capture.pIntermediaryBuffer, pDevice->capture.intermediaryBufferCap, pDevice->capture.format, pDevice->capture.channels);
            pDevice->capture.intermediaryBufferLen = pDevice->capture.intermediaryBufferCap;
        }

        if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
            ma_uint64 intermediaryBufferSizeInBytes;
            
            pDevice->playback.intermediaryBufferLen = 0;
            if (pConfig->deviceType == ma_device_type_duplex) {
                pDevice->playback.intermediaryBufferCap = pDevice->capture.intermediaryBufferCap;   /* In duplex mode, make sure the intermediary buffer is always the same size as the capture side. */
            } else {
                pDevice->playback.intermediaryBufferCap = intermediaryBufferCap;
                if (pDevice->playback.intermediaryBufferCap == 0) {
                    pDevice->playback.intermediaryBufferCap = pDevice->playback.internalPeriodSizeInFrames;
                }
            }

            intermediaryBufferSizeInBytes = pDevice->playback.intermediaryBufferCap * ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
            
            pDevice->playback.pIntermediaryBuffer = ma_malloc((size_t)intermediaryBufferSizeInBytes, &pContext->allocationCallbacks);
            if (pDevice->playback.pIntermediaryBuffer == NULL) {
                ma_device_uninit(pDevice);
                return MA_OUT_OF_MEMORY;
            }

            /* Silence the buffer for safety. */
            ma_silence_pcm_frames(pDevice->playback.pIntermediaryBuffer, pDevice->playback.intermediaryBufferCap, pDevice->playback.format, pDevice->playback.channels);
            pDevice->playback.intermediaryBufferLen = 0;
        }
    } else {
        /* Not using a fixed sized data callback so no need for an intermediary buffer. */
    }


    /* Some backends don't require the worker thread. */
    if (!ma_context_is_backend_asynchronous(pContext)) {
        /* The worker thread. */

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

        *pGainDB = 0;
        return result;
    }

    *pGainDB = ma_volume_linear_to_db(factor);

    return MA_SUCCESS;
}


MA_API ma_result ma_device_handle_backend_data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
{
    if (pDevice == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pOutput == NULL && pInput == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pDevice->type == ma_device_type_duplex) {
        if (pInput != NULL) {
            ma_device__handle_duplex_callback_capture(pDevice, frameCount, pInput, &pDevice->duplexRB.rb);
        }

        if (pOutput != NULL) {
            ma_device__handle_duplex_callback_playback(pDevice, frameCount, pOutput, &pDevice->duplexRB.rb);
        }
    } else {
        if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_loopback) {
            if (pInput == NULL) {
                return MA_INVALID_ARGS;
            }

            ma_device__send_frames_to_client(pDevice, frameCount, pInput);
        }

        if (pDevice->type == ma_device_type_playback) {
            if (pOutput == NULL) {
                return MA_INVALID_ARGS;
            }

            ma_device__read_frames_from_client(pDevice, frameCount, pOutput);
        }
    }

    return MA_SUCCESS;
}

MA_API ma_uint32 ma_calculate_buffer_size_in_frames_from_descriptor(const ma_device_descriptor* pDescriptor, ma_uint32 nativeSampleRate, ma_performance_profile performanceProfile)
{
    if (pDescriptor == NULL) {
        return 0;
    }

    /*
    We must have a non-0 native sample rate, but some backends don't allow retrieval of this at the
    time when the size of the buffer needs to be determined. In this case we need to just take a best
    guess and move on. We'll try using the sample rate in pDescriptor first. If that's not set we'll
    just fall back to MA_DEFAULT_SAMPLE_RATE.

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

    }
    if (nativeSampleRate == 0) {
        nativeSampleRate = MA_DEFAULT_SAMPLE_RATE;
    }

    MA_ASSERT(nativeSampleRate != 0);

    if (pDescriptor->periodSizeInFrames == 0) {
        if (pDescriptor->periodSizeInMilliseconds == 0) {
            if (performanceProfile == ma_performance_profile_low_latency) {
                return ma_calculate_buffer_size_in_frames_from_milliseconds(MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_LOW_LATENCY, nativeSampleRate);
            } else {
                return ma_calculate_buffer_size_in_frames_from_milliseconds(MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_CONSERVATIVE, nativeSampleRate);
            }
        } else {
            return ma_calculate_buffer_size_in_frames_from_milliseconds(pDescriptor->periodSizeInMilliseconds, nativeSampleRate);
        }
    } else {
        return pDescriptor->periodSizeInFrames;
    }
}
#endif  /* MA_NO_DEVICE_IO */


MA_API ma_uint32 ma_calculate_buffer_size_in_milliseconds_from_frames(ma_uint32 bufferSizeInFrames, ma_uint32 sampleRate)
{
    /* Prevent a division by zero. */
    if (sampleRate == 0) {
        return 0;
    }

    return bufferSizeInFrames*1000 / sampleRate;
}

MA_API ma_uint32 ma_calculate_buffer_size_in_frames_from_milliseconds(ma_uint32 bufferSizeInMilliseconds, ma_uint32 sampleRate)
{
    /* Prevent a division by zero. */
    if (sampleRate == 0) {
        return 0;
    }

    return bufferSizeInMilliseconds*sampleRate / 1000;
}

MA_API void ma_copy_pcm_frames(void* dst, const void* src, ma_uint64 frameCount, ma_format format, ma_uint32 channels)
{
    if (dst == src) {
        return; /* No-op. */
    }

    ma_copy_memory_64(dst, src, frameCount * ma_get_bytes_per_frame(format, channels));
}

MA_API void ma_silence_pcm_frames(void* p, ma_uint64 frameCount, ma_format format, ma_uint32 channels)
{
    if (format == ma_format_u8) {
        ma_uint64 sampleCount = frameCount * channels;
        ma_uint64 iSample;
        for (iSample = 0; iSample < sampleCount; iSample += 1) {
            ((ma_uint8*)p)[iSample] = 128;
        }
    } else {
        ma_zero_memory_64(p, frameCount * ma_get_bytes_per_frame(format, channels));
    }
}

MA_API void* ma_offset_pcm_frames_ptr(void* p, ma_uint64 offsetInFrames, ma_format format, ma_uint32 channels)
{
    return ma_offset_ptr(p, offsetInFrames * ma_get_bytes_per_frame(format, channels));
}

MA_API const void* ma_offset_pcm_frames_const_ptr(const void* p, ma_uint64 offsetInFrames, ma_format format, ma_uint32 channels)
{
    return ma_offset_ptr(p, offsetInFrames * ma_get_bytes_per_frame(format, channels));
}


MA_API void ma_clip_samples_u8(ma_uint8* pDst, const ma_int16* pSrc, ma_uint64 count)
{
    ma_uint64 iSample;

    MA_ASSERT(pDst != NULL);
    MA_ASSERT(pSrc != NULL);

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

    ma_uint64 iSample;

    MA_ASSERT(pDst != NULL);
    MA_ASSERT(pSrc != NULL);

    for (iSample = 0; iSample < count; iSample += 1) {
        pDst[iSample] = ma_clip_f32(pSrc[iSample]);
    }
}

MA_API void ma_clip_pcm_frames(void* pDst, const void* pSrc, ma_uint64 frameCount, ma_format format, ma_uint32 channels)
{
    ma_uint64 sampleCount;

    MA_ASSERT(pDst != NULL);
    MA_ASSERT(pSrc != NULL);

    sampleCount = frameCount * channels;

    switch (format) {
        case ma_format_u8:  ma_clip_samples_u8( (ma_uint8*)pDst, (const ma_int16*)pSrc, sampleCount); break;
        case ma_format_s16: ma_clip_samples_s16((ma_int16*)pDst, (const ma_int32*)pSrc, sampleCount); break;
        case ma_format_s24: ma_clip_samples_s24((ma_uint8*)pDst, (const ma_int64*)pSrc, sampleCount); break;
        case ma_format_s32: ma_clip_samples_s32((ma_int32*)pDst, (const ma_int64*)pSrc, sampleCount); break;
        case ma_format_f32: ma_clip_samples_f32((   float*)pDst, (const    float*)pSrc, sampleCount); break;

        /* Do nothing if we don't know the format. We're including these here to silence a compiler warning about enums not being handled by the switch. */
        case ma_format_unknown:

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

MA_API void ma_apply_volume_factor_s32(ma_int32* pSamples, ma_uint64 sampleCount, float factor)
{
    ma_copy_and_apply_volume_factor_s32(pSamples, pSamples, sampleCount, factor);
}

MA_API void ma_apply_volume_factor_f32(float* pSamples, ma_uint64 sampleCount, float factor)
{
    ma_copy_and_apply_volume_factor_f32(pSamples, pSamples, sampleCount, factor);
}

MA_API void ma_copy_and_apply_volume_factor_pcm_frames_u8(ma_uint8* pFramesOut, const ma_uint8* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_u8(pFramesOut, pFramesIn, frameCount*channels, factor);
}

MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s16(ma_int16* pFramesOut, const ma_int16* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_s16(pFramesOut, pFramesIn, frameCount*channels, factor);
}

MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s24(void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_s24(pFramesOut, pFramesIn, frameCount*channels, factor);
}

MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s32(ma_int32* pFramesOut, const ma_int32* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_s32(pFramesOut, pFramesIn, frameCount*channels, factor);
}

MA_API void ma_copy_and_apply_volume_factor_pcm_frames_f32(float* pFramesOut, const float* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_f32(pFramesOut, pFramesIn, frameCount*channels, factor);
}

MA_API void ma_copy_and_apply_volume_factor_pcm_frames(void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float factor)
{
    switch (format)
    {
    case ma_format_u8:  ma_copy_and_apply_volume_factor_pcm_frames_u8 ((ma_uint8*)pFramesOut, (const ma_uint8*)pFramesIn, frameCount, channels, factor); return;
    case ma_format_s16: ma_copy_and_apply_volume_factor_pcm_frames_s16((ma_int16*)pFramesOut, (const ma_int16*)pFramesIn, frameCount, channels, factor); return;
    case ma_format_s24: ma_copy_and_apply_volume_factor_pcm_frames_s24(           pFramesOut,                  pFramesIn, frameCount, channels, factor); return;
    case ma_format_s32: ma_copy_and_apply_volume_factor_pcm_frames_s32((ma_int32*)pFramesOut, (const ma_int32*)pFramesIn, frameCount, channels, factor); return;
    case ma_format_f32: ma_copy_and_apply_volume_factor_pcm_frames_f32(   (float*)pFramesOut,    (const float*)pFramesIn, frameCount, channels, factor); return;
    default: return;    /* Do nothing. */
    }
}

MA_API void ma_apply_volume_factor_pcm_frames_u8(ma_uint8* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_pcm_frames_u8(pFrames, pFrames, frameCount, channels, factor);
}

MA_API void ma_apply_volume_factor_pcm_frames_s16(ma_int16* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_pcm_frames_s16(pFrames, pFrames, frameCount, channels, factor);
}

MA_API void ma_apply_volume_factor_pcm_frames_s24(void* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_pcm_frames_s24(pFrames, pFrames, frameCount, channels, factor);
}

MA_API void ma_apply_volume_factor_pcm_frames_s32(ma_int32* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_pcm_frames_s32(pFrames, pFrames, frameCount, channels, factor);
}

MA_API void ma_apply_volume_factor_pcm_frames_f32(float* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_pcm_frames_f32(pFrames, pFrames, frameCount, channels, factor);
}

MA_API void ma_apply_volume_factor_pcm_frames(void* pFramesOut, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float factor)
{
    ma_copy_and_apply_volume_factor_pcm_frames(pFramesOut, pFramesOut, frameCount, format, channels, factor);
}


MA_API void ma_copy_and_apply_volume_factor_per_channel_f32(float* pFramesOut, const float* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float* pChannelGains)
{
    ma_uint64 iFrame;

    if (channels == 2) {
        /* TODO: Do an optimized implementation for stereo and mono. Can do a SIMD optimized implementation as well. */
    }

    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            pFramesOut[iFrame * channels + iChannel] = pFramesIn[iFrame * channels + iChannel] * pChannelGains[iChannel];
        }
    }
}



static MA_INLINE ma_int16 ma_apply_volume_unclipped_u8(ma_int16 x, ma_int16 volume)

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

    MA_ASSERT(pDst != NULL);
    MA_ASSERT(pSrc != NULL);

    /* For the f32 case we need to make sure this supports in-place processing where the input and output buffers are the same. */

    for (iSample = 0; iSample < count; iSample += 1) {
        pDst[iSample] = ma_clip_f32(ma_apply_volume_unclipped_f32(pSrc[iSample], volume));
    }
}

MA_API void ma_copy_and_apply_volume_and_clip_pcm_frames(void* pDst, const void* pSrc, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float volume)
{
    MA_ASSERT(pDst != NULL);
    MA_ASSERT(pSrc != NULL);

    if (volume == 1) {
        ma_clip_pcm_frames(pDst, pSrc, frameCount, format, channels);   /* Optimized case for volume = 1. */
    } else if (volume == 0) {
        ma_silence_pcm_frames(pDst, frameCount, format, channels);      /* Optimized case for volume = 0. */
    } else {
        ma_uint64 sampleCount = frameCount * channels;

        switch (format) {
            case ma_format_u8:  ma_copy_and_apply_volume_and_clip_samples_u8( (ma_uint8*)pDst, (const ma_int16*)pSrc, sampleCount, volume); break;
            case ma_format_s16: ma_copy_and_apply_volume_and_clip_samples_s16((ma_int16*)pDst, (const ma_int32*)pSrc, sampleCount, volume); break;
            case ma_format_s24: ma_copy_and_apply_volume_and_clip_samples_s24((ma_uint8*)pDst, (const ma_int64*)pSrc, sampleCount, volume); break;
            case ma_format_s32: ma_copy_and_apply_volume_and_clip_samples_s32((ma_int32*)pDst, (const ma_int64*)pSrc, sampleCount, volume); break;
            case ma_format_f32: ma_copy_and_apply_volume_and_clip_samples_f32((   float*)pDst, (const    float*)pSrc, sampleCount, volume); break;

            /* Do nothing if we don't know the format. We're including these here to silence a compiler warning about enums not being handled by the switch. */
            case ma_format_unknown:

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

        } else
    #endif
        {
            ma_pcm_u8_to_f32__optimized(dst, src, count, ditherMode);
        }
#endif
}


#ifdef MA_USE_REFERENCE_CONVERSION_APIS
static MA_INLINE void ma_pcm_interleave_u8__reference(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_uint8* dst_u8 = (ma_uint8*)dst;
    const ma_uint8** src_u8 = (const ma_uint8**)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_u8[iFrame*channels + iChannel] = src_u8[iChannel][iFrame];
        }
    }
}
#else
static MA_INLINE void ma_pcm_interleave_u8__optimized(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_uint8* dst_u8 = (ma_uint8*)dst;
    const ma_uint8** src_u8 = (const ma_uint8**)src;

    if (channels == 1) {
        ma_copy_memory_64(dst, src[0], frameCount * sizeof(ma_uint8));
    } else if (channels == 2) {
        ma_uint64 iFrame;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            dst_u8[iFrame*2 + 0] = src_u8[0][iFrame];
            dst_u8[iFrame*2 + 1] = src_u8[1][iFrame];
        }
    } else {
        ma_uint64 iFrame;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            ma_uint32 iChannel;
            for (iChannel = 0; iChannel < channels; iChannel += 1) {
                dst_u8[iFrame*channels + iChannel] = src_u8[iChannel][iFrame];
            }
        }
    }
}
#endif

MA_API void ma_pcm_interleave_u8(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_interleave_u8__reference(dst, src, frameCount, channels);
#else
    ma_pcm_interleave_u8__optimized(dst, src, frameCount, channels);
#endif
}


static MA_INLINE void ma_pcm_deinterleave_u8__reference(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_uint8** dst_u8 = (ma_uint8**)dst;
    const ma_uint8* src_u8 = (const ma_uint8*)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_u8[iChannel][iFrame] = src_u8[iFrame*channels + iChannel];
        }
    }
}

static MA_INLINE void ma_pcm_deinterleave_u8__optimized(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_deinterleave_u8__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_deinterleave_u8(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_deinterleave_u8__reference(dst, src, frameCount, channels);
#else
    ma_pcm_deinterleave_u8__optimized(dst, src, frameCount, channels);
#endif
}


/* s16 */
static MA_INLINE void ma_pcm_s16_to_u8__reference(void* dst, const void* src, ma_uint64 count, ma_dither_mode ditherMode)
{
    ma_uint8* dst_u8 = (ma_uint8*)dst;
    const ma_int16* src_s16 = (const ma_int16*)src;

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

            ma_pcm_s16_to_f32__neon(dst, src, count, ditherMode);
        } else
    #endif
        {
            ma_pcm_s16_to_f32__optimized(dst, src, count, ditherMode);
        }
#endif
}


static MA_INLINE void ma_pcm_interleave_s16__reference(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_int16* dst_s16 = (ma_int16*)dst;
    const ma_int16** src_s16 = (const ma_int16**)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_s16[iFrame*channels + iChannel] = src_s16[iChannel][iFrame];
        }
    }
}

static MA_INLINE void ma_pcm_interleave_s16__optimized(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_interleave_s16__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_interleave_s16(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_interleave_s16__reference(dst, src, frameCount, channels);
#else
    ma_pcm_interleave_s16__optimized(dst, src, frameCount, channels);
#endif
}


static MA_INLINE void ma_pcm_deinterleave_s16__reference(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_int16** dst_s16 = (ma_int16**)dst;
    const ma_int16* src_s16 = (const ma_int16*)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_s16[iChannel][iFrame] = src_s16[iFrame*channels + iChannel];
        }
    }
}

static MA_INLINE void ma_pcm_deinterleave_s16__optimized(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_deinterleave_s16__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_deinterleave_s16(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_deinterleave_s16__reference(dst, src, frameCount, channels);
#else
    ma_pcm_deinterleave_s16__optimized(dst, src, frameCount, channels);
#endif
}


/* s24 */
static MA_INLINE void ma_pcm_s24_to_u8__reference(void* dst, const void* src, ma_uint64 count, ma_dither_mode ditherMode)
{
    ma_uint8* dst_u8 = (ma_uint8*)dst;
    const ma_uint8* src_s24 = (const ma_uint8*)src;

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

            ma_pcm_s24_to_f32__neon(dst, src, count, ditherMode);
        } else
    #endif
        {
            ma_pcm_s24_to_f32__optimized(dst, src, count, ditherMode);
        }
#endif
}


static MA_INLINE void ma_pcm_interleave_s24__reference(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_uint8* dst8 = (ma_uint8*)dst;
    const ma_uint8** src8 = (const ma_uint8**)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst8[iFrame*3*channels + iChannel*3 + 0] = src8[iChannel][iFrame*3 + 0];
            dst8[iFrame*3*channels + iChannel*3 + 1] = src8[iChannel][iFrame*3 + 1];
            dst8[iFrame*3*channels + iChannel*3 + 2] = src8[iChannel][iFrame*3 + 2];
        }
    }
}

static MA_INLINE void ma_pcm_interleave_s24__optimized(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_interleave_s24__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_interleave_s24(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_interleave_s24__reference(dst, src, frameCount, channels);
#else
    ma_pcm_interleave_s24__optimized(dst, src, frameCount, channels);
#endif
}


static MA_INLINE void ma_pcm_deinterleave_s24__reference(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_uint8** dst8 = (ma_uint8**)dst;
    const ma_uint8* src8 = (const ma_uint8*)src;

    ma_uint32 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst8[iChannel][iFrame*3 + 0] = src8[iFrame*3*channels + iChannel*3 + 0];
            dst8[iChannel][iFrame*3 + 1] = src8[iFrame*3*channels + iChannel*3 + 1];
            dst8[iChannel][iFrame*3 + 2] = src8[iFrame*3*channels + iChannel*3 + 2];
        }
    }
}

static MA_INLINE void ma_pcm_deinterleave_s24__optimized(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_deinterleave_s24__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_deinterleave_s24(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_deinterleave_s24__reference(dst, src, frameCount, channels);
#else
    ma_pcm_deinterleave_s24__optimized(dst, src, frameCount, channels);
#endif
}



/* s32 */
static MA_INLINE void ma_pcm_s32_to_u8__reference(void* dst, const void* src, ma_uint64 count, ma_dither_mode ditherMode)
{
    ma_uint8* dst_u8 = (ma_uint8*)dst;
    const ma_int32* src_s32 = (const ma_int32*)src;

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

            ma_pcm_s32_to_f32__neon(dst, src, count, ditherMode);
        } else
    #endif
        {
            ma_pcm_s32_to_f32__optimized(dst, src, count, ditherMode);
        }
#endif
}


static MA_INLINE void ma_pcm_interleave_s32__reference(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_int32* dst_s32 = (ma_int32*)dst;
    const ma_int32** src_s32 = (const ma_int32**)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_s32[iFrame*channels + iChannel] = src_s32[iChannel][iFrame];
        }
    }
}

static MA_INLINE void ma_pcm_interleave_s32__optimized(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_interleave_s32__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_interleave_s32(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_interleave_s32__reference(dst, src, frameCount, channels);
#else
    ma_pcm_interleave_s32__optimized(dst, src, frameCount, channels);
#endif
}


static MA_INLINE void ma_pcm_deinterleave_s32__reference(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_int32** dst_s32 = (ma_int32**)dst;
    const ma_int32* src_s32 = (const ma_int32*)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_s32[iChannel][iFrame] = src_s32[iFrame*channels + iChannel];
        }
    }
}

static MA_INLINE void ma_pcm_deinterleave_s32__optimized(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_deinterleave_s32__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_deinterleave_s32(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_deinterleave_s32__reference(dst, src, frameCount, channels);
#else
    ma_pcm_deinterleave_s32__optimized(dst, src, frameCount, channels);
#endif
}


/* f32 */
static MA_INLINE void ma_pcm_f32_to_u8__reference(void* dst, const void* src, ma_uint64 count, ma_dither_mode ditherMode)
{
    ma_uint64 i;

    ma_uint8* dst_u8 = (ma_uint8*)dst;

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



MA_API void ma_pcm_f32_to_f32(void* dst, const void* src, ma_uint64 count, ma_dither_mode ditherMode)
{
    (void)ditherMode;

    ma_copy_memory_64(dst, src, count * sizeof(float));
}


static void ma_pcm_interleave_f32__reference(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    float* dst_f32 = (float*)dst;
    const float** src_f32 = (const float**)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_f32[iFrame*channels + iChannel] = src_f32[iChannel][iFrame];
        }
    }
}

static void ma_pcm_interleave_f32__optimized(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_interleave_f32__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_interleave_f32(void* dst, const void** src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_interleave_f32__reference(dst, src, frameCount, channels);
#else
    ma_pcm_interleave_f32__optimized(dst, src, frameCount, channels);
#endif
}


static void ma_pcm_deinterleave_f32__reference(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    float** dst_f32 = (float**)dst;
    const float* src_f32 = (const float*)src;

    ma_uint64 iFrame;
    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        ma_uint32 iChannel;
        for (iChannel = 0; iChannel < channels; iChannel += 1) {
            dst_f32[iChannel][iFrame] = src_f32[iFrame*channels + iChannel];
        }
    }
}

static void ma_pcm_deinterleave_f32__optimized(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
    ma_pcm_deinterleave_f32__reference(dst, src, frameCount, channels);
}

MA_API void ma_pcm_deinterleave_f32(void** dst, const void* src, ma_uint64 frameCount, ma_uint32 channels)
{
#ifdef MA_USE_REFERENCE_CONVERSION_APIS
    ma_pcm_deinterleave_f32__reference(dst, src, frameCount, channels);
#else
    ma_pcm_deinterleave_f32__optimized(dst, src, frameCount, channels);
#endif
}


MA_API void ma_pcm_convert(void* pOut, ma_format formatOut, const void* pIn, ma_format formatIn, ma_uint64 sampleCount, ma_dither_mode ditherMode)
{
    if (formatOut == formatIn) {
        ma_copy_memory_64(pOut, pIn, sampleCount * ma_get_bytes_per_sample(formatOut));
        return;
    }

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

                case ma_format_s24: ma_pcm_f32_to_s24(pOut, pIn, sampleCount, ditherMode); return;
                case ma_format_s32: ma_pcm_f32_to_s32(pOut, pIn, sampleCount, ditherMode); return;
                default: break;
            }
        } break;

        default: break;
    }
}

MA_API void ma_convert_pcm_frames_format(void* pOut, ma_format formatOut, const void* pIn, ma_format formatIn, ma_uint64 frameCount, ma_uint32 channels, ma_dither_mode ditherMode)
{
    ma_pcm_convert(pOut, formatOut, pIn, formatIn, frameCount * channels, ditherMode);
}

MA_API void ma_deinterleave_pcm_frames(ma_format format, ma_uint32 channels, ma_uint64 frameCount, const void* pInterleavedPCMFrames, void** ppDeinterleavedPCMFrames)
{
    if (pInterleavedPCMFrames == NULL || ppDeinterleavedPCMFrames == NULL) {
        return; /* Invalid args. */
    }

    /* For efficiency we do this per format. */
    switch (format) {
        case ma_format_s16:
        {
            const ma_int16* pSrcS16 = (const ma_int16*)pInterleavedPCMFrames;
            ma_uint64 iPCMFrame;
            for (iPCMFrame = 0; iPCMFrame < frameCount; ++iPCMFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < channels; ++iChannel) {
                    ma_int16* pDstS16 = (ma_int16*)ppDeinterleavedPCMFrames[iChannel];
                    pDstS16[iPCMFrame] = pSrcS16[iPCMFrame*channels+iChannel];
                }
            }
        } break;

        case ma_format_f32:
        {
            const float* pSrcF32 = (const float*)pInterleavedPCMFrames;
            ma_uint64 iPCMFrame;
            for (iPCMFrame = 0; iPCMFrame < frameCount; ++iPCMFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < channels; ++iChannel) {
                    float* pDstF32 = (float*)ppDeinterleavedPCMFrames[iChannel];
                    pDstF32[iPCMFrame] = pSrcF32[iPCMFrame*channels+iChannel];
                }
            }
        } break;

        default:
        {
            ma_uint32 sampleSizeInBytes = ma_get_bytes_per_sample(format);
            ma_uint64 iPCMFrame;
            for (iPCMFrame = 0; iPCMFrame < frameCount; ++iPCMFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < channels; ++iChannel) {
                          void* pDst = ma_offset_ptr(ppDeinterleavedPCMFrames[iChannel], iPCMFrame*sampleSizeInBytes);
                    const void* pSrc = ma_offset_ptr(pInterleavedPCMFrames, (iPCMFrame*channels+iChannel)*sampleSizeInBytes);
                    memcpy(pDst, pSrc, sampleSizeInBytes);
                }
            }
        } break;
    }
}

MA_API void ma_interleave_pcm_frames(ma_format format, ma_uint32 channels, ma_uint64 frameCount, const void** ppDeinterleavedPCMFrames, void* pInterleavedPCMFrames)
{
    switch (format)
    {
        case ma_format_s16:
        {
            ma_int16* pDstS16 = (ma_int16*)pInterleavedPCMFrames;
            ma_uint64 iPCMFrame;
            for (iPCMFrame = 0; iPCMFrame < frameCount; ++iPCMFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < channels; ++iChannel) {
                    const ma_int16* pSrcS16 = (const ma_int16*)ppDeinterleavedPCMFrames[iChannel];
                    pDstS16[iPCMFrame*channels+iChannel] = pSrcS16[iPCMFrame];
                }
            }
        } break;

        case ma_format_f32:
        {
            float* pDstF32 = (float*)pInterleavedPCMFrames;
            ma_uint64 iPCMFrame;
            for (iPCMFrame = 0; iPCMFrame < frameCount; ++iPCMFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < channels; ++iChannel) {
                    const float* pSrcF32 = (const float*)ppDeinterleavedPCMFrames[iChannel];
                    pDstF32[iPCMFrame*channels+iChannel] = pSrcF32[iPCMFrame];
                }
            }
        } break;

        default:
        {
            ma_uint32 sampleSizeInBytes = ma_get_bytes_per_sample(format);
            ma_uint64 iPCMFrame;
            for (iPCMFrame = 0; iPCMFrame < frameCount; ++iPCMFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < channels; ++iChannel) {
                          void* pDst = ma_offset_ptr(pInterleavedPCMFrames, (iPCMFrame*channels+iChannel)*sampleSizeInBytes);
                    const void* pSrc = ma_offset_ptr(ppDeinterleavedPCMFrames[iChannel], iPCMFrame*sampleSizeInBytes);
                    memcpy(pDst, pSrc, sampleSizeInBytes);
                }
            }
        } break;
    }
}

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

        pBQ->pR1->f32 = 0;
        pBQ->pR2->f32 = 0;
    } else {
        pBQ->pR1->s32 = 0;
        pBQ->pR2->s32 = 0;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_biquad_process_pcm_frame_f32__direct_form_2_transposed(ma_biquad* pBQ, float* pY, const float* pX)
{
    ma_uint32 c;
    const ma_uint32 channels = pBQ->channels;
    const float b0 = pBQ->b0.f32;
    const float b1 = pBQ->b1.f32;
    const float b2 = pBQ->b2.f32;
    const float a1 = pBQ->a1.f32;
    const float a2 = pBQ->a2.f32;

    MA_ASSUME(channels > 0);

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

        y  = b0*x        + r1;
        r1 = b1*x - a1*y + r2;
        r2 = b2*x - a2*y;

        pY[c]           = y;
        pBQ->pR1[c].f32 = r1;
        pBQ->pR2[c].f32 = r2;
    }
}

static MA_INLINE void ma_biquad_process_pcm_frame_f32(ma_biquad* pBQ, float* pY, const float* pX)
{
    ma_biquad_process_pcm_frame_f32__direct_form_2_transposed(pBQ, pY, pX);
}

static MA_INLINE void ma_biquad_process_pcm_frame_s16__direct_form_2_transposed(ma_biquad* pBQ, ma_int16* pY, const ma_int16* pX)
{
    ma_uint32 c;
    const ma_uint32 channels = pBQ->channels;
    const ma_int32 b0 = pBQ->b0.s32;
    const ma_int32 b1 = pBQ->b1.s32;
    const ma_int32 b2 = pBQ->b2.s32;
    const ma_int32 a1 = pBQ->a1.s32;
    const ma_int32 a2 = pBQ->a2.s32;

    MA_ASSUME(channels > 0);

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

        y  = (b0*x        + r1) >> MA_BIQUAD_FIXED_POINT_SHIFT;
        r1 = (b1*x - a1*y + r2);
        r2 = (b2*x - a2*y);

        pY[c]           = (ma_int16)ma_clamp(y, -32768, 32767);
        pBQ->pR1[c].s32 = r1;
        pBQ->pR2[c].s32 = r2;
    }
}

static MA_INLINE void ma_biquad_process_pcm_frame_s16(ma_biquad* pBQ, ma_int16* pY, const ma_int16* pX)
{
    ma_biquad_process_pcm_frame_s16__direct_form_2_transposed(pBQ, pY, pX);
}

MA_API ma_result ma_biquad_process_pcm_frames(ma_biquad* pBQ, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint32 n;

    if (pBQ == NULL || pFramesOut == NULL || pFramesIn == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Note that the logic below needs to support in-place filtering. That is, it must support the case where pFramesOut and pFramesIn are the same. */

    if (pBQ->format == ma_format_f32) {
        /* */ float* pY = (      float*)pFramesOut;
        const float* pX = (const float*)pFramesIn;

        for (n = 0; n < frameCount; n += 1) {
            ma_biquad_process_pcm_frame_f32__direct_form_2_transposed(pBQ, pY, pX);
            pY += pBQ->channels;
            pX += pBQ->channels;
        }
    } else if (pBQ->format == ma_format_s16) {
        /* */ ma_int16* pY = (      ma_int16*)pFramesOut;
        const ma_int16* pX = (const ma_int16*)pFramesIn;

        for (n = 0; n < frameCount; n += 1) {
            ma_biquad_process_pcm_frame_s16__direct_form_2_transposed(pBQ, pY, pX);
            pY += pBQ->channels;
            pX += pBQ->channels;
        }
    } else {
        MA_ASSERT(MA_FALSE);
        return MA_INVALID_ARGS; /* Format not supported. Should never hit this because it's checked in ma_biquad_init() and ma_biquad_reinit(). */
    }

    return MA_SUCCESS;
}

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


    if (pLPF->format == ma_format_f32) {
        pLPF->a.f32 = 0;
    } else {
        pLPF->a.s32 = 0;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_lpf1_process_pcm_frame_f32(ma_lpf1* pLPF, float* pY, const float* pX)
{
    ma_uint32 c;
    const ma_uint32 channels = pLPF->channels;
    const float a = pLPF->a.f32;
    const float b = 1 - a;

    MA_ASSUME(channels > 0);
    for (c = 0; c < channels; c += 1) {
        float r1 = pLPF->pR1[c].f32;
        float x  = pX[c];
        float y;

        y = b*x + a*r1;

        pY[c]           = y;
        pLPF->pR1[c].f32 = y;
    }
}

static MA_INLINE void ma_lpf1_process_pcm_frame_s16(ma_lpf1* pLPF, ma_int16* pY, const ma_int16* pX)
{
    ma_uint32 c;
    const ma_uint32 channels = pLPF->channels;
    const ma_int32 a = pLPF->a.s32;
    const ma_int32 b = ((1 << MA_BIQUAD_FIXED_POINT_SHIFT) - a);

    MA_ASSUME(channels > 0);
    for (c = 0; c < channels; c += 1) {
        ma_int32 r1 = pLPF->pR1[c].s32;
        ma_int32 x  = pX[c];
        ma_int32 y;

        y = (b*x + a*r1) >> MA_BIQUAD_FIXED_POINT_SHIFT;

        pY[c]            = (ma_int16)y;
        pLPF->pR1[c].s32 = (ma_int32)y;
    }
}

MA_API ma_result ma_lpf1_process_pcm_frames(ma_lpf1* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint32 n;

    if (pLPF == NULL || pFramesOut == NULL || pFramesIn == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Note that the logic below needs to support in-place filtering. That is, it must support the case where pFramesOut and pFramesIn are the same. */

    if (pLPF->format == ma_format_f32) {
        /* */ float* pY = (      float*)pFramesOut;
        const float* pX = (const float*)pFramesIn;

        for (n = 0; n < frameCount; n += 1) {
            ma_lpf1_process_pcm_frame_f32(pLPF, pY, pX);
            pY += pLPF->channels;
            pX += pLPF->channels;
        }
    } else if (pLPF->format == ma_format_s16) {
        /* */ ma_int16* pY = (      ma_int16*)pFramesOut;
        const ma_int16* pX = (const ma_int16*)pFramesIn;

        for (n = 0; n < frameCount; n += 1) {
            ma_lpf1_process_pcm_frame_s16(pLPF, pY, pX);
            pY += pLPF->channels;
            pX += pLPF->channels;
        }
    } else {
        MA_ASSERT(MA_FALSE);
        return MA_INVALID_ARGS; /* Format not supported. Should never hit this because it's checked in ma_biquad_init() and ma_biquad_reinit(). */
    }

    return MA_SUCCESS;
}

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

{
    if (pLPF == NULL) {
        return MA_INVALID_ARGS;
    }

    ma_biquad_clear_cache(&pLPF->bq);

    return MA_SUCCESS;
}

static MA_INLINE void ma_lpf2_process_pcm_frame_s16(ma_lpf2* pLPF, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pLPF->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_lpf2_process_pcm_frame_f32(ma_lpf2* pLPF, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pLPF->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_lpf2_process_pcm_frames(ma_lpf2* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pLPF == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pLPF->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_lpf2_get_latency(const ma_lpf2* pLPF)
{
    if (pLPF == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pLPF->bq);
}

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

        ma_lpf1_clear_cache(&pLPF->pLPF1[ilpf1]);
    }

    for (ilpf2 = 0; ilpf2 < pLPF->lpf2Count; ilpf2 += 1) {
        ma_lpf2_clear_cache(&pLPF->pLPF2[ilpf2]);
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_lpf_process_pcm_frame_f32(ma_lpf* pLPF, float* pY, const void* pX)
{
    ma_uint32 ilpf1;
    ma_uint32 ilpf2;

    MA_ASSERT(pLPF->format == ma_format_f32);

    MA_COPY_MEMORY(pY, pX, ma_get_bytes_per_frame(pLPF->format, pLPF->channels));

    for (ilpf1 = 0; ilpf1 < pLPF->lpf1Count; ilpf1 += 1) {
        ma_lpf1_process_pcm_frame_f32(&pLPF->pLPF1[ilpf1], pY, pY);
    }

    for (ilpf2 = 0; ilpf2 < pLPF->lpf2Count; ilpf2 += 1) {
        ma_lpf2_process_pcm_frame_f32(&pLPF->pLPF2[ilpf2], pY, pY);
    }
}

static MA_INLINE void ma_lpf_process_pcm_frame_s16(ma_lpf* pLPF, ma_int16* pY, const ma_int16* pX)
{
    ma_uint32 ilpf1;
    ma_uint32 ilpf2;

    MA_ASSERT(pLPF->format == ma_format_s16);

    MA_COPY_MEMORY(pY, pX, ma_get_bytes_per_frame(pLPF->format, pLPF->channels));

    for (ilpf1 = 0; ilpf1 < pLPF->lpf1Count; ilpf1 += 1) {
        ma_lpf1_process_pcm_frame_s16(&pLPF->pLPF1[ilpf1], pY, pY);
    }

    for (ilpf2 = 0; ilpf2 < pLPF->lpf2Count; ilpf2 += 1) {
        ma_lpf2_process_pcm_frame_s16(&pLPF->pLPF2[ilpf2], pY, pY);
    }
}

MA_API ma_result ma_lpf_process_pcm_frames(ma_lpf* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_result result;
    ma_uint32 ilpf1;
    ma_uint32 ilpf2;

    if (pLPF == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Faster path for in-place. */
    if (pFramesOut == pFramesIn) {
        for (ilpf1 = 0; ilpf1 < pLPF->lpf1Count; ilpf1 += 1) {
            result = ma_lpf1_process_pcm_frames(&pLPF->pLPF1[ilpf1], pFramesOut, pFramesOut, frameCount);
            if (result != MA_SUCCESS) {
                return result;
            }
        }

        for (ilpf2 = 0; ilpf2 < pLPF->lpf2Count; ilpf2 += 1) {
            result = ma_lpf2_process_pcm_frames(&pLPF->pLPF2[ilpf2], pFramesOut, pFramesOut, frameCount);
            if (result != MA_SUCCESS) {
                return result;
            }
        }
    }

    /* Slightly slower path for copying. */
    if (pFramesOut != pFramesIn) {
        ma_uint32 iFrame;

        /*  */ if (pLPF->format == ma_format_f32) {
            /* */ float* pFramesOutF32 = (      float*)pFramesOut;
            const float* pFramesInF32  = (const float*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                ma_lpf_process_pcm_frame_f32(pLPF, pFramesOutF32, pFramesInF32);
                pFramesOutF32 += pLPF->channels;
                pFramesInF32  += pLPF->channels;
            }
        } else if (pLPF->format == ma_format_s16) {
            /* */ ma_int16* pFramesOutS16 = (      ma_int16*)pFramesOut;
            const ma_int16* pFramesInS16  = (const ma_int16*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                ma_lpf_process_pcm_frame_s16(pLPF, pFramesOutS16, pFramesInS16);
                pFramesOutS16 += pLPF->channels;
                pFramesInS16  += pLPF->channels;
            }
        } else {
            MA_ASSERT(MA_FALSE);
            return MA_INVALID_OPERATION;    /* Should never hit this. */
        }
    }

    return MA_SUCCESS;

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

    a = ma_expd(-2 * MA_PI_D * pConfig->cutoffFrequency / pConfig->sampleRate);
    if (pConfig->format == ma_format_f32) {
        pHPF->a.f32 = (float)a;
    } else {
        pHPF->a.s32 = ma_biquad_float_to_fp(a);
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_hpf1_process_pcm_frame_f32(ma_hpf1* pHPF, float* pY, const float* pX)
{
    ma_uint32 c;
    const ma_uint32 channels = pHPF->channels;
    const float a = 1 - pHPF->a.f32;
    const float b = 1 - a;

    MA_ASSUME(channels > 0);
    for (c = 0; c < channels; c += 1) {
        float r1 = pHPF->pR1[c].f32;
        float x  = pX[c];
        float y;

        y = b*x - a*r1;

        pY[c]            = y;
        pHPF->pR1[c].f32 = y;
    }
}

static MA_INLINE void ma_hpf1_process_pcm_frame_s16(ma_hpf1* pHPF, ma_int16* pY, const ma_int16* pX)
{
    ma_uint32 c;
    const ma_uint32 channels = pHPF->channels;
    const ma_int32 a = ((1 << MA_BIQUAD_FIXED_POINT_SHIFT) - pHPF->a.s32);
    const ma_int32 b = ((1 << MA_BIQUAD_FIXED_POINT_SHIFT) - a);

    MA_ASSUME(channels > 0);
    for (c = 0; c < channels; c += 1) {
        ma_int32 r1 = pHPF->pR1[c].s32;
        ma_int32 x  = pX[c];
        ma_int32 y;

        y = (b*x - a*r1) >> MA_BIQUAD_FIXED_POINT_SHIFT;

        pY[c]            = (ma_int16)y;
        pHPF->pR1[c].s32 = (ma_int32)y;
    }
}

MA_API ma_result ma_hpf1_process_pcm_frames(ma_hpf1* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint32 n;

    if (pHPF == NULL || pFramesOut == NULL || pFramesIn == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Note that the logic below needs to support in-place filtering. That is, it must support the case where pFramesOut and pFramesIn are the same. */

    if (pHPF->format == ma_format_f32) {
        /* */ float* pY = (      float*)pFramesOut;
        const float* pX = (const float*)pFramesIn;

        for (n = 0; n < frameCount; n += 1) {
            ma_hpf1_process_pcm_frame_f32(pHPF, pY, pX);
            pY += pHPF->channels;
            pX += pHPF->channels;
        }
    } else if (pHPF->format == ma_format_s16) {
        /* */ ma_int16* pY = (      ma_int16*)pFramesOut;
        const ma_int16* pX = (const ma_int16*)pFramesIn;

        for (n = 0; n < frameCount; n += 1) {
            ma_hpf1_process_pcm_frame_s16(pHPF, pY, pX);
            pY += pHPF->channels;
            pX += pHPF->channels;
        }
    } else {
        MA_ASSERT(MA_FALSE);
        return MA_INVALID_ARGS; /* Format not supported. Should never hit this because it's checked in ma_biquad_init() and ma_biquad_reinit(). */
    }

    return MA_SUCCESS;
}

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


    bqConfig = ma_hpf2__get_biquad_config(pConfig);
    result = ma_biquad_reinit(&bqConfig, &pHPF->bq);
    if (result != MA_SUCCESS) {
        return result;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_hpf2_process_pcm_frame_s16(ma_hpf2* pHPF, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pHPF->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_hpf2_process_pcm_frame_f32(ma_hpf2* pHPF, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pHPF->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_hpf2_process_pcm_frames(ma_hpf2* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pHPF == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pHPF->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_hpf2_get_latency(const ma_hpf2* pHPF)
{
    if (pHPF == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pHPF->bq);
}

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

    if (pHPF->_ownsHeap) {
        ma_free(pHPF->_pHeap, pAllocationCallbacks);
    }
}

MA_API ma_result ma_hpf_reinit(const ma_hpf_config* pConfig, ma_hpf* pHPF)
{
    return ma_hpf_reinit__internal(pConfig, NULL, pHPF, /*isNew*/MA_FALSE);
}

MA_API ma_result ma_hpf_process_pcm_frames(ma_hpf* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_result result;
    ma_uint32 ihpf1;
    ma_uint32 ihpf2;

    if (pHPF == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Faster path for in-place. */
    if (pFramesOut == pFramesIn) {
        for (ihpf1 = 0; ihpf1 < pHPF->hpf1Count; ihpf1 += 1) {
            result = ma_hpf1_process_pcm_frames(&pHPF->pHPF1[ihpf1], pFramesOut, pFramesOut, frameCount);
            if (result != MA_SUCCESS) {
                return result;
            }
        }

        for (ihpf2 = 0; ihpf2 < pHPF->hpf2Count; ihpf2 += 1) {
            result = ma_hpf2_process_pcm_frames(&pHPF->pHPF2[ihpf2], pFramesOut, pFramesOut, frameCount);
            if (result != MA_SUCCESS) {
                return result;
            }
        }
    }

    /* Slightly slower path for copying. */
    if (pFramesOut != pFramesIn) {
        ma_uint32 iFrame;

        /*  */ if (pHPF->format == ma_format_f32) {
            /* */ float* pFramesOutF32 = (      float*)pFramesOut;
            const float* pFramesInF32  = (const float*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                MA_COPY_MEMORY(pFramesOutF32, pFramesInF32, ma_get_bytes_per_frame(pHPF->format, pHPF->channels));

                for (ihpf1 = 0; ihpf1 < pHPF->hpf1Count; ihpf1 += 1) {
                    ma_hpf1_process_pcm_frame_f32(&pHPF->pHPF1[ihpf1], pFramesOutF32, pFramesOutF32);
                }

                for (ihpf2 = 0; ihpf2 < pHPF->hpf2Count; ihpf2 += 1) {
                    ma_hpf2_process_pcm_frame_f32(&pHPF->pHPF2[ihpf2], pFramesOutF32, pFramesOutF32);
                }

                pFramesOutF32 += pHPF->channels;
                pFramesInF32  += pHPF->channels;
            }
        } else if (pHPF->format == ma_format_s16) {
            /* */ ma_int16* pFramesOutS16 = (      ma_int16*)pFramesOut;
            const ma_int16* pFramesInS16  = (const ma_int16*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                MA_COPY_MEMORY(pFramesOutS16, pFramesInS16, ma_get_bytes_per_frame(pHPF->format, pHPF->channels));

                for (ihpf1 = 0; ihpf1 < pHPF->hpf1Count; ihpf1 += 1) {
                    ma_hpf1_process_pcm_frame_s16(&pHPF->pHPF1[ihpf1], pFramesOutS16, pFramesOutS16);
                }

                for (ihpf2 = 0; ihpf2 < pHPF->hpf2Count; ihpf2 += 1) {
                    ma_hpf2_process_pcm_frame_s16(&pHPF->pHPF2[ihpf2], pFramesOutS16, pFramesOutS16);
                }

                pFramesOutS16 += pHPF->channels;
                pFramesInS16  += pHPF->channels;
            }
        } else {
            MA_ASSERT(MA_FALSE);
            return MA_INVALID_OPERATION;    /* Should never hit this. */
        }
    }

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


    bqConfig = ma_bpf2__get_biquad_config(pConfig);
    result = ma_biquad_reinit(&bqConfig, &pBPF->bq);
    if (result != MA_SUCCESS) {
        return result;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_bpf2_process_pcm_frame_s16(ma_bpf2* pBPF, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pBPF->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_bpf2_process_pcm_frame_f32(ma_bpf2* pBPF, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pBPF->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_bpf2_process_pcm_frames(ma_bpf2* pBPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pBPF == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pBPF->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_bpf2_get_latency(const ma_bpf2* pBPF)
{
    if (pBPF == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pBPF->bq);
}

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

    if (pBPF->_ownsHeap) {
        ma_free(pBPF->_pHeap, pAllocationCallbacks);
    }
}

MA_API ma_result ma_bpf_reinit(const ma_bpf_config* pConfig, ma_bpf* pBPF)
{
    return ma_bpf_reinit__internal(pConfig, NULL, pBPF, /*isNew*/MA_FALSE);
}

MA_API ma_result ma_bpf_process_pcm_frames(ma_bpf* pBPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_result result;
    ma_uint32 ibpf2;

    if (pBPF == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Faster path for in-place. */
    if (pFramesOut == pFramesIn) {
        for (ibpf2 = 0; ibpf2 < pBPF->bpf2Count; ibpf2 += 1) {
            result = ma_bpf2_process_pcm_frames(&pBPF->pBPF2[ibpf2], pFramesOut, pFramesOut, frameCount);
            if (result != MA_SUCCESS) {
                return result;
            }
        }
    }

    /* Slightly slower path for copying. */
    if (pFramesOut != pFramesIn) {
        ma_uint32 iFrame;

        /*  */ if (pBPF->format == ma_format_f32) {
            /* */ float* pFramesOutF32 = (      float*)pFramesOut;
            const float* pFramesInF32  = (const float*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                MA_COPY_MEMORY(pFramesOutF32, pFramesInF32, ma_get_bytes_per_frame(pBPF->format, pBPF->channels));

                for (ibpf2 = 0; ibpf2 < pBPF->bpf2Count; ibpf2 += 1) {
                    ma_bpf2_process_pcm_frame_f32(&pBPF->pBPF2[ibpf2], pFramesOutF32, pFramesOutF32);
                }

                pFramesOutF32 += pBPF->channels;
                pFramesInF32  += pBPF->channels;
            }
        } else if (pBPF->format == ma_format_s16) {
            /* */ ma_int16* pFramesOutS16 = (      ma_int16*)pFramesOut;
            const ma_int16* pFramesInS16  = (const ma_int16*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                MA_COPY_MEMORY(pFramesOutS16, pFramesInS16, ma_get_bytes_per_frame(pBPF->format, pBPF->channels));

                for (ibpf2 = 0; ibpf2 < pBPF->bpf2Count; ibpf2 += 1) {
                    ma_bpf2_process_pcm_frame_s16(&pBPF->pBPF2[ibpf2], pFramesOutS16, pFramesOutS16);
                }

                pFramesOutS16 += pBPF->channels;
                pFramesInS16  += pBPF->channels;
            }
        } else {
            MA_ASSERT(MA_FALSE);
            return MA_INVALID_OPERATION;    /* Should never hit this. */
        }
    }

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


    bqConfig = ma_notch2__get_biquad_config(pConfig);
    result = ma_biquad_reinit(&bqConfig, &pFilter->bq);
    if (result != MA_SUCCESS) {
        return result;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_notch2_process_pcm_frame_s16(ma_notch2* pFilter, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pFilter->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_notch2_process_pcm_frame_f32(ma_notch2* pFilter, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pFilter->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_notch2_process_pcm_frames(ma_notch2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pFilter == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pFilter->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_notch2_get_latency(const ma_notch2* pFilter)
{
    if (pFilter == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pFilter->bq);
}

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


    bqConfig = ma_peak2__get_biquad_config(pConfig);
    result = ma_biquad_reinit(&bqConfig, &pFilter->bq);
    if (result != MA_SUCCESS) {
        return result;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_peak2_process_pcm_frame_s16(ma_peak2* pFilter, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pFilter->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_peak2_process_pcm_frame_f32(ma_peak2* pFilter, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pFilter->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_peak2_process_pcm_frames(ma_peak2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pFilter == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pFilter->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_peak2_get_latency(const ma_peak2* pFilter)
{
    if (pFilter == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pFilter->bq);
}

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


    bqConfig = ma_loshelf2__get_biquad_config(pConfig);
    result = ma_biquad_reinit(&bqConfig, &pFilter->bq);
    if (result != MA_SUCCESS) {
        return result;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_loshelf2_process_pcm_frame_s16(ma_loshelf2* pFilter, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pFilter->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_loshelf2_process_pcm_frame_f32(ma_loshelf2* pFilter, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pFilter->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_loshelf2_process_pcm_frames(ma_loshelf2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pFilter == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pFilter->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_loshelf2_get_latency(const ma_loshelf2* pFilter)
{
    if (pFilter == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pFilter->bq);
}

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


    bqConfig = ma_hishelf2__get_biquad_config(pConfig);
    result = ma_biquad_reinit(&bqConfig, &pFilter->bq);
    if (result != MA_SUCCESS) {
        return result;
    }

    return MA_SUCCESS;
}

static MA_INLINE void ma_hishelf2_process_pcm_frame_s16(ma_hishelf2* pFilter, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
    ma_biquad_process_pcm_frame_s16(&pFilter->bq, pFrameOut, pFrameIn);
}

static MA_INLINE void ma_hishelf2_process_pcm_frame_f32(ma_hishelf2* pFilter, float* pFrameOut, const float* pFrameIn)
{
    ma_biquad_process_pcm_frame_f32(&pFilter->bq, pFrameOut, pFrameIn);
}

MA_API ma_result ma_hishelf2_process_pcm_frames(ma_hishelf2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pFilter == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_biquad_process_pcm_frames(&pFilter->bq, pFramesOut, pFramesIn, frameCount);
}

MA_API ma_uint32 ma_hishelf2_get_latency(const ma_hishelf2* pFilter)
{
    if (pFilter == NULL) {
        return 0;
    }

    return ma_biquad_get_latency(&pFilter->bq);
}

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

    }

    if (pConfig->decay < 0 || pConfig->decay > 1) {
        return MA_INVALID_ARGS;
    }

    pDelay->config             = *pConfig;
    pDelay->bufferSizeInFrames = pConfig->delayInFrames;
    pDelay->cursor             = 0;

    pDelay->pBuffer = (float*)ma_malloc((size_t)(pDelay->bufferSizeInFrames * ma_get_bytes_per_frame(ma_format_f32, pConfig->channels)), pAllocationCallbacks);
    if (pDelay->pBuffer == NULL) {
        return MA_OUT_OF_MEMORY;
    }

    ma_silence_pcm_frames(pDelay->pBuffer, pDelay->bufferSizeInFrames, ma_format_f32, pConfig->channels);

    return MA_SUCCESS;
}

MA_API void ma_delay_uninit(ma_delay* pDelay, const ma_allocation_callbacks* pAllocationCallbacks)
{
    if (pDelay == NULL) {
        return;
    }

    ma_free(pDelay->pBuffer, pAllocationCallbacks);
}

MA_API ma_result ma_delay_process_pcm_frames(ma_delay* pDelay, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount)
{
    ma_uint32 iFrame;
    ma_uint32 iChannel;
    float* pFramesOutF32 = (float*)pFramesOut;
    const float* pFramesInF32 = (const float*)pFramesIn;

    if (pDelay == NULL || pFramesOut == NULL || pFramesIn == NULL) {
        return MA_INVALID_ARGS;
    }

    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        for (iChannel = 0; iChannel < pDelay->config.channels; iChannel += 1) {
            ma_uint32 iBuffer = (pDelay->cursor * pDelay->config.channels) + iChannel;

            if (pDelay->config.delayStart) {
                /* Delayed start. */

                /* Read */
                pFramesOutF32[iChannel] = pDelay->pBuffer[iBuffer] * pDelay->config.wet;

                /* Feedback */

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

        ma_free(pGainer->_pHeap, pAllocationCallbacks);
    }
}

static float ma_gainer_calculate_current_gain(const ma_gainer* pGainer, ma_uint32 channel)
{
    float a = (float)pGainer->t / pGainer->config.smoothTimeInFrames;
    return ma_mix_f32_fast(pGainer->pOldGains[channel], pGainer->pNewGains[channel], a);
}

MA_API ma_result ma_gainer_process_pcm_frames(ma_gainer* pGainer, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint32 iChannel;
    float* pFramesOutF32 = (float*)pFramesOut;
    const float* pFramesInF32 = (const float*)pFramesIn;

    if (pGainer == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pGainer->t >= pGainer->config.smoothTimeInFrames) {
        /* Fast path. No gain calculation required. */
        ma_copy_and_apply_volume_factor_per_channel_f32(pFramesOutF32, pFramesInF32, frameCount, pGainer->config.channels, pGainer->pNewGains);

        /* Now that some frames have been processed we need to make sure future changes to the gain are interpolated. */
        if (pGainer->t == (ma_uint32)-1) {
            pGainer->t = pGainer->config.smoothTimeInFrames;
        }
    } else {
        /* Slow path. Need to interpolate the gain for each channel individually. */

        /* We can allow the input and output buffers to be null in which case we'll just update the internal timer. */
        if (pFramesOut != NULL && pFramesIn != NULL) {
            float a = (float)pGainer->t / pGainer->config.smoothTimeInFrames;
            float d = 1.0f / pGainer->config.smoothTimeInFrames;
            ma_uint32 channelCount = pGainer->config.channels;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < channelCount; iChannel += 1) {
                    pFramesOutF32[iChannel] = pFramesInF32[iChannel] * ma_mix_f32_fast(pGainer->pOldGains[iChannel], pGainer->pNewGains[iChannel], a);
                }

                pFramesOutF32 += channelCount;
                pFramesInF32  += channelCount;

                a += d;
                if (a > 1) {
                    a = 1;
                }
            }
        }

        pGainer->t = (ma_uint32)ma_min(pGainer->t + frameCount, pGainer->config.smoothTimeInFrames);

    #if 0   /* Reference implementation. */
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            /* We can allow the input and output buffers to be null in which case we'll just update the internal timer. */
            if (pFramesOut != NULL && pFramesIn != NULL) {
                for (iChannel = 0; iChannel < pGainer->config.channels; iChannel += 1) {
                    pFramesOutF32[iFrame*pGainer->config.channels + iChannel] = pFramesInF32[iFrame*pGainer->config.channels + iChannel] * ma_gainer_calculate_current_gain(pGainer, iChannel);
                }
            }

            /* Move interpolation time forward, but don't go beyond our smoothing time. */
            pGainer->t = ma_min(pGainer->t + 1, pGainer->config.smoothTimeInFrames);
        }

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

    }

    pPanner->format   = pConfig->format;
    pPanner->channels = pConfig->channels;
    pPanner->mode     = pConfig->mode;
    pPanner->pan      = pConfig->pan;

    return MA_SUCCESS;
}

static void ma_stereo_balance_pcm_frames_f32(float* pFramesOut, const float* pFramesIn, ma_uint64 frameCount, float pan)
{
    ma_uint64 iFrame;

    if (pan > 0) {
        float factor = 1.0f - pan;
        if (pFramesOut == pFramesIn) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                pFramesOut[iFrame*2 + 0] = pFramesIn[iFrame*2 + 0] * factor;
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                pFramesOut[iFrame*2 + 0] = pFramesIn[iFrame*2 + 0] * factor;
                pFramesOut[iFrame*2 + 1] = pFramesIn[iFrame*2 + 1];
            }
        }
    } else {
        float factor = 1.0f + pan;
        if (pFramesOut == pFramesIn) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                pFramesOut[iFrame*2 + 1] = pFramesIn[iFrame*2 + 1] * factor;
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                pFramesOut[iFrame*2 + 0] = pFramesIn[iFrame*2 + 0];
                pFramesOut[iFrame*2 + 1] = pFramesIn[iFrame*2 + 1] * factor;
            }
        }
    }
}

static void ma_stereo_balance_pcm_frames(void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount, ma_format format, float pan)
{
    if (pan == 0) {
        /* Fast path. No panning required. */
        if (pFramesOut == pFramesIn) {
            /* No-op */
        } else {
            ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, format, 2);
        }

        return;
    }

    switch (format) {
        case ma_format_f32: ma_stereo_balance_pcm_frames_f32((float*)pFramesOut, (float*)pFramesIn, frameCount, pan); break;

        /* Unknown format. Just copy. */
        default:
        {
            ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, format, 2);
        } break;
    }
}


static void ma_stereo_pan_pcm_frames_f32(float* pFramesOut, const float* pFramesIn, ma_uint64 frameCount, float pan)
{
    ma_uint64 iFrame;

    if (pan > 0) {
        float factorL0 = 1.0f - pan;
        float factorL1 = 0.0f + pan;

        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float sample0 = (pFramesIn[iFrame*2 + 0] * factorL0);
            float sample1 = (pFramesIn[iFrame*2 + 0] * factorL1) + pFramesIn[iFrame*2 + 1];

            pFramesOut[iFrame*2 + 0] = sample0;
            pFramesOut[iFrame*2 + 1] = sample1;
        }
    } else {
        float factorR0 = 0.0f - pan;
        float factorR1 = 1.0f + pan;

        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float sample0 = pFramesIn[iFrame*2 + 0] + (pFramesIn[iFrame*2 + 1] * factorR0);
            float sample1 =                           (pFramesIn[iFrame*2 + 1] * factorR1);

            pFramesOut[iFrame*2 + 0] = sample0;
            pFramesOut[iFrame*2 + 1] = sample1;
        }
    }
}

static void ma_stereo_pan_pcm_frames(void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount, ma_format format, float pan)
{
    if (pan == 0) {
        /* Fast path. No panning required. */
        if (pFramesOut == pFramesIn) {
            /* No-op */
        } else {
            ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, format, 2);
        }

        return;
    }

    switch (format) {
        case ma_format_f32: ma_stereo_pan_pcm_frames_f32((float*)pFramesOut, (float*)pFramesIn, frameCount, pan); break;

        /* Unknown format. Just copy. */
        default:
        {
            ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, format, 2);
        } break;
    }
}

MA_API ma_result ma_panner_process_pcm_frames(ma_panner* pPanner, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pPanner == NULL || pFramesOut == NULL || pFramesIn == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pPanner->channels == 2) {
        /* Stereo case. For now assume channel 0 is left and channel right is 1, but should probably add support for a channel map. */
        if (pPanner->mode == ma_pan_mode_balance) {
            ma_stereo_balance_pcm_frames(pFramesOut, pFramesIn, frameCount, pPanner->format, pPanner->pan);
        } else {
            ma_stereo_pan_pcm_frames(pFramesOut, pFramesIn, frameCount, pPanner->format, pPanner->pan);
        }
    } else {
        if (pPanner->channels == 1) {
            /* Panning has no effect on mono streams. */
            ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, pPanner->format, pPanner->channels);
        } else {
            /* For now we're not going to support non-stereo set ups. Not sure how I want to handle this case just yet. */
            ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, pPanner->format, pPanner->channels);
        }
    }

    return MA_SUCCESS;
}

MA_API void ma_panner_set_mode(ma_panner* pPanner, ma_pan_mode mode)
{
    if (pPanner == NULL) {
        return;

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


    pFader->config         = *pConfig;
    pFader->volumeBeg      = 1;
    pFader->volumeEnd      = 1;
    pFader->lengthInFrames = 0;
    pFader->cursorInFrames = 0;

    return MA_SUCCESS;
}

MA_API ma_result ma_fader_process_pcm_frames(ma_fader* pFader, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pFader == NULL) {
        return MA_INVALID_ARGS;
    }

    /*
    For now we need to clamp frameCount so that the cursor never overflows 32-bits. This is required for
    the conversion to a float which we use for the linear interpolation. This might be changed later.
    */
    if (frameCount + pFader->cursorInFrames > UINT_MAX) {
        frameCount = UINT_MAX - pFader->cursorInFrames;
    }

    /* Optimized path if volumeBeg and volumeEnd are equal. */
    if (pFader->volumeBeg == pFader->volumeEnd) {
        if (pFader->volumeBeg == 1) {
            /* Straight copy. */
            ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, pFader->config.format, pFader->config.channels);
        } else {
            /* Copy with volume. */
            ma_copy_and_apply_volume_and_clip_pcm_frames(pFramesOut, pFramesIn, frameCount, pFader->config.format, pFader->config.channels, pFader->volumeEnd);
        }
    } else {
        /* Slower path. Volumes are different, so may need to do an interpolation. */
        if (pFader->cursorInFrames >= pFader->lengthInFrames) {
            /* Fast path. We've gone past the end of the fade period so just apply the end volume to all samples. */
            ma_copy_and_apply_volume_and_clip_pcm_frames(pFramesOut, pFramesIn, frameCount, pFader->config.format, pFader->config.channels, pFader->volumeEnd);
        } else {
            /* Slow path. This is where we do the actual fading. */
            ma_uint64 iFrame;
            ma_uint32 iChannel;

            /* For now we only support f32. Support for other formats will be added later. */
            if (pFader->config.format == ma_format_f32) {
                const float* pFramesInF32  = (const float*)pFramesIn;
                /* */ float* pFramesOutF32 = (      float*)pFramesOut;

                for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                    float a = (ma_uint32)ma_min(pFader->cursorInFrames + iFrame, pFader->lengthInFrames) / (float)((ma_uint32)pFader->lengthInFrames);   /* Safe cast due to the frameCount clamp at the top of this function. */
                    float volume = ma_mix_f32_fast(pFader->volumeBeg, pFader->volumeEnd, a);

                    for (iChannel = 0; iChannel < pFader->config.channels; iChannel += 1) {
                        pFramesOutF32[iFrame*pFader->config.channels + iChannel] = pFramesInF32[iFrame*pFader->config.channels + iChannel] * volume;
                    }
                }
            } else {
                return MA_NOT_IMPLEMENTED;
            }
        }
    }

    pFader->cursorInFrames += frameCount;

    return MA_SUCCESS;
}

MA_API void ma_fader_get_data_format(const ma_fader* pFader, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate)
{
    if (pFader == NULL) {
        return;
    }

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

        return 0.0f;
    }

    /* The current volume depends on the position of the cursor. */
    if (pFader->cursorInFrames == 0) {
        return pFader->volumeBeg;
    } else if (pFader->cursorInFrames >= pFader->lengthInFrames) {
        return pFader->volumeEnd;
    } else {
        /* The cursor is somewhere inside the fading period. We can figure this out with a simple linear interpoluation between volumeBeg and volumeEnd based on our cursor position. */
        return ma_mix_f32_fast(pFader->volumeBeg, pFader->volumeEnd, (ma_uint32)pFader->cursorInFrames / (float)((ma_uint32)pFader->lengthInFrames));    /* Safe cast to uint32 because we clamp it in ma_fader_process_pcm_frames(). */
    }
}





MA_API ma_vec3f ma_vec3f_init_3f(float x, float y, float z)
{
    ma_vec3f v;

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

{
    return ma_vec3f_init_3f(
        a.y*b.z - a.z*b.y,
        a.z*b.x - a.x*b.z,
        a.x*b.y - a.y*b.x
    );
}



static void ma_channel_map_apply_f32(float* pFramesOut, const ma_channel* pChannelMapOut, ma_uint32 channelsOut, const float* pFramesIn, const ma_channel* pChannelMapIn, ma_uint32 channelsIn, ma_uint64 frameCount, ma_channel_mix_mode mode, ma_mono_ex...
static ma_bool32 ma_is_spatial_channel_position(ma_channel channelPosition);


#ifndef MA_DEFAULT_SPEED_OF_SOUND
#define MA_DEFAULT_SPEED_OF_SOUND   343.3f
#endif

/*
These vectors represent the direction that speakers are facing from the center point. They're used
for panning in the spatializer. Must be normalized.

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

        }

        /*printf("d = %f; cutoffInner = %f; cutoffOuter = %f; angularGain = %f\n", d, cutoffInner, cutoffOuter, angularGain);*/
        return angularGain;
    } else {
        /* Inner angle is 360 degrees so no need to do any attenuation. */
        return 1;
    }
}

MA_API ma_result ma_spatializer_process_pcm_frames(ma_spatializer* pSpatializer, ma_spatializer_listener* pListener, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_channel* pChannelMapIn  = pSpatializer->pChannelMapIn;
    ma_channel* pChannelMapOut = pListener->config.pChannelMapOut;

    if (pSpatializer == NULL) {
        return MA_INVALID_ARGS;
    }

    /* If we're not spatializing we need to run an optimized path. */
    if (c89atomic_load_i32(&pSpatializer->attenuationModel) == ma_attenuation_model_none) {
        if (ma_spatializer_listener_is_enabled(pListener)) {
            /* No attenuation is required, but we'll need to do some channel conversion. */
            if (pSpatializer->channelsIn == pSpatializer->channelsOut) {
                ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, ma_format_f32, pSpatializer->channelsIn);
            } else {
                ma_channel_map_apply_f32((float*)pFramesOut, pChannelMapOut, pSpatializer->channelsOut, (const float*)pFramesIn, pChannelMapIn, pSpatializer->channelsIn, frameCount, ma_channel_mix_mode_rectangular, ma_mono_expansion_mode_default);   ...
            }
        } else {
            /* The listener is disabled. Output silence. */
            ma_silence_pcm_frames(pFramesOut, frameCount, ma_format_f32, pSpatializer->channelsOut);
        }

        /*
        We're not doing attenuation so don't bother with doppler for now. I'm not sure if this is
        the correct thinking so might need to review this later.
        */
        pSpatializer->dopplerPitch = 1;
    } else {
        /*
        Let's first determine which listener the sound is closest to. Need to keep in mind that we

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

        */
        for (iChannel = 0; iChannel < channelsOut; iChannel += 1) {
            pSpatializer->pNewChannelGainsOut[iChannel] = gain;
        }

        /*
        Convert to our output channel count. If the listener is disabled we just output silence here. We cannot ignore
        the whole section of code here because we need to update some internal spatialization state.
        */
        if (ma_spatializer_listener_is_enabled(pListener)) {
            ma_channel_map_apply_f32((float*)pFramesOut, pChannelMapOut, channelsOut, (const float*)pFramesIn, pChannelMapIn, channelsIn, frameCount, ma_channel_mix_mode_rectangular, ma_mono_expansion_mode_default);
        } else {
            ma_silence_pcm_frames(pFramesOut, frameCount, ma_format_f32, pSpatializer->channelsOut);
        }

        /*
        Calculate our per-channel gains. We do this based on the normalized relative position of the sound and it's
        relation to the direction of the channel.
        */
        if (distance > 0) {
            ma_vec3f unitPos = relativePos;
            float distanceInv = 1/distance;
            unitPos.x *= distanceInv;

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

                    }
                }
                #endif
            }
        } else {
            /* Assume the sound is right on top of us. Don't do any panning. */
        }

        /* Now we need to apply the volume to each channel. This needs to run through the gainer to ensure we get a smooth volume transition. */
        ma_gainer_set_gains(&pSpatializer->gainer, pSpatializer->pNewChannelGainsOut);
        ma_gainer_process_pcm_frames(&pSpatializer->gainer, pFramesOut, pFramesOut, frameCount);

        /*
        Before leaving we'll want to update our doppler pitch so that the caller can apply some
        pitch shifting if they desire. Note that we need to negate the relative position here
        because the doppler calculation needs to be source-to-listener, but ours is listener-to-
        source.
        */
        if (dopplerFactor > 0) {
            pSpatializer->dopplerPitch = ma_doppler_pitch(ma_vec3f_sub(pListener->position, pSpatializer->position), pSpatializer->velocity, listenerVel, speedOfSound, dopplerFactor);
        } else {

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

    if (pResampler->config.lpfOrder > MA_MAX_FILTER_ORDER) {
        return MA_INVALID_ARGS;
    }

    lpfSampleRate      = (ma_uint32)(ma_max(pResampler->config.sampleRateIn, pResampler->config.sampleRateOut));
    lpfCutoffFrequency = (   double)(ma_min(pResampler->config.sampleRateIn, pResampler->config.sampleRateOut) * 0.5 * pResampler->config.lpfNyquistFactor);

    lpfConfig = ma_lpf_config_init(pResampler->config.format, pResampler->config.channels, lpfSampleRate, lpfCutoffFrequency, pResampler->config.lpfOrder);

    /*
    If the resampler is alreay initialized we don't want to do a fresh initialization of the low-pass filter because it will result in the cached frames
    getting cleared. Instead we re-initialize the filter which will maintain any cached frames.
    */
    if (isResamplerAlreadyInitialized) {
        result = ma_lpf_reinit(&lpfConfig, &pResampler->lpf);
    } else {
        result = ma_lpf_init_preallocated(&lpfConfig, ma_offset_ptr(pHeap, pHeapLayout->lpfOffset), &pResampler->lpf);
    }

    if (result != MA_SUCCESS) {
        return result;
    }

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

        pResampler->x0.s16 = (ma_int16*)ma_offset_ptr(pHeap, heapLayout.x0Offset);
        pResampler->x1.s16 = (ma_int16*)ma_offset_ptr(pHeap, heapLayout.x1Offset);
    }

    /* Setting the rate will set up the filter and time advances for us. */
    result = ma_linear_resampler_set_rate_internal(pResampler, pHeap, &heapLayout, pConfig->sampleRateIn, pConfig->sampleRateOut, /* isResamplerAlreadyInitialized = */ MA_FALSE);
    if (result != MA_SUCCESS) {
        return result;
    }

    pResampler->inTimeInt  = 1;  /* Set this to one to force an input sample to always be loaded for the first output frame. */
    pResampler->inTimeFrac = 0;

    return MA_SUCCESS;
}

MA_API ma_result ma_linear_resampler_init(const ma_linear_resampler_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_linear_resampler* pResampler)
{
    ma_result result;
    size_t heapSizeInBytes;
    void* pHeap;

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


    MA_ASSERT(a <= (1<<shift));

    b = x * ((1<<shift) - a);
    c = y * a;
    r = b + c;

    return (ma_int16)(r >> shift);
}

static void ma_linear_resampler_interpolate_frame_s16(ma_linear_resampler* pResampler, ma_int16* MA_RESTRICT pFrameOut)
{
    ma_uint32 c;
    ma_uint32 a;
    const ma_uint32 channels = pResampler->config.channels;
    const ma_uint32 shift = 12;

    MA_ASSERT(pResampler != NULL);
    MA_ASSERT(pFrameOut  != NULL);

    a = (pResampler->inTimeFrac << shift) / pResampler->config.sampleRateOut;

    MA_ASSUME(channels > 0);
    for (c = 0; c < channels; c += 1) {
        ma_int16 s = ma_linear_resampler_mix_s16(pResampler->x0.s16[c], pResampler->x1.s16[c], a, shift);
        pFrameOut[c] = s;
    }
}


static void ma_linear_resampler_interpolate_frame_f32(ma_linear_resampler* pResampler, float* MA_RESTRICT pFrameOut)
{
    ma_uint32 c;
    float a;
    const ma_uint32 channels = pResampler->config.channels;

    MA_ASSERT(pResampler != NULL);
    MA_ASSERT(pFrameOut  != NULL);

    a = (float)pResampler->inTimeFrac / pResampler->config.sampleRateOut;

    MA_ASSUME(channels > 0);
    for (c = 0; c < channels; c += 1) {
        float s = ma_mix_f32_fast(pResampler->x0.f32[c], pResampler->x1.f32[c], a);
        pFrameOut[c] = s;
    }
}

static ma_result ma_linear_resampler_process_pcm_frames_s16_downsample(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    const ma_int16* pFramesInS16;
    /* */ ma_int16* pFramesOutS16;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;

    MA_ASSERT(pResampler     != NULL);
    MA_ASSERT(pFrameCountIn  != NULL);
    MA_ASSERT(pFrameCountOut != NULL);

    pFramesInS16       = (const ma_int16*)pFramesIn;
    pFramesOutS16      = (      ma_int16*)pFramesOut;
    frameCountIn       = *pFrameCountIn;
    frameCountOut      = *pFrameCountOut;
    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    while (framesProcessedOut < frameCountOut) {
        /* Before interpolating we need to load the buffers. When doing this we need to ensure we run every input sample through the filter. */
        while (pResampler->inTimeInt > 0 && frameCountIn > framesProcessedIn) {
            ma_uint32 iChannel;

            if (pFramesInS16 != NULL) {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.s16[iChannel] = pResampler->x1.s16[iChannel];
                    pResampler->x1.s16[iChannel] = pFramesInS16[iChannel];
                }
                pFramesInS16 += pResampler->config.channels;
            } else {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.s16[iChannel] = pResampler->x1.s16[iChannel];
                    pResampler->x1.s16[iChannel] = 0;
                }
            }

            /* Filter. */
            ma_lpf_process_pcm_frame_s16(&pResampler->lpf, pResampler->x1.s16, pResampler->x1.s16);

            framesProcessedIn     += 1;
            pResampler->inTimeInt -= 1;
        }

        if (pResampler->inTimeInt > 0) {
            break;  /* Ran out of input data. */
        }

        /* Getting here means the frames have been loaded and filtered and we can generate the next output frame. */
        if (pFramesOutS16 != NULL) {
            MA_ASSERT(pResampler->inTimeInt == 0);
            ma_linear_resampler_interpolate_frame_s16(pResampler, pFramesOutS16);

            pFramesOutS16 += pResampler->config.channels;
        }

        framesProcessedOut += 1;

        /* Advance time forward. */
        pResampler->inTimeInt  += pResampler->inAdvanceInt;
        pResampler->inTimeFrac += pResampler->inAdvanceFrac;
        if (pResampler->inTimeFrac >= pResampler->config.sampleRateOut) {
            pResampler->inTimeFrac -= pResampler->config.sampleRateOut;
            pResampler->inTimeInt  += 1;
        }
    }

    *pFrameCountIn  = framesProcessedIn;
    *pFrameCountOut = framesProcessedOut;

    return MA_SUCCESS;
}

static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    const ma_int16* pFramesInS16;
    /* */ ma_int16* pFramesOutS16;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;

    MA_ASSERT(pResampler     != NULL);
    MA_ASSERT(pFrameCountIn  != NULL);
    MA_ASSERT(pFrameCountOut != NULL);

    pFramesInS16       = (const ma_int16*)pFramesIn;
    pFramesOutS16      = (      ma_int16*)pFramesOut;
    frameCountIn       = *pFrameCountIn;
    frameCountOut      = *pFrameCountOut;
    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    while (framesProcessedOut < frameCountOut) {
        /* Before interpolating we need to load the buffers. */
        while (pResampler->inTimeInt > 0 && frameCountIn > framesProcessedIn) {
            ma_uint32 iChannel;

            if (pFramesInS16 != NULL) {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.s16[iChannel] = pResampler->x1.s16[iChannel];
                    pResampler->x1.s16[iChannel] = pFramesInS16[iChannel];
                }
                pFramesInS16 += pResampler->config.channels;
            } else {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.s16[iChannel] = pResampler->x1.s16[iChannel];
                    pResampler->x1.s16[iChannel] = 0;
                }
            }

            framesProcessedIn     += 1;
            pResampler->inTimeInt -= 1;
        }

        if (pResampler->inTimeInt > 0) {
            break;  /* Ran out of input data. */
        }

        /* Getting here means the frames have been loaded and we can generate the next output frame. */
        if (pFramesOutS16 != NULL) {
            MA_ASSERT(pResampler->inTimeInt == 0);
            ma_linear_resampler_interpolate_frame_s16(pResampler, pFramesOutS16);

            /* Filter. */
            ma_lpf_process_pcm_frame_s16(&pResampler->lpf, pFramesOutS16, pFramesOutS16);

            pFramesOutS16 += pResampler->config.channels;
        }

        framesProcessedOut += 1;

        /* Advance time forward. */
        pResampler->inTimeInt  += pResampler->inAdvanceInt;
        pResampler->inTimeFrac += pResampler->inAdvanceFrac;
        if (pResampler->inTimeFrac >= pResampler->config.sampleRateOut) {
            pResampler->inTimeFrac -= pResampler->config.sampleRateOut;
            pResampler->inTimeInt  += 1;
        }
    }

    *pFrameCountIn  = framesProcessedIn;
    *pFrameCountOut = framesProcessedOut;

    return MA_SUCCESS;
}

static ma_result ma_linear_resampler_process_pcm_frames_s16(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    MA_ASSERT(pResampler != NULL);

    if (pResampler->config.sampleRateIn > pResampler->config.sampleRateOut) {
        return ma_linear_resampler_process_pcm_frames_s16_downsample(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    } else {
        return ma_linear_resampler_process_pcm_frames_s16_upsample(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    }
}


static ma_result ma_linear_resampler_process_pcm_frames_f32_downsample(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    const float* pFramesInF32;
    /* */ float* pFramesOutF32;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;

    MA_ASSERT(pResampler     != NULL);
    MA_ASSERT(pFrameCountIn  != NULL);
    MA_ASSERT(pFrameCountOut != NULL);

    pFramesInF32       = (const float*)pFramesIn;
    pFramesOutF32      = (      float*)pFramesOut;
    frameCountIn       = *pFrameCountIn;
    frameCountOut      = *pFrameCountOut;
    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    while (framesProcessedOut < frameCountOut) {
        /* Before interpolating we need to load the buffers. When doing this we need to ensure we run every input sample through the filter. */
        while (pResampler->inTimeInt > 0 && frameCountIn > framesProcessedIn) {
            ma_uint32 iChannel;

            if (pFramesInF32 != NULL) {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.f32[iChannel] = pResampler->x1.f32[iChannel];
                    pResampler->x1.f32[iChannel] = pFramesInF32[iChannel];
                }
                pFramesInF32 += pResampler->config.channels;
            } else {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.f32[iChannel] = pResampler->x1.f32[iChannel];
                    pResampler->x1.f32[iChannel] = 0;
                }
            }

            /* Filter. */
            ma_lpf_process_pcm_frame_f32(&pResampler->lpf, pResampler->x1.f32, pResampler->x1.f32);

            framesProcessedIn     += 1;
            pResampler->inTimeInt -= 1;
        }

        if (pResampler->inTimeInt > 0) {
            break;  /* Ran out of input data. */
        }

        /* Getting here means the frames have been loaded and filtered and we can generate the next output frame. */
        if (pFramesOutF32 != NULL) {
            MA_ASSERT(pResampler->inTimeInt == 0);
            ma_linear_resampler_interpolate_frame_f32(pResampler, pFramesOutF32);

            pFramesOutF32 += pResampler->config.channels;
        }

        framesProcessedOut += 1;

        /* Advance time forward. */
        pResampler->inTimeInt  += pResampler->inAdvanceInt;
        pResampler->inTimeFrac += pResampler->inAdvanceFrac;
        if (pResampler->inTimeFrac >= pResampler->config.sampleRateOut) {
            pResampler->inTimeFrac -= pResampler->config.sampleRateOut;
            pResampler->inTimeInt  += 1;
        }
    }

    *pFrameCountIn  = framesProcessedIn;
    *pFrameCountOut = framesProcessedOut;

    return MA_SUCCESS;
}

static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    const float* pFramesInF32;
    /* */ float* pFramesOutF32;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;

    MA_ASSERT(pResampler     != NULL);
    MA_ASSERT(pFrameCountIn  != NULL);
    MA_ASSERT(pFrameCountOut != NULL);

    pFramesInF32       = (const float*)pFramesIn;
    pFramesOutF32      = (      float*)pFramesOut;
    frameCountIn       = *pFrameCountIn;
    frameCountOut      = *pFrameCountOut;
    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    while (framesProcessedOut < frameCountOut) {
        /* Before interpolating we need to load the buffers. */
        while (pResampler->inTimeInt > 0 && frameCountIn > framesProcessedIn) {
            ma_uint32 iChannel;

            if (pFramesInF32 != NULL) {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.f32[iChannel] = pResampler->x1.f32[iChannel];
                    pResampler->x1.f32[iChannel] = pFramesInF32[iChannel];
                }
                pFramesInF32 += pResampler->config.channels;
            } else {
                for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
                    pResampler->x0.f32[iChannel] = pResampler->x1.f32[iChannel];
                    pResampler->x1.f32[iChannel] = 0;
                }
            }

            framesProcessedIn     += 1;
            pResampler->inTimeInt -= 1;
        }

        if (pResampler->inTimeInt > 0) {
            break;  /* Ran out of input data. */
        }

        /* Getting here means the frames have been loaded and we can generate the next output frame. */
        if (pFramesOutF32 != NULL) {
            MA_ASSERT(pResampler->inTimeInt == 0);
            ma_linear_resampler_interpolate_frame_f32(pResampler, pFramesOutF32);

            /* Filter. */
            ma_lpf_process_pcm_frame_f32(&pResampler->lpf, pFramesOutF32, pFramesOutF32);

            pFramesOutF32 += pResampler->config.channels;
        }

        framesProcessedOut += 1;

        /* Advance time forward. */
        pResampler->inTimeInt  += pResampler->inAdvanceInt;
        pResampler->inTimeFrac += pResampler->inAdvanceFrac;
        if (pResampler->inTimeFrac >= pResampler->config.sampleRateOut) {
            pResampler->inTimeFrac -= pResampler->config.sampleRateOut;
            pResampler->inTimeInt  += 1;
        }
    }

    *pFrameCountIn  = framesProcessedIn;
    *pFrameCountOut = framesProcessedOut;

    return MA_SUCCESS;
}

static ma_result ma_linear_resampler_process_pcm_frames_f32(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    MA_ASSERT(pResampler != NULL);

    if (pResampler->config.sampleRateIn > pResampler->config.sampleRateOut) {
        return ma_linear_resampler_process_pcm_frames_f32_downsample(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    } else {
        return ma_linear_resampler_process_pcm_frames_f32_upsample(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    }
}


MA_API ma_result ma_linear_resampler_process_pcm_frames(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    if (pResampler == NULL) {
        return MA_INVALID_ARGS;
    }

    /*  */ if (pResampler->config.format == ma_format_s16) {
        return ma_linear_resampler_process_pcm_frames_s16(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    } else if (pResampler->config.format == ma_format_f32) {
        return ma_linear_resampler_process_pcm_frames_f32(pResampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    } else {
        /* Should never get here. Getting here means the format is not supported and you didn't check the return value of ma_linear_resampler_init(). */
        MA_ASSERT(MA_FALSE);
        return MA_INVALID_ARGS;
    }
}


MA_API ma_result ma_linear_resampler_set_rate(ma_linear_resampler* pResampler, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut)
{

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


MA_API ma_uint64 ma_linear_resampler_get_output_latency(const ma_linear_resampler* pResampler)
{
    if (pResampler == NULL) {
        return 0;
    }

    return ma_linear_resampler_get_input_latency(pResampler) * pResampler->config.sampleRateOut / pResampler->config.sampleRateIn;
}

MA_API ma_result ma_linear_resampler_get_required_input_frame_count(const ma_linear_resampler* pResampler, ma_uint64 outputFrameCount, ma_uint64* pInputFrameCount)
{
    ma_uint64 inputFrameCount;

    if (pInputFrameCount == NULL) {
        return MA_INVALID_ARGS;
    }

    *pInputFrameCount = 0;

    if (pResampler == NULL) {
        return MA_INVALID_ARGS;
    }

    if (outputFrameCount == 0) {
        return MA_SUCCESS;
    }

    /* Any whole input frames are consumed before the first output frame is generated. */
    inputFrameCount = pResampler->inTimeInt;
    outputFrameCount -= 1;

    /* The rest of the output frames can be calculated in constant time. */
    inputFrameCount += outputFrameCount * pResampler->inAdvanceInt;
    inputFrameCount += (pResampler->inTimeFrac + (outputFrameCount * pResampler->inAdvanceFrac)) / pResampler->config.sampleRateOut;

    *pInputFrameCount = inputFrameCount;

    return MA_SUCCESS;
}

MA_API ma_result ma_linear_resampler_get_expected_output_frame_count(const ma_linear_resampler* pResampler, ma_uint64 inputFrameCount, ma_uint64* pOutputFrameCount)
{
    ma_uint64 outputFrameCount;
    ma_uint64 preliminaryInputFrameCountFromFrac;
    ma_uint64 preliminaryInputFrameCount;

    if (pOutputFrameCount == NULL) {
        return MA_INVALID_ARGS;
    }

    *pOutputFrameCount = 0;

    if (pResampler == NULL) {
        return MA_INVALID_ARGS;
    }

    /*
    The first step is to get a preliminary output frame count. This will either be exactly equal to what we need, or less by 1. We need to
    determine how many input frames will be consumed by this value. If it's greater than our original input frame count it means we won't
    be able to generate an extra frame because we will have run out of input data. Otherwise we will have enough input for the generation
    of an extra output frame. This add-by-one logic is necessary due to how the data loading logic works when processing frames.
    */
    outputFrameCount = (inputFrameCount * pResampler->config.sampleRateOut) / pResampler->config.sampleRateIn;

    /*
    We need to determine how many *whole* input frames will have been processed to generate our preliminary output frame count. This is
    used in the logic below to determine whether or not we need to add an extra output frame.
    */
    preliminaryInputFrameCountFromFrac = (pResampler->inTimeFrac + outputFrameCount*pResampler->inAdvanceFrac) / pResampler->config.sampleRateOut;
    preliminaryInputFrameCount         = (pResampler->inTimeInt  + outputFrameCount*pResampler->inAdvanceInt ) + preliminaryInputFrameCountFromFrac;

    /*
    If the total number of *whole* input frames that would be required to generate our preliminary output frame count is greather than
    the amount of whole input frames we have available as input we need to *not* add an extra output frame as there won't be enough data
    to actually process. Otherwise we need to add the extra output frame.
    */
    if (preliminaryInputFrameCount <= inputFrameCount) {
        outputFrameCount += 1;
    }

    *pOutputFrameCount = outputFrameCount;

    return MA_SUCCESS;
}

MA_API ma_result ma_linear_resampler_reset(ma_linear_resampler* pResampler)
{
    ma_uint32 iChannel;

    if (pResampler == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Timers need to be cleared back to zero. */
    pResampler->inTimeInt  = 1;  /* Set this to one to force an input sample to always be loaded for the first output frame. */
    pResampler->inTimeFrac = 0;

    /* Cached samples need to be cleared. */
    if (pResampler->config.format == ma_format_f32) {
        for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
            pResampler->x0.f32[iChannel] = 0;
            pResampler->x1.f32[iChannel] = 0;
        }
    } else {
        for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {

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

{
    (void)pUserData;

    ma_linear_resampler_uninit((ma_linear_resampler*)pBackend, pAllocationCallbacks);
}

static ma_result ma_resampling_backend_process__linear(void* pUserData, ma_resampling_backend* pBackend, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    (void)pUserData;

    return ma_linear_resampler_process_pcm_frames((ma_linear_resampler*)pBackend, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
}

static ma_result ma_resampling_backend_set_rate__linear(void* pUserData, ma_resampling_backend* pBackend, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut)
{
    (void)pUserData;

    return ma_linear_resampler_set_rate((ma_linear_resampler*)pBackend, sampleRateIn, sampleRateOut);
}

static ma_uint64 ma_resampling_backend_get_input_latency__linear(void* pUserData, const ma_resampling_backend* pBackend)

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

    return ma_linear_resampler_get_input_latency((const ma_linear_resampler*)pBackend);
}

static ma_uint64 ma_resampling_backend_get_output_latency__linear(void* pUserData, const ma_resampling_backend* pBackend)
{
    (void)pUserData;

    return ma_linear_resampler_get_output_latency((const ma_linear_resampler*)pBackend);
}

static ma_result ma_resampling_backend_get_required_input_frame_count__linear(void* pUserData, const ma_resampling_backend* pBackend, ma_uint64 outputFrameCount, ma_uint64* pInputFrameCount)
{
    (void)pUserData;

    return ma_linear_resampler_get_required_input_frame_count((const ma_linear_resampler*)pBackend, outputFrameCount, pInputFrameCount);
}

static ma_result ma_resampling_backend_get_expected_output_frame_count__linear(void* pUserData, const ma_resampling_backend* pBackend, ma_uint64 inputFrameCount, ma_uint64* pOutputFrameCount)
{
    (void)pUserData;

    return ma_linear_resampler_get_expected_output_frame_count((const ma_linear_resampler*)pBackend, inputFrameCount, pOutputFrameCount);
}

static ma_result ma_resampling_backend_reset__linear(void* pUserData, ma_resampling_backend* pBackend)
{
    (void)pUserData;

    return ma_linear_resampler_reset((ma_linear_resampler*)pBackend);
}

static ma_resampling_backend_vtable g_ma_linear_resampler_vtable =
{
    ma_resampling_backend_get_heap_size__linear,
    ma_resampling_backend_init__linear,
    ma_resampling_backend_uninit__linear,
    ma_resampling_backend_process__linear,
    ma_resampling_backend_set_rate__linear,
    ma_resampling_backend_get_input_latency__linear,
    ma_resampling_backend_get_output_latency__linear,
    ma_resampling_backend_get_required_input_frame_count__linear,
    ma_resampling_backend_get_expected_output_frame_count__linear,
    ma_resampling_backend_reset__linear
};



MA_API ma_resampler_config ma_resampler_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut, ma_resample_algorithm algorithm)
{
    ma_resampler_config config;

    MA_ZERO_OBJECT(&config);

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

        return;
    }

    pResampler->pBackendVTable->onUninit(pResampler->pBackendUserData, pResampler->pBackend, pAllocationCallbacks);

    if (pResampler->_ownsHeap) {
        ma_free(pResampler->_pHeap, pAllocationCallbacks);
    }
}

MA_API ma_result ma_resampler_process_pcm_frames(ma_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    if (pResampler == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pFrameCountOut == NULL && pFrameCountIn == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pResampler->pBackendVTable == NULL || pResampler->pBackendVTable->onProcess == NULL) {

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

        return 0;
    }

    if (pResampler->pBackendVTable == NULL || pResampler->pBackendVTable->onGetOutputLatency == NULL) {
        return 0;
    }

    return pResampler->pBackendVTable->onGetOutputLatency(pResampler->pBackendUserData, pResampler->pBackend);
}

MA_API ma_result ma_resampler_get_required_input_frame_count(const ma_resampler* pResampler, ma_uint64 outputFrameCount, ma_uint64* pInputFrameCount)
{
    if (pInputFrameCount == NULL) {
        return MA_INVALID_ARGS;
    }

    *pInputFrameCount = 0;

    if (pResampler == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pResampler->pBackendVTable == NULL || pResampler->pBackendVTable->onGetRequiredInputFrameCount == NULL) {
        return MA_NOT_IMPLEMENTED;
    }

    return pResampler->pBackendVTable->onGetRequiredInputFrameCount(pResampler->pBackendUserData, pResampler->pBackend, outputFrameCount, pInputFrameCount);
}

MA_API ma_result ma_resampler_get_expected_output_frame_count(const ma_resampler* pResampler, ma_uint64 inputFrameCount, ma_uint64* pOutputFrameCount)
{
    if (pOutputFrameCount == NULL) {
        return MA_INVALID_ARGS;
    }

    *pOutputFrameCount = 0;

    if (pResampler == NULL) {
        return MA_INVALID_ARGS;
    }

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


                default: break;
            }
        }
    }

    return MA_SUCCESS;
}


static void ma_channel_map_apply_shuffle_table_u8(ma_uint8* pFramesOut, ma_uint32 channelsOut, const ma_uint8* pFramesIn, ma_uint32 channelsIn, ma_uint64 frameCount, const ma_uint8* pShuffleTable)
{
    ma_uint64 iFrame;
    ma_uint32 iChannelOut;

    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
            ma_uint8 iChannelIn = pShuffleTable[iChannelOut];
            if (iChannelIn < channelsIn) {  /* For safety, and to deal with MA_CHANNEL_INDEX_NULL. */
                pFramesOut[iChannelOut] = pFramesIn[iChannelIn];
            } else {
                pFramesOut[iChannelOut] = 0;
            }
        }

        pFramesOut += channelsOut;
        pFramesIn  += channelsIn;
    }
}

static void ma_channel_map_apply_shuffle_table_s16(ma_int16* pFramesOut, ma_uint32 channelsOut, const ma_int16* pFramesIn, ma_uint32 channelsIn, ma_uint64 frameCount, const ma_uint8* pShuffleTable)
{
    ma_uint64 iFrame;
    ma_uint32 iChannelOut;

    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
            ma_uint8 iChannelIn = pShuffleTable[iChannelOut];
            if (iChannelIn < channelsIn) {  /* For safety, and to deal with MA_CHANNEL_INDEX_NULL. */
                pFramesOut[iChannelOut] = pFramesIn[iChannelIn];
            } else {
                pFramesOut[iChannelOut] = 0;
            }
        }

        pFramesOut += channelsOut;
        pFramesIn  += channelsIn;
    }
}

static void ma_channel_map_apply_shuffle_table_s24(ma_uint8* pFramesOut, ma_uint32 channelsOut, const ma_uint8* pFramesIn, ma_uint32 channelsIn, ma_uint64 frameCount, const ma_uint8* pShuffleTable)
{
    ma_uint64 iFrame;
    ma_uint32 iChannelOut;

    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
            ma_uint8 iChannelIn = pShuffleTable[iChannelOut];
            if (iChannelIn < channelsIn) {  /* For safety, and to deal with MA_CHANNEL_INDEX_NULL. */
                pFramesOut[iChannelOut*3 + 0] = pFramesIn[iChannelIn*3 + 0];
                pFramesOut[iChannelOut*3 + 1] = pFramesIn[iChannelIn*3 + 1];
                pFramesOut[iChannelOut*3 + 2] = pFramesIn[iChannelIn*3 + 2];
            } else {
                pFramesOut[iChannelOut*3 + 0] = 0;
            }   pFramesOut[iChannelOut*3 + 1] = 0;
        }       pFramesOut[iChannelOut*3 + 2] = 0;

        pFramesOut += channelsOut*3;
        pFramesIn  += channelsIn*3;
    }
}

static void ma_channel_map_apply_shuffle_table_s32(ma_int32* pFramesOut, ma_uint32 channelsOut, const ma_int32* pFramesIn, ma_uint32 channelsIn, ma_uint64 frameCount, const ma_uint8* pShuffleTable)
{
    ma_uint64 iFrame;
    ma_uint32 iChannelOut;

    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
            ma_uint8 iChannelIn = pShuffleTable[iChannelOut];
            if (iChannelIn < channelsIn) {  /* For safety, and to deal with MA_CHANNEL_INDEX_NULL. */
                pFramesOut[iChannelOut] = pFramesIn[iChannelIn];
            } else {
                pFramesOut[iChannelOut] = 0;
            }
        }

        pFramesOut += channelsOut;
        pFramesIn  += channelsIn;
    }
}

static void ma_channel_map_apply_shuffle_table_f32(float* pFramesOut, ma_uint32 channelsOut, const float* pFramesIn, ma_uint32 channelsIn, ma_uint64 frameCount, const ma_uint8* pShuffleTable)
{
    ma_uint64 iFrame;
    ma_uint32 iChannelOut;

    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
        for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
            ma_uint8 iChannelIn = pShuffleTable[iChannelOut];
            if (iChannelIn < channelsIn) {  /* For safety, and to deal with MA_CHANNEL_INDEX_NULL. */
                pFramesOut[iChannelOut] = pFramesIn[iChannelIn];
            } else {
                pFramesOut[iChannelOut] = 0;
            }
        }

        pFramesOut += channelsOut;
        pFramesIn  += channelsIn;
    }
}

static ma_result ma_channel_map_apply_shuffle_table(void* pFramesOut, ma_uint32 channelsOut, const void* pFramesIn, ma_uint32 channelsIn, ma_uint64 frameCount, const ma_uint8* pShuffleTable, ma_format format)
{
    if (pFramesOut == NULL || pFramesIn == NULL || channelsOut == 0 || pShuffleTable == NULL) {
        return MA_INVALID_ARGS;
    }

    switch (format)
    {
        case ma_format_u8:
        {
            ma_channel_map_apply_shuffle_table_u8((ma_uint8*)pFramesOut, channelsOut, (const ma_uint8*)pFramesIn, channelsIn, frameCount, pShuffleTable);
        } break;

        case ma_format_s16:
        {
            ma_channel_map_apply_shuffle_table_s16((ma_int16*)pFramesOut, channelsOut, (const ma_int16*)pFramesIn, channelsIn, frameCount, pShuffleTable);
        } break;

        case ma_format_s24:
        {
            ma_channel_map_apply_shuffle_table_s24((ma_uint8*)pFramesOut, channelsOut, (const ma_uint8*)pFramesIn, channelsIn, frameCount, pShuffleTable);
        } break;

        case ma_format_s32:
        {
            ma_channel_map_apply_shuffle_table_s32((ma_int32*)pFramesOut, channelsOut, (const ma_int32*)pFramesIn, channelsIn, frameCount, pShuffleTable);
        } break;

        case ma_format_f32:
        {
            ma_channel_map_apply_shuffle_table_f32((float*)pFramesOut, channelsOut, (const float*)pFramesIn, channelsIn, frameCount, pShuffleTable);
        } break;

        default: return MA_INVALID_ARGS;    /* Unknown format. */
    }

    return MA_SUCCESS;
}

static ma_result ma_channel_map_apply_mono_out_f32(float* pFramesOut, const float* pFramesIn, const ma_channel* pChannelMapIn, ma_uint32 channelsIn, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint32 iChannelIn;
    ma_uint32 accumulationCount;

    if (pFramesOut == NULL || pFramesIn == NULL || channelsIn == 0) {
        return MA_INVALID_ARGS;
    }

    /* In this case the output stream needs to be the average of all channels, ignoring NONE. */

    /* A quick pre-processing step to get the accumulation counter since we're ignoring NONE channels. */
    accumulationCount = 0;
    for (iChannelIn = 0; iChannelIn < channelsIn; iChannelIn += 1) {
        if (ma_channel_map_get_channel(pChannelMapIn, channelsIn, iChannelIn) != MA_CHANNEL_NONE) {
            accumulationCount += 1;
        }
    }

    if (accumulationCount > 0) {    /* <-- Prevent a division by zero. */
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float accumulation = 0;

            for (iChannelIn = 0; iChannelIn < channelsIn; iChannelIn += 1) {
                ma_channel channelIn = ma_channel_map_get_channel(pChannelMapIn, channelsIn, iChannelIn);
                if (channelIn != MA_CHANNEL_NONE) {
                    accumulation += pFramesIn[iChannelIn];
                }
            }

            pFramesOut[0] = accumulation / accumulationCount;
            pFramesOut += 1;
            pFramesIn  += channelsIn;
        }
    } else {
        ma_silence_pcm_frames(pFramesOut, frameCount, ma_format_f32, 1);
    }

    return MA_SUCCESS;
}

static ma_result ma_channel_map_apply_mono_in_f32(float* pFramesOut, const ma_channel* pChannelMapOut, ma_uint32 channelsOut, const float* pFramesIn, ma_uint64 frameCount, ma_mono_expansion_mode monoExpansionMode)
{
    ma_uint64 iFrame;
    ma_uint32 iChannelOut;

    if (pFramesOut == NULL || channelsOut == 0 || pFramesIn == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Note that the MA_CHANNEL_NONE channel must be ignored in all cases. */
    switch (monoExpansionMode)

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


            for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
                ma_channel channelOut = ma_channel_map_get_channel(pChannelMapOut, channelsOut, iChannelOut);
                if (channelOut != MA_CHANNEL_NONE) {
                    validChannelCount += 1;
                }
            }

            weight = 1.0f / validChannelCount;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
                    ma_channel channelOut = ma_channel_map_get_channel(pChannelMapOut, channelsOut, iChannelOut);
                    if (channelOut != MA_CHANNEL_NONE) {
                        pFramesOut[iChannelOut] = pFramesIn[0] * weight;
                    }
                }

                pFramesOut += channelsOut;
                pFramesIn  += 1;
            }

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

                        iChannelLeft  = iChannelOut;
                    }
                    if (channelOut == MA_CHANNEL_FRONT_RIGHT) {
                        iChannelRight = iChannelOut;
                    }
                }


                if (iChannelLeft != (ma_uint32)-1 && iChannelRight != (ma_uint32)-1) {
                    /* We found our stereo channels so we can duplicate the signal across those channels. */
                    for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                        for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
                            ma_channel channelOut = ma_channel_map_get_channel(pChannelMapOut, channelsOut, iChannelOut);
                            if (channelOut != MA_CHANNEL_NONE) {
                                if (iChannelOut == iChannelLeft || iChannelOut == iChannelRight) {
                                    pFramesOut[iChannelOut] = pFramesIn[0];
                                } else {
                                    pFramesOut[iChannelOut] = 0.0f;
                                }
                            }
                        }

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

                /* Fallthrough. Does not have stereo channels. */
                goto default_handler;
            }
        };  /* Fallthrough. See comments above. */

        case ma_mono_expansion_mode_duplicate:
        default:
        {
            default_handler:
            {
                for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                    for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
                        ma_channel channelOut = ma_channel_map_get_channel(pChannelMapOut, channelsOut, iChannelOut);
                        if (channelOut != MA_CHANNEL_NONE) {
                            pFramesOut[iChannelOut] = pFramesIn[0];
                        }
                    }

                    pFramesOut += channelsOut;
                    pFramesIn  += 1;
                }
            }
        } break;
    }

    return MA_SUCCESS;
}

static void ma_channel_map_apply_f32(float* pFramesOut, const ma_channel* pChannelMapOut, ma_uint32 channelsOut, const float* pFramesIn, const ma_channel* pChannelMapIn, ma_uint32 channelsIn, ma_uint64 frameCount, ma_channel_mix_mode mode, ma_mono_ex...
{
    ma_channel_conversion_path conversionPath = ma_channel_map_get_conversion_path(pChannelMapIn, channelsIn, pChannelMapOut, channelsOut, mode);

    /* Optimized Path: Passthrough */
    if (conversionPath == ma_channel_conversion_path_passthrough) {
        ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, ma_format_f32, channelsOut);
        return;
    }

    /* Special Path: Mono Output. */
    if (conversionPath == ma_channel_conversion_path_mono_out) {
        ma_channel_map_apply_mono_out_f32(pFramesOut, pFramesIn, pChannelMapIn, channelsIn, frameCount);
        return;
    }

    /* Special Path: Mono Input. */
    if (conversionPath == ma_channel_conversion_path_mono_in) {
        ma_channel_map_apply_mono_in_f32(pFramesOut, pChannelMapOut, channelsOut, pFramesIn, frameCount, monoExpansionMode);
        return;
    }

    /* Getting here means we aren't running on an optimized conversion path. */
    if (channelsOut <= MA_MAX_CHANNELS) {
        ma_result result;

        if (mode == ma_channel_mix_mode_simple) {
            ma_channel shuffleTable[MA_MAX_CHANNELS];

            result = ma_channel_map_build_shuffle_table(pChannelMapIn, channelsIn, pChannelMapOut, channelsOut, shuffleTable);
            if (result != MA_SUCCESS) {
                return;
            }

            result = ma_channel_map_apply_shuffle_table(pFramesOut, channelsOut, pFramesIn, channelsIn, frameCount, shuffleTable, ma_format_f32);
            if (result != MA_SUCCESS) {
                return;
            }
        } else {
            ma_uint32 iFrame;
            ma_uint32 iChannelOut;
            ma_uint32 iChannelIn;
            float weights[32][32];  /* Do not use MA_MAX_CHANNELS here! */

            /*

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

            if (channelsIn <= ma_countof(weights) && channelsOut <= ma_countof(weights)) {
                /* Pre-compute weights. */
                for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
                    ma_channel channelOut = ma_channel_map_get_channel(pChannelMapOut, channelsOut, iChannelOut);
                    for (iChannelIn = 0; iChannelIn < channelsIn; iChannelIn += 1) {
                        ma_channel channelIn = ma_channel_map_get_channel(pChannelMapIn, channelsIn, iChannelIn);
                        weights[iChannelOut][iChannelIn] = ma_calculate_channel_position_rectangular_weight(channelOut, channelIn);
                    }
                }

                for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                    for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
                        float accumulation = 0;

                        for (iChannelIn = 0; iChannelIn < channelsIn; iChannelIn += 1) {
                            accumulation += pFramesIn[iChannelIn] * weights[iChannelOut][iChannelIn];
                        }

                        pFramesOut[iChannelOut] = accumulation;
                    }

                    pFramesOut += channelsOut;
                    pFramesIn  += channelsIn;
                }
            } else {
                /* Cannot pre-compute weights because not enough room in stack-allocated buffer. */
                for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                    for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
                        float accumulation = 0;
                        ma_channel channelOut = ma_channel_map_get_channel(pChannelMapOut, channelsOut, iChannelOut);

                        for (iChannelIn = 0; iChannelIn < channelsIn; iChannelIn += 1) {
                            ma_channel channelIn = ma_channel_map_get_channel(pChannelMapIn, channelsIn, iChannelIn);
                            accumulation += pFramesIn[iChannelIn] * ma_calculate_channel_position_rectangular_weight(channelOut, channelIn);
                        }

                        pFramesOut[iChannelOut] = accumulation;
                    }

                    pFramesOut += channelsOut;
                    pFramesIn  += channelsIn;
                }
            }
        }
    } else {
        /* Fall back to silence. If you hit this, what are you doing with so many channels?! */
        ma_silence_pcm_frames(pFramesOut, frameCount, ma_format_f32, channelsOut);
    }
}


typedef struct
{
    size_t sizeInBytes;
    size_t channelMapInOffset;
    size_t channelMapOutOffset;
    size_t shuffleTableOffset;

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

{
    if (pConverter == NULL) {
        return;
    }

    if (pConverter->_ownsHeap) {
        ma_free(pConverter->_pHeap, pAllocationCallbacks);
    }
}

static ma_result ma_channel_converter_process_pcm_frames__passthrough(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pFramesOut != NULL);
    MA_ASSERT(pFramesIn  != NULL);

    ma_copy_memory_64(pFramesOut, pFramesIn, frameCount * ma_get_bytes_per_frame(pConverter->format, pConverter->channelsOut));
    return MA_SUCCESS;
}

static ma_result ma_channel_converter_process_pcm_frames__shuffle(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pFramesOut != NULL);
    MA_ASSERT(pFramesIn  != NULL);
    MA_ASSERT(pConverter->channelsIn == pConverter->channelsOut);

    return ma_channel_map_apply_shuffle_table(pFramesOut, pConverter->channelsOut, pFramesIn, pConverter->channelsIn, frameCount, pConverter->pShuffleTable, pConverter->format);
}

static ma_result ma_channel_converter_process_pcm_frames__mono_in(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint64 iFrame;

    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pFramesOut != NULL);
    MA_ASSERT(pFramesIn  != NULL);
    MA_ASSERT(pConverter->channelsIn == 1);

    switch (pConverter->format)
    {
        case ma_format_u8:
        {
            /* */ ma_uint8* pFramesOutU8 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInU8  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < pConverter->channelsOut; iChannel += 1) {
                    pFramesOutU8[iFrame*pConverter->channelsOut + iChannel] = pFramesInU8[iFrame];
                }
            }
        } break;

        case ma_format_s16:
        {
            /* */ ma_int16* pFramesOutS16 = (      ma_int16*)pFramesOut;
            const ma_int16* pFramesInS16  = (const ma_int16*)pFramesIn;

            if (pConverter->channelsOut == 2) {
                for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                    pFramesOutS16[iFrame*2 + 0] = pFramesInS16[iFrame];
                    pFramesOutS16[iFrame*2 + 1] = pFramesInS16[iFrame];
                }
            } else {
                for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                    ma_uint32 iChannel;
                    for (iChannel = 0; iChannel < pConverter->channelsOut; iChannel += 1) {
                        pFramesOutS16[iFrame*pConverter->channelsOut + iChannel] = pFramesInS16[iFrame];
                    }
                }
            }
        } break;

        case ma_format_s24:
        {
            /* */ ma_uint8* pFramesOutS24 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInS24  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < pConverter->channelsOut; iChannel += 1) {
                    ma_uint64 iSampleOut = iFrame*pConverter->channelsOut + iChannel;
                    ma_uint64 iSampleIn  = iFrame;
                    pFramesOutS24[iSampleOut*3 + 0] = pFramesInS24[iSampleIn*3 + 0];
                    pFramesOutS24[iSampleOut*3 + 1] = pFramesInS24[iSampleIn*3 + 1];
                    pFramesOutS24[iSampleOut*3 + 2] = pFramesInS24[iSampleIn*3 + 2];
                }
            }
        } break;

        case ma_format_s32:
        {
            /* */ ma_int32* pFramesOutS32 = (      ma_int32*)pFramesOut;
            const ma_int32* pFramesInS32  = (const ma_int32*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                ma_uint32 iChannel;
                for (iChannel = 0; iChannel < pConverter->channelsOut; iChannel += 1) {
                    pFramesOutS32[iFrame*pConverter->channelsOut + iChannel] = pFramesInS32[iFrame];
                }
            }
        } break;

        case ma_format_f32:
        {
            /* */ float* pFramesOutF32 = (      float*)pFramesOut;
            const float* pFramesInF32  = (const float*)pFramesIn;

            if (pConverter->channelsOut == 2) {
                for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                    pFramesOutF32[iFrame*2 + 0] = pFramesInF32[iFrame];
                    pFramesOutF32[iFrame*2 + 1] = pFramesInF32[iFrame];
                }
            } else {
                for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                    ma_uint32 iChannel;
                    for (iChannel = 0; iChannel < pConverter->channelsOut; iChannel += 1) {
                        pFramesOutF32[iFrame*pConverter->channelsOut + iChannel] = pFramesInF32[iFrame];
                    }
                }
            }
        } break;

        default: return MA_INVALID_OPERATION;   /* Unknown format. */
    }

    return MA_SUCCESS;
}

static ma_result ma_channel_converter_process_pcm_frames__mono_out(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint32 iChannel;

    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pFramesOut != NULL);
    MA_ASSERT(pFramesIn  != NULL);
    MA_ASSERT(pConverter->channelsOut == 1);

    switch (pConverter->format)
    {
        case ma_format_u8:
        {
            /* */ ma_uint8* pFramesOutU8 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInU8  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                ma_int32 t = 0;
                for (iChannel = 0; iChannel < pConverter->channelsIn; iChannel += 1) {
                    t += ma_pcm_sample_u8_to_s16_no_scale(pFramesInU8[iFrame*pConverter->channelsIn + iChannel]);
                }

                pFramesOutU8[iFrame] = ma_clip_u8(t / pConverter->channelsOut);
            }
        } break;

        case ma_format_s16:
        {
            /* */ ma_int16* pFramesOutS16 = (      ma_int16*)pFramesOut;
            const ma_int16* pFramesInS16  = (const ma_int16*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                ma_int32 t = 0;
                for (iChannel = 0; iChannel < pConverter->channelsIn; iChannel += 1) {
                    t += pFramesInS16[iFrame*pConverter->channelsIn + iChannel];
                }

                pFramesOutS16[iFrame] = (ma_int16)(t / pConverter->channelsIn);
            }
        } break;

        case ma_format_s24:
        {
            /* */ ma_uint8* pFramesOutS24 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInS24  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                ma_int64 t = 0;
                for (iChannel = 0; iChannel < pConverter->channelsIn; iChannel += 1) {
                    t += ma_pcm_sample_s24_to_s32_no_scale(&pFramesInS24[(iFrame*pConverter->channelsIn + iChannel)*3]);
                }

                ma_pcm_sample_s32_to_s24_no_scale(t / pConverter->channelsIn, &pFramesOutS24[iFrame*3]);
            }
        } break;

        case ma_format_s32:
        {
            /* */ ma_int32* pFramesOutS32 = (      ma_int32*)pFramesOut;
            const ma_int32* pFramesInS32  = (const ma_int32*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                ma_int64 t = 0;
                for (iChannel = 0; iChannel < pConverter->channelsIn; iChannel += 1) {
                    t += pFramesInS32[iFrame*pConverter->channelsIn + iChannel];
                }

                pFramesOutS32[iFrame] = (ma_int32)(t / pConverter->channelsIn);
            }
        } break;

        case ma_format_f32:
        {
            /* */ float* pFramesOutF32 = (      float*)pFramesOut;
            const float* pFramesInF32  = (const float*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; ++iFrame) {
                float t = 0;
                for (iChannel = 0; iChannel < pConverter->channelsIn; iChannel += 1) {
                    t += pFramesInF32[iFrame*pConverter->channelsIn + iChannel];
                }

                pFramesOutF32[iFrame] = t / pConverter->channelsIn;
            }
        } break;

        default: return MA_INVALID_OPERATION;   /* Unknown format. */
    }

    return MA_SUCCESS;
}

static ma_result ma_channel_converter_process_pcm_frames__weights(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    ma_uint32 iFrame;
    ma_uint32 iChannelIn;
    ma_uint32 iChannelOut;

    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pFramesOut != NULL);
    MA_ASSERT(pFramesIn  != NULL);

    /* This is the more complicated case. Each of the output channels is accumulated with 0 or more input channels. */

    /* Clear. */
    ma_zero_memory_64(pFramesOut, frameCount * ma_get_bytes_per_frame(pConverter->format, pConverter->channelsOut));

    /* Accumulate. */
    switch (pConverter->format)
    {
        case ma_format_u8:
        {
            /* */ ma_uint8* pFramesOutU8 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInU8  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
                        ma_int16 u8_O = ma_pcm_sample_u8_to_s16_no_scale(pFramesOutU8[iFrame*pConverter->channelsOut + iChannelOut]);
                        ma_int16 u8_I = ma_pcm_sample_u8_to_s16_no_scale(pFramesInU8 [iFrame*pConverter->channelsIn  + iChannelIn ]);
                        ma_int32 s    = (ma_int32)ma_clamp(u8_O + ((u8_I * pConverter->weights.s16[iChannelIn][iChannelOut]) >> MA_CHANNEL_CONVERTER_FIXED_POINT_SHIFT), -128, 127);
                        pFramesOutU8[iFrame*pConverter->channelsOut + iChannelOut] = ma_clip_u8((ma_int16)s);
                    }
                }
            }
        } break;

        case ma_format_s16:
        {
            /* */ ma_int16* pFramesOutS16 = (      ma_int16*)pFramesOut;
            const ma_int16* pFramesInS16  = (const ma_int16*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
                        ma_int32 s = pFramesOutS16[iFrame*pConverter->channelsOut + iChannelOut];
                        s += (pFramesInS16[iFrame*pConverter->channelsIn + iChannelIn] * pConverter->weights.s16[iChannelIn][iChannelOut]) >> MA_CHANNEL_CONVERTER_FIXED_POINT_SHIFT;

                        pFramesOutS16[iFrame*pConverter->channelsOut + iChannelOut] = (ma_int16)ma_clamp(s, -32768, 32767);
                    }
                }
            }
        } break;

        case ma_format_s24:
        {
            /* */ ma_uint8* pFramesOutS24 = (      ma_uint8*)pFramesOut;
            const ma_uint8* pFramesInS24  = (const ma_uint8*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
                        ma_int64 s24_O = ma_pcm_sample_s24_to_s32_no_scale(&pFramesOutS24[(iFrame*pConverter->channelsOut + iChannelOut)*3]);
                        ma_int64 s24_I = ma_pcm_sample_s24_to_s32_no_scale(&pFramesInS24 [(iFrame*pConverter->channelsIn  + iChannelIn )*3]);
                        ma_int64 s24   = (ma_int32)ma_clamp(s24_O + ((s24_I * pConverter->weights.s16[iChannelIn][iChannelOut]) >> MA_CHANNEL_CONVERTER_FIXED_POINT_SHIFT), -8388608, 8388607);
                        ma_pcm_sample_s32_to_s24_no_scale(s24, &pFramesOutS24[(iFrame*pConverter->channelsOut + iChannelOut)*3]);
                    }
                }
            }
        } break;

        case ma_format_s32:
        {
            /* */ ma_int32* pFramesOutS32 = (      ma_int32*)pFramesOut;
            const ma_int32* pFramesInS32  = (const ma_int32*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
                        ma_int64 s = pFramesOutS32[iFrame*pConverter->channelsOut + iChannelOut];
                        s += ((ma_int64)pFramesInS32[iFrame*pConverter->channelsIn + iChannelIn] * pConverter->weights.s16[iChannelIn][iChannelOut]) >> MA_CHANNEL_CONVERTER_FIXED_POINT_SHIFT;

                        pFramesOutS32[iFrame*pConverter->channelsOut + iChannelOut] = ma_clip_s32(s);
                    }
                }
            }
        } break;

        case ma_format_f32:
        {
            /* */ float* pFramesOutF32 = (      float*)pFramesOut;
            const float* pFramesInF32  = (const float*)pFramesIn;

            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
                    for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
                        pFramesOutF32[iFrame*pConverter->channelsOut + iChannelOut] += pFramesInF32[iFrame*pConverter->channelsIn + iChannelIn] * pConverter->weights.f32[iChannelIn][iChannelOut];
                    }
                }
            }
        } break;

        default: return MA_INVALID_OPERATION;   /* Unknown format. */
    }

    return MA_SUCCESS;
}

MA_API ma_result ma_channel_converter_process_pcm_frames(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
    if (pConverter == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pFramesOut == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pFramesIn == NULL) {
        ma_zero_memory_64(pFramesOut, frameCount * ma_get_bytes_per_frame(pConverter->format, pConverter->channelsOut));
        return MA_SUCCESS;
    }

    switch (pConverter->conversionPath)
    {
        case ma_channel_conversion_path_passthrough: return ma_channel_converter_process_pcm_frames__passthrough(pConverter, pFramesOut, pFramesIn, frameCount);
        case ma_channel_conversion_path_mono_out:    return ma_channel_converter_process_pcm_frames__mono_out(pConverter, pFramesOut, pFramesIn, frameCount);
        case ma_channel_conversion_path_mono_in:     return ma_channel_converter_process_pcm_frames__mono_in(pConverter, pFramesOut, pFramesIn, frameCount);
        case ma_channel_conversion_path_shuffle:     return ma_channel_converter_process_pcm_frames__shuffle(pConverter, pFramesOut, pFramesIn, frameCount);
        case ma_channel_conversion_path_weights:
        default:
        {
            return ma_channel_converter_process_pcm_frames__weights(pConverter, pFramesOut, pFramesIn, frameCount);
        }
    }
}

MA_API ma_result ma_channel_converter_get_input_channel_map(const ma_channel_converter* pConverter, ma_channel* pChannelMap, size_t channelMapCap)
{
    if (pConverter == NULL || pChannelMap == NULL) {
        return MA_INVALID_ARGS;
    }

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

        ma_resampler_uninit(&pConverter->resampler, pAllocationCallbacks);
    }

    ma_channel_converter_uninit(&pConverter->channelConverter, pAllocationCallbacks);

    if (pConverter->_ownsHeap) {
        ma_free(pConverter->_pHeap, pAllocationCallbacks);
    }
}

static ma_result ma_data_converter_process_pcm_frames__passthrough(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 frameCount;

    MA_ASSERT(pConverter != NULL);

    frameCountIn = 0;
    if (pFrameCountIn != NULL) {
        frameCountIn = *pFrameCountIn;
    }

    frameCountOut = 0;
    if (pFrameCountOut != NULL) {
        frameCountOut = *pFrameCountOut;
    }

    frameCount = ma_min(frameCountIn, frameCountOut);

    if (pFramesOut != NULL) {
        if (pFramesIn != NULL) {
            ma_copy_memory_64(pFramesOut, pFramesIn, frameCount * ma_get_bytes_per_frame(pConverter->formatOut, pConverter->channelsOut));
        } else {
            ma_zero_memory_64(pFramesOut,            frameCount * ma_get_bytes_per_frame(pConverter->formatOut, pConverter->channelsOut));
        }
    }

    if (pFrameCountIn != NULL) {
        *pFrameCountIn = frameCount;
    }
    if (pFrameCountOut != NULL) {
        *pFrameCountOut = frameCount;
    }

    return MA_SUCCESS;
}

static ma_result ma_data_converter_process_pcm_frames__format_only(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 frameCount;

    MA_ASSERT(pConverter != NULL);

    frameCountIn = 0;
    if (pFrameCountIn != NULL) {
        frameCountIn = *pFrameCountIn;
    }

    frameCountOut = 0;
    if (pFrameCountOut != NULL) {
        frameCountOut = *pFrameCountOut;
    }

    frameCount = ma_min(frameCountIn, frameCountOut);

    if (pFramesOut != NULL) {
        if (pFramesIn != NULL) {
            ma_convert_pcm_frames_format(pFramesOut, pConverter->formatOut, pFramesIn, pConverter->formatIn, frameCount, pConverter->channelsIn, pConverter->ditherMode);
        } else {
            ma_zero_memory_64(pFramesOut, frameCount * ma_get_bytes_per_frame(pConverter->formatOut, pConverter->channelsOut));
        }
    }

    if (pFrameCountIn != NULL) {
        *pFrameCountIn = frameCount;
    }
    if (pFrameCountOut != NULL) {
        *pFrameCountOut = frameCount;
    }

    return MA_SUCCESS;
}


static ma_result ma_data_converter_process_pcm_frames__resample_with_format_conversion(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    ma_result result = MA_SUCCESS;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;

    MA_ASSERT(pConverter != NULL);

    frameCountIn = 0;
    if (pFrameCountIn != NULL) {
        frameCountIn = *pFrameCountIn;
    }

    frameCountOut = 0;
    if (pFrameCountOut != NULL) {
        frameCountOut = *pFrameCountOut;
    }

    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    while (framesProcessedOut < frameCountOut) {
        ma_uint8 pTempBufferOut[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
        const ma_uint32 tempBufferOutCap = sizeof(pTempBufferOut) / ma_get_bytes_per_frame(pConverter->resampler.format, pConverter->resampler.channels);
        const void* pFramesInThisIteration;
        /* */ void* pFramesOutThisIteration;
        ma_uint64 frameCountInThisIteration;
        ma_uint64 frameCountOutThisIteration;

        if (pFramesIn != NULL) {
            pFramesInThisIteration = ma_offset_ptr(pFramesIn, framesProcessedIn * ma_get_bytes_per_frame(pConverter->formatIn, pConverter->channelsIn));
        } else {
            pFramesInThisIteration = NULL;
        }

        if (pFramesOut != NULL) {
            pFramesOutThisIteration = ma_offset_ptr(pFramesOut, framesProcessedOut * ma_get_bytes_per_frame(pConverter->formatOut, pConverter->channelsOut));
        } else {
            pFramesOutThisIteration = NULL;
        }

        /* Do a pre format conversion if necessary. */
        if (pConverter->hasPreFormatConversion) {
            ma_uint8 pTempBufferIn[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
            const ma_uint32 tempBufferInCap = sizeof(pTempBufferIn) / ma_get_bytes_per_frame(pConverter->resampler.format, pConverter->resampler.channels);

            frameCountInThisIteration  = (frameCountIn - framesProcessedIn);
            if (frameCountInThisIteration > tempBufferInCap) {
                frameCountInThisIteration = tempBufferInCap;
            }

            if (pConverter->hasPostFormatConversion) {
               if (frameCountInThisIteration > tempBufferOutCap) {
                   frameCountInThisIteration = tempBufferOutCap;
               }
            }

            if (pFramesInThisIteration != NULL) {
                ma_convert_pcm_frames_format(pTempBufferIn, pConverter->resampler.format, pFramesInThisIteration, pConverter->formatIn, frameCountInThisIteration, pConverter->channelsIn, pConverter->ditherMode);
            } else {
                MA_ZERO_MEMORY(pTempBufferIn, sizeof(pTempBufferIn));
            }

            frameCountOutThisIteration = (frameCountOut - framesProcessedOut);

            if (pConverter->hasPostFormatConversion) {
                /* Both input and output conversion required. Output to the temp buffer. */
                if (frameCountOutThisIteration > tempBufferOutCap) {
                    frameCountOutThisIteration = tempBufferOutCap;
                }

                result = ma_resampler_process_pcm_frames(&pConverter->resampler, pTempBufferIn, &frameCountInThisIteration, pTempBufferOut, &frameCountOutThisIteration);
            } else {
                /* Only pre-format required. Output straight to the output buffer. */
                result = ma_resampler_process_pcm_frames(&pConverter->resampler, pTempBufferIn, &frameCountInThisIteration, pFramesOutThisIteration, &frameCountOutThisIteration);
            }

            if (result != MA_SUCCESS) {
                break;
            }
        } else {
            /* No pre-format required. Just read straight from the input buffer. */
            MA_ASSERT(pConverter->hasPostFormatConversion == MA_TRUE);

            frameCountInThisIteration  = (frameCountIn  - framesProcessedIn);
            frameCountOutThisIteration = (frameCountOut - framesProcessedOut);
            if (frameCountOutThisIteration > tempBufferOutCap) {
                frameCountOutThisIteration = tempBufferOutCap;
            }

            result = ma_resampler_process_pcm_frames(&pConverter->resampler, pFramesInThisIteration, &frameCountInThisIteration, pTempBufferOut, &frameCountOutThisIteration);
            if (result != MA_SUCCESS) {
                break;
            }
        }

        /* If we are doing a post format conversion we need to do that now. */
        if (pConverter->hasPostFormatConversion) {
            if (pFramesOutThisIteration != NULL) {
                ma_convert_pcm_frames_format(pFramesOutThisIteration, pConverter->formatOut, pTempBufferOut, pConverter->resampler.format, frameCountOutThisIteration, pConverter->resampler.channels, pConverter->ditherMode);
            }
        }

        framesProcessedIn  += frameCountInThisIteration;
        framesProcessedOut += frameCountOutThisIteration;

        MA_ASSERT(framesProcessedIn  <= frameCountIn);
        MA_ASSERT(framesProcessedOut <= frameCountOut);

        if (frameCountOutThisIteration == 0) {
            break;  /* Consumed all of our input data. */
        }
    }

    if (pFrameCountIn != NULL) {
        *pFrameCountIn = framesProcessedIn;
    }
    if (pFrameCountOut != NULL) {
        *pFrameCountOut = framesProcessedOut;
    }

    return result;
}

static ma_result ma_data_converter_process_pcm_frames__resample_only(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    MA_ASSERT(pConverter != NULL);

    if (pConverter->hasPreFormatConversion == MA_FALSE && pConverter->hasPostFormatConversion == MA_FALSE) {
        /* Neither pre- nor post-format required. This is simple case where only resampling is required. */
        return ma_resampler_process_pcm_frames(&pConverter->resampler, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    } else {
        /* Format conversion required. */
        return ma_data_converter_process_pcm_frames__resample_with_format_conversion(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
    }
}

static ma_result ma_data_converter_process_pcm_frames__channels_only(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    ma_result result;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 frameCount;

    MA_ASSERT(pConverter != NULL);

    frameCountIn = 0;
    if (pFrameCountIn != NULL) {
        frameCountIn = *pFrameCountIn;
    }

    frameCountOut = 0;
    if (pFrameCountOut != NULL) {
        frameCountOut = *pFrameCountOut;
    }

    frameCount = ma_min(frameCountIn, frameCountOut);

    if (pConverter->hasPreFormatConversion == MA_FALSE && pConverter->hasPostFormatConversion == MA_FALSE) {
        /* No format conversion required. */
        result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pFramesOut, pFramesIn, frameCount);
        if (result != MA_SUCCESS) {
            return result;
        }
    } else {
        /* Format conversion required. */
        ma_uint64 framesProcessed = 0;

        while (framesProcessed < frameCount) {
            ma_uint8 pTempBufferOut[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
            const ma_uint32 tempBufferOutCap = sizeof(pTempBufferOut) / ma_get_bytes_per_frame(pConverter->channelConverter.format, pConverter->channelConverter.channelsOut);
            const void* pFramesInThisIteration;
            /* */ void* pFramesOutThisIteration;
            ma_uint64 frameCountThisIteration;

            if (pFramesIn != NULL) {
                pFramesInThisIteration = ma_offset_ptr(pFramesIn, framesProcessed * ma_get_bytes_per_frame(pConverter->formatIn, pConverter->channelsIn));
            } else {
                pFramesInThisIteration = NULL;
            }

            if (pFramesOut != NULL) {
                pFramesOutThisIteration = ma_offset_ptr(pFramesOut, framesProcessed * ma_get_bytes_per_frame(pConverter->formatOut, pConverter->channelsOut));
            } else {
                pFramesOutThisIteration = NULL;
            }

            /* Do a pre format conversion if necessary. */
            if (pConverter->hasPreFormatConversion) {
                ma_uint8 pTempBufferIn[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
                const ma_uint32 tempBufferInCap = sizeof(pTempBufferIn) / ma_get_bytes_per_frame(pConverter->channelConverter.format, pConverter->channelConverter.channelsIn);

                frameCountThisIteration = (frameCount - framesProcessed);
                if (frameCountThisIteration > tempBufferInCap) {
                    frameCountThisIteration = tempBufferInCap;
                }

                if (pConverter->hasPostFormatConversion) {
                    if (frameCountThisIteration > tempBufferOutCap) {
                        frameCountThisIteration = tempBufferOutCap;
                    }
                }

                if (pFramesInThisIteration != NULL) {
                    ma_convert_pcm_frames_format(pTempBufferIn, pConverter->channelConverter.format, pFramesInThisIteration, pConverter->formatIn, frameCountThisIteration, pConverter->channelsIn, pConverter->ditherMode);
                } else {
                    MA_ZERO_MEMORY(pTempBufferIn, sizeof(pTempBufferIn));
                }

                if (pConverter->hasPostFormatConversion) {
                    /* Both input and output conversion required. Output to the temp buffer. */
                    result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pTempBufferOut, pTempBufferIn, frameCountThisIteration);
                } else {
                    /* Only pre-format required. Output straight to the output buffer. */
                    result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pFramesOutThisIteration, pTempBufferIn, frameCountThisIteration);
                }

                if (result != MA_SUCCESS) {
                    break;
                }
            } else {
                /* No pre-format required. Just read straight from the input buffer. */
                MA_ASSERT(pConverter->hasPostFormatConversion == MA_TRUE);

                frameCountThisIteration = (frameCount - framesProcessed);
                if (frameCountThisIteration > tempBufferOutCap) {
                    frameCountThisIteration = tempBufferOutCap;
                }

                result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pTempBufferOut, pFramesInThisIteration, frameCountThisIteration);
                if (result != MA_SUCCESS) {
                    break;
                }
            }

            /* If we are doing a post format conversion we need to do that now. */
            if (pConverter->hasPostFormatConversion) {
                if (pFramesOutThisIteration != NULL) {
                    ma_convert_pcm_frames_format(pFramesOutThisIteration, pConverter->formatOut, pTempBufferOut, pConverter->channelConverter.format, frameCountThisIteration, pConverter->channelConverter.channelsOut, pConverter->ditherMode);
                }
            }

            framesProcessed += frameCountThisIteration;
        }
    }

    if (pFrameCountIn != NULL) {
        *pFrameCountIn = frameCount;
    }
    if (pFrameCountOut != NULL) {
        *pFrameCountOut = frameCount;
    }

    return MA_SUCCESS;
}

static ma_result ma_data_converter_process_pcm_frames__resample_first(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    ma_result result;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;
    ma_uint8  pTempBufferIn[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];   /* In resampler format. */
    ma_uint64 tempBufferInCap;
    ma_uint8  pTempBufferMid[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];  /* In resampler format, channel converter input format. */
    ma_uint64 tempBufferMidCap;
    ma_uint8  pTempBufferOut[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];  /* In channel converter output format. */
    ma_uint64 tempBufferOutCap;

    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pConverter->resampler.format   == pConverter->channelConverter.format);
    MA_ASSERT(pConverter->resampler.channels == pConverter->channelConverter.channelsIn);
    MA_ASSERT(pConverter->resampler.channels <  pConverter->channelConverter.channelsOut);

    frameCountIn = 0;
    if (pFrameCountIn != NULL) {
        frameCountIn = *pFrameCountIn;
    }

    frameCountOut = 0;
    if (pFrameCountOut != NULL) {
        frameCountOut = *pFrameCountOut;
    }

    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    tempBufferInCap  = sizeof(pTempBufferIn)  / ma_get_bytes_per_frame(pConverter->resampler.format, pConverter->resampler.channels);
    tempBufferMidCap = sizeof(pTempBufferIn)  / ma_get_bytes_per_frame(pConverter->resampler.format, pConverter->resampler.channels);
    tempBufferOutCap = sizeof(pTempBufferOut) / ma_get_bytes_per_frame(pConverter->channelConverter.format, pConverter->channelConverter.channelsOut);

    while (framesProcessedOut < frameCountOut) {
        ma_uint64 frameCountInThisIteration;
        ma_uint64 frameCountOutThisIteration;
        const void* pRunningFramesIn = NULL;
        void* pRunningFramesOut = NULL;
        const void* pResampleBufferIn;
        void* pChannelsBufferOut;

        if (pFramesIn != NULL) {
            pRunningFramesIn  = ma_offset_ptr(pFramesIn,  framesProcessedIn  * ma_get_bytes_per_frame(pConverter->formatIn, pConverter->channelsIn));
        }
        if (pFramesOut != NULL) {
            pRunningFramesOut = ma_offset_ptr(pFramesOut, framesProcessedOut * ma_get_bytes_per_frame(pConverter->formatOut, pConverter->channelsOut));
        }

        /* Run input data through the resampler and output it to the temporary buffer. */
        frameCountInThisIteration = (frameCountIn - framesProcessedIn);

        if (pConverter->hasPreFormatConversion) {
            if (frameCountInThisIteration > tempBufferInCap) {
                frameCountInThisIteration = tempBufferInCap;
            }
        }

        frameCountOutThisIteration = (frameCountOut - framesProcessedOut);
        if (frameCountOutThisIteration > tempBufferMidCap) {
            frameCountOutThisIteration = tempBufferMidCap;
        }

        /* We can't read more frames than can fit in the output buffer. */
        if (pConverter->hasPostFormatConversion) {
            if (frameCountOutThisIteration > tempBufferOutCap) {
                frameCountOutThisIteration = tempBufferOutCap;
            }
        }

        /* We need to ensure we don't try to process too many input frames that we run out of room in the output buffer. If this happens we'll end up glitching. */

        /*
        We need to try to predict how many input frames will be required for the resampler. If the
        resampler can tell us, we'll use that. Otherwise we'll need to make a best guess. The further
        off we are from this, the more wasted format conversions we'll end up doing.
        */
        #if 1
        {
            ma_uint64 requiredInputFrameCount;

            result = ma_resampler_get_required_input_frame_count(&pConverter->resampler, frameCountOutThisIteration, &requiredInputFrameCount);
            if (result != MA_SUCCESS) {
                /* Fall back to a best guess. */
                requiredInputFrameCount = (frameCountOutThisIteration * pConverter->resampler.sampleRateIn) / pConverter->resampler.sampleRateOut;
            }

            if (frameCountInThisIteration > requiredInputFrameCount) {
                frameCountInThisIteration = requiredInputFrameCount;
            }
        }
        #endif

        if (pConverter->hasPreFormatConversion) {
            if (pFramesIn != NULL) {
                ma_convert_pcm_frames_format(pTempBufferIn, pConverter->resampler.format, pRunningFramesIn, pConverter->formatIn, frameCountInThisIteration, pConverter->channelsIn, pConverter->ditherMode);
                pResampleBufferIn = pTempBufferIn;
            } else {
                pResampleBufferIn = NULL;
            }
        } else {
            pResampleBufferIn = pRunningFramesIn;
        }

        result = ma_resampler_process_pcm_frames(&pConverter->resampler, pResampleBufferIn, &frameCountInThisIteration, pTempBufferMid, &frameCountOutThisIteration);
        if (result != MA_SUCCESS) {
            return result;
        }


        /*
        The input data has been resampled so now we need to run it through the channel converter. The input data is always contained in pTempBufferMid. We only need to do
        this part if we have an output buffer.
        */
        if (pFramesOut != NULL) {
            if (pConverter->hasPostFormatConversion) {
                pChannelsBufferOut = pTempBufferOut;
            } else {
                pChannelsBufferOut = pRunningFramesOut;
            }

            result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pChannelsBufferOut, pTempBufferMid, frameCountOutThisIteration);
            if (result != MA_SUCCESS) {
                return result;
            }

            /* Finally we do post format conversion. */
            if (pConverter->hasPostFormatConversion) {
                ma_convert_pcm_frames_format(pRunningFramesOut, pConverter->formatOut, pChannelsBufferOut, pConverter->channelConverter.format, frameCountOutThisIteration, pConverter->channelConverter.channelsOut, pConverter->ditherMode);
            }
        }


        framesProcessedIn  += frameCountInThisIteration;
        framesProcessedOut += frameCountOutThisIteration;

        MA_ASSERT(framesProcessedIn  <= frameCountIn);
        MA_ASSERT(framesProcessedOut <= frameCountOut);

        if (frameCountOutThisIteration == 0) {
            break;  /* Consumed all of our input data. */
        }
    }

    if (pFrameCountIn != NULL) {
        *pFrameCountIn = framesProcessedIn;
    }
    if (pFrameCountOut != NULL) {
        *pFrameCountOut = framesProcessedOut;
    }

    return MA_SUCCESS;
}

static ma_result ma_data_converter_process_pcm_frames__channels_first(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    ma_result result;
    ma_uint64 frameCountIn;
    ma_uint64 frameCountOut;
    ma_uint64 framesProcessedIn;
    ma_uint64 framesProcessedOut;
    ma_uint8  pTempBufferIn[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];   /* In resampler format. */
    ma_uint64 tempBufferInCap;
    ma_uint8  pTempBufferMid[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];  /* In resampler format, channel converter input format. */
    ma_uint64 tempBufferMidCap;
    ma_uint8  pTempBufferOut[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];  /* In channel converter output format. */
    ma_uint64 tempBufferOutCap;

    MA_ASSERT(pConverter != NULL);
    MA_ASSERT(pConverter->resampler.format   == pConverter->channelConverter.format);
    MA_ASSERT(pConverter->resampler.channels == pConverter->channelConverter.channelsOut);
    MA_ASSERT(pConverter->resampler.channels <= pConverter->channelConverter.channelsIn);

    frameCountIn = 0;
    if (pFrameCountIn != NULL) {
        frameCountIn = *pFrameCountIn;
    }

    frameCountOut = 0;
    if (pFrameCountOut != NULL) {
        frameCountOut = *pFrameCountOut;
    }

    framesProcessedIn  = 0;
    framesProcessedOut = 0;

    tempBufferInCap  = sizeof(pTempBufferIn)  / ma_get_bytes_per_frame(pConverter->channelConverter.format, pConverter->channelConverter.channelsIn);
    tempBufferMidCap = sizeof(pTempBufferIn)  / ma_get_bytes_per_frame(pConverter->channelConverter.format, pConverter->channelConverter.channelsOut);
    tempBufferOutCap = sizeof(pTempBufferOut) / ma_get_bytes_per_frame(pConverter->resampler.format, pConverter->resampler.channels);

    while (framesProcessedOut < frameCountOut) {
        ma_uint64 frameCountInThisIteration;
        ma_uint64 frameCountOutThisIteration;
        const void* pRunningFramesIn = NULL;
        void* pRunningFramesOut = NULL;
        const void* pChannelsBufferIn;
        void* pResampleBufferOut;

        if (pFramesIn != NULL) {
            pRunningFramesIn  = ma_offset_ptr(pFramesIn,  framesProcessedIn  * ma_get_bytes_per_frame(pConverter->formatIn, pConverter->channelsIn));
        }
        if (pFramesOut != NULL) {
            pRunningFramesOut = ma_offset_ptr(pFramesOut, framesProcessedOut * ma_get_bytes_per_frame(pConverter->formatOut, pConverter->channelsOut));
        }

        /*
        Before doing any processing we need to determine how many frames we should try processing
        this iteration, for both input and output. The resampler requires us to perform format and
        channel conversion before passing any data into it. If we get our input count wrong, we'll
        end up peforming redundant pre-processing. This isn't the end of the world, but it does
        result in some inefficiencies proportionate to how far our estimates are off.

        If the resampler has a means to calculate exactly how much we'll need, we'll use that.
        Otherwise we'll make a best guess. In order to do this, we'll need to calculate the output
        frame count first.
        */
        frameCountOutThisIteration = (frameCountOut - framesProcessedOut);
        if (frameCountOutThisIteration > tempBufferMidCap) {
            frameCountOutThisIteration = tempBufferMidCap;
        }

        if (pConverter->hasPostFormatConversion) {
            if (frameCountOutThisIteration > tempBufferOutCap) {
                frameCountOutThisIteration = tempBufferOutCap;
            }
        }

        /* Now that we have the output frame count we can determine the input frame count. */
        frameCountInThisIteration = (frameCountIn - framesProcessedIn);
        if (pConverter->hasPreFormatConversion) {
            if (frameCountInThisIteration > tempBufferInCap) {
                frameCountInThisIteration = tempBufferInCap;
            }
        }

        if (frameCountInThisIteration > tempBufferMidCap) {
            frameCountInThisIteration = tempBufferMidCap;
        }

        #if 1
        {
            ma_uint64 requiredInputFrameCount;

            result = ma_resampler_get_required_input_frame_count(&pConverter->resampler, frameCountOutThisIteration, &requiredInputFrameCount);
            if (result != MA_SUCCESS) {
                /* Fall back to a best guess. */
                requiredInputFrameCount = (frameCountOutThisIteration * pConverter->resampler.sampleRateIn) / pConverter->resampler.sampleRateOut;
            }

            if (frameCountInThisIteration > requiredInputFrameCount) {
                frameCountInThisIteration = requiredInputFrameCount;
            }
        }
        #endif


        /* Pre format conversion. */
        if (pConverter->hasPreFormatConversion) {
            if (pRunningFramesIn != NULL) {
                ma_convert_pcm_frames_format(pTempBufferIn, pConverter->channelConverter.format, pRunningFramesIn, pConverter->formatIn, frameCountInThisIteration, pConverter->channelsIn, pConverter->ditherMode);
                pChannelsBufferIn = pTempBufferIn;
            } else {
                pChannelsBufferIn = NULL;
            }
        } else {
            pChannelsBufferIn = pRunningFramesIn;
        }


        /* Channel conversion. */
        result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pTempBufferMid, pChannelsBufferIn, frameCountInThisIteration);
        if (result != MA_SUCCESS) {
            return result;
        }


        /* Resampling. */
        if (pConverter->hasPostFormatConversion) {
            pResampleBufferOut = pTempBufferOut;
        } else {
            pResampleBufferOut = pRunningFramesOut;
        }

        result = ma_resampler_process_pcm_frames(&pConverter->resampler, pTempBufferMid, &frameCountInThisIteration, pResampleBufferOut, &frameCountOutThisIteration);
        if (result != MA_SUCCESS) {
            return result;
        }


        /* Post format conversion. */
        if (pConverter->hasPostFormatConversion) {
            if (pRunningFramesOut != NULL) {
                ma_convert_pcm_frames_format(pRunningFramesOut, pConverter->formatOut, pResampleBufferOut, pConverter->resampler.format, frameCountOutThisIteration, pConverter->channelsOut, pConverter->ditherMode);
            }
        }


        framesProcessedIn  += frameCountInThisIteration;
        framesProcessedOut += frameCountOutThisIteration;

        MA_ASSERT(framesProcessedIn  <= frameCountIn);
        MA_ASSERT(framesProcessedOut <= frameCountOut);

        if (frameCountOutThisIteration == 0) {
            break;  /* Consumed all of our input data. */
        }
    }

    if (pFrameCountIn != NULL) {
        *pFrameCountIn = framesProcessedIn;
    }
    if (pFrameCountOut != NULL) {
        *pFrameCountOut = framesProcessedOut;
    }

    return MA_SUCCESS;
}

MA_API ma_result ma_data_converter_process_pcm_frames(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
{
    if (pConverter == NULL) {
        return MA_INVALID_ARGS;
    }

    switch (pConverter->executionPath)
    {
        case ma_data_converter_execution_path_passthrough:    return ma_data_converter_process_pcm_frames__passthrough(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
        case ma_data_converter_execution_path_format_only:    return ma_data_converter_process_pcm_frames__format_only(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
        case ma_data_converter_execution_path_channels_only:  return ma_data_converter_process_pcm_frames__channels_only(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
        case ma_data_converter_execution_path_resample_only:  return ma_data_converter_process_pcm_frames__resample_only(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
        case ma_data_converter_execution_path_resample_first: return ma_data_converter_process_pcm_frames__resample_first(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
        case ma_data_converter_execution_path_channels_first: return ma_data_converter_process_pcm_frames__channels_first(pConverter, pFramesIn, pFrameCountIn, pFramesOut, pFrameCountOut);
        default: return MA_INVALID_OPERATION;   /* Should never hit this. */
    }
}

MA_API ma_result ma_data_converter_set_rate(ma_data_converter* pConverter, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut)
{
    if (pConverter == NULL) {
        return MA_INVALID_ARGS;
    }

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

        return 0;
    }

    if (pConverter->hasResampler) {
        return ma_resampler_get_output_latency(&pConverter->resampler);
    }

    return 0;   /* No latency without a resampler. */
}

MA_API ma_result ma_data_converter_get_required_input_frame_count(const ma_data_converter* pConverter, ma_uint64 outputFrameCount, ma_uint64* pInputFrameCount)
{
    if (pInputFrameCount == NULL) {
        return MA_INVALID_ARGS;
    }

    *pInputFrameCount = 0;

    if (pConverter == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pConverter->hasResampler) {
        return ma_resampler_get_required_input_frame_count(&pConverter->resampler, outputFrameCount, pInputFrameCount);
    } else {
        *pInputFrameCount = outputFrameCount;   /* 1:1 */
        return MA_SUCCESS;
    }
}

MA_API ma_result ma_data_converter_get_expected_output_frame_count(const ma_data_converter* pConverter, ma_uint64 inputFrameCount, ma_uint64* pOutputFrameCount)
{
    if (pOutputFrameCount == NULL) {
        return MA_INVALID_ARGS;
    }

    *pOutputFrameCount = 0;

    if (pConverter == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pConverter->hasResampler) {
        return ma_resampler_get_expected_output_frame_count(&pConverter->resampler, inputFrameCount, pOutputFrameCount);
    } else {
        *pOutputFrameCount = inputFrameCount;   /* 1:1 */
        return MA_SUCCESS;
    }
}

MA_API ma_result ma_data_converter_get_input_channel_map(const ma_data_converter* pConverter, ma_channel* pChannelMap, size_t channelMapCap)
{
    if (pConverter == NULL || pChannelMap == NULL) {
        return MA_INVALID_ARGS;

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

    return MA_FALSE;
}



/**************************************************************************************************************************************************************

Conversion Helpers

**************************************************************************************************************************************************************/
MA_API ma_uint64 ma_convert_frames(void* pOut, ma_uint64 frameCountOut, ma_format formatOut, ma_uint32 channelsOut, ma_uint32 sampleRateOut, const void* pIn, ma_uint64 frameCountIn, ma_format formatIn, ma_uint32 channelsIn, ma_uint32 sampleRateIn)
{
    ma_data_converter_config config;

    config = ma_data_converter_config_init(formatIn, formatOut, channelsIn, channelsOut, sampleRateIn, sampleRateOut);
    config.resampling.linear.lpfOrder = ma_min(MA_DEFAULT_RESAMPLER_LPF_ORDER, MA_MAX_FILTER_ORDER);

    return ma_convert_frames_ex(pOut, frameCountOut, pIn, frameCountIn, &config);
}

MA_API ma_uint64 ma_convert_frames_ex(void* pOut, ma_uint64 frameCountOut, const void* pIn, ma_uint64 frameCountIn, const ma_data_converter_config* pConfig)
{
    ma_result result;
    ma_data_converter converter;

    if (frameCountIn == 0 || pConfig == NULL) {
        return 0;
    }

    result = ma_data_converter_init(pConfig, NULL, &converter);
    if (result != MA_SUCCESS) {
        return 0;   /* Failed to initialize the data converter. */
    }

    if (pOut == NULL) {
        result = ma_data_converter_get_expected_output_frame_count(&converter, frameCountIn, &frameCountOut);
        if (result != MA_SUCCESS) {
            if (result == MA_NOT_IMPLEMENTED) {
                /* No way to calculate the number of frames, so we'll need to brute force it and loop. */
                frameCountOut = 0;

                while (frameCountIn > 0) {
                    ma_uint64 framesProcessedIn  = frameCountIn;
                    ma_uint64 framesProcessedOut = 0xFFFFFFFF;

                    result = ma_data_converter_process_pcm_frames(&converter, pIn, &framesProcessedIn, NULL, &framesProcessedOut);
                    if (result != MA_SUCCESS) {
                        break;
                    }

                    frameCountIn  -= framesProcessedIn;
                }
            }
        }
    } else {
        result = ma_data_converter_process_pcm_frames(&converter, pIn, &frameCountIn, pOut, &frameCountOut);
        if (result != MA_SUCCESS) {
            frameCountOut = 0;
        }
    }

    ma_data_converter_uninit(&converter, NULL);
    return frameCountOut;
}


/**************************************************************************************************************************************************************

Ring Buffer

**************************************************************************************************************************************************************/
static MA_INLINE ma_uint32 ma_rb__extract_offset_in_bytes(ma_uint32 encodedOffset)
{

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


    return ma_offset_ptr(pBuffer, ma_rb_get_subbuffer_offset(pRB, subbufferIndex));
}



static MA_INLINE ma_uint32 ma_pcm_rb_get_bpf(ma_pcm_rb* pRB)
{
    MA_ASSERT(pRB != NULL);

    return ma_get_bytes_per_frame(pRB->format, pRB->channels);
}

MA_API ma_result ma_pcm_rb_init_ex(ma_format format, ma_uint32 channels, ma_uint32 subbufferSizeInFrames, ma_uint32 subbufferCount, ma_uint32 subbufferStrideInFrames, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallba...
{
    ma_uint32 bpf;
    ma_result result;

    if (pRB == NULL) {
        return MA_INVALID_ARGS;
    }

    MA_ZERO_OBJECT(pRB);

    bpf = ma_get_bytes_per_frame(format, channels);
    if (bpf == 0) {
        return MA_INVALID_ARGS;
    }

    result = ma_rb_init_ex(subbufferSizeInFrames*bpf, subbufferCount, subbufferStrideInFrames*bpf, pOptionalPreallocatedBuffer, pAllocationCallbacks, &pRB->rb);
    if (result != MA_SUCCESS) {
        return result;
    }

    pRB->format   = format;

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

    return ma_rb_get_subbuffer_ptr(&pRB->rb, subbufferIndex, pBuffer);
}



MA_API ma_result ma_duplex_rb_init(ma_format captureFormat, ma_uint32 captureChannels, ma_uint32 sampleRate, ma_uint32 captureInternalSampleRate, ma_uint32 captureInternalPeriodSizeInFrames, const ma_allocation_callbacks* pAllocationCallbacks, ma_dup...
{
    ma_result result;
    ma_uint32 sizeInFrames;

    sizeInFrames = (ma_uint32)ma_calculate_frame_count_after_resampling(sampleRate, captureInternalSampleRate, captureInternalPeriodSizeInFrames * 5);
    if (sizeInFrames == 0) {
        return MA_INVALID_ARGS;
    }

    result = ma_pcm_rb_init(captureFormat, captureChannels, sizeInFrames, NULL, pAllocationCallbacks, &pRB->rb);
    if (result != MA_SUCCESS) {
        return result;
    }

    /* Seek forward a bit so we have a bit of a buffer in case of desyncs. */

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

        }
    } else {
        pCurrentDataSource = (ma_data_source_base*)pCurrentDataSource->pCurrent;
    }

    *ppCurrentDataSource = pCurrentDataSource;

    return MA_SUCCESS;
}

static ma_result ma_data_source_read_pcm_frames_within_range(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
    ma_result result;
    ma_uint64 framesRead = 0;
    ma_bool32 loop = ma_data_source_is_looping(pDataSource);

    if (pDataSourceBase == NULL) {
        return MA_AT_END;
    }

    if (frameCount == 0) {
        return MA_INVALID_ARGS;
    }

    if ((pDataSourceBase->vtable->flags & MA_DATA_SOURCE_SELF_MANAGED_RANGE_AND_LOOP_POINT) != 0 || (pDataSourceBase->rangeEndInFrames == ~((ma_uint64)0) && (pDataSourceBase->loopEndInFrames == ~((ma_uint64)0) || loop == MA_FALSE))) {
        /* Either the data source is self-managing the range, or no range is set - just read like normal. The data source itself will tell us when the end is reached. */
        result = pDataSourceBase->vtable->onRead(pDataSourceBase, pFramesOut, frameCount, &framesRead);
    } else {
        /* Need to clamp to within the range. */
        ma_uint64 cursor;

        result = ma_data_source_get_cursor_in_pcm_frames(pDataSourceBase, &cursor);
        if (result != MA_SUCCESS) {
            /* Failed to retrieve the cursor. Cannot read within a range or loop points. Just read like normal - this may happen for things like noise data sources where it doesn't really matter. */
            result = pDataSourceBase->vtable->onRead(pDataSourceBase, pFramesOut, frameCount, &framesRead);
        } else {
            ma_uint64 rangeEnd;

            /* We have the cursor. We need to make sure we don't read beyond our range. */
            rangeEnd = pDataSourceBase->rangeEndInFrames;

            /* If looping, make sure we're within range. */
            if (loop) {
                if (pDataSourceBase->loopEndInFrames != ~((ma_uint64)0)) {
                    rangeEnd = ma_min(rangeEnd, pDataSourceBase->rangeBegInFrames + pDataSourceBase->loopEndInFrames);
                }
            }

            if (frameCount > (rangeEnd - cursor) && rangeEnd != ~((ma_uint64)0)) {
                frameCount = (rangeEnd - cursor);
            }

            /*
            If the cursor is sitting on the end of the range the frame count will be set to 0 which can
            result in MA_INVALID_ARGS. In this case, we don't want to try reading, but instead return
            MA_AT_END so the higher level function can know about it.
            */
            if (frameCount > 0) {
                result = pDataSourceBase->vtable->onRead(pDataSourceBase, pFramesOut, frameCount, &framesRead);
            } else {
                result = MA_AT_END; /* The cursor is sitting on the end of the range which means we're at the end. */
            }
        }
    }

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

    /* We need to make sure MA_AT_END is returned if we hit the end of the range. */
    if (result == MA_SUCCESS && framesRead == 0) {
        result  = MA_AT_END;
    }

    return result;
}

MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_result result = MA_SUCCESS;
    ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
    ma_data_source_base* pCurrentDataSource;
    void* pRunningFramesOut = pFramesOut;
    ma_uint64 totalFramesProcessed = 0;
    ma_format format;
    ma_uint32 channels;
    ma_uint32 emptyLoopCounter = 0; /* Keeps track of how many times 0 frames have been read. For infinite loop detection of sounds with no audio data. */
    ma_bool32 loop;

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

    if (frameCount == 0) {
        return MA_INVALID_ARGS;
    }

    if (pDataSourceBase == NULL) {
        return MA_INVALID_ARGS;
    }

    loop = ma_data_source_is_looping(pDataSource);

    /*
    We need to know the data format so we can advance the output buffer as we read frames. If this
    fails, chaining will not work and we'll just read as much as we can from the current source.
    */
    if (ma_data_source_get_data_format(pDataSource, &format, &channels, NULL, NULL, 0) != MA_SUCCESS) {
        result = ma_data_source_resolve_current(pDataSource, (ma_data_source**)&pCurrentDataSource);
        if (result != MA_SUCCESS) {
            return result;
        }

        return ma_data_source_read_pcm_frames_within_range(pCurrentDataSource, pFramesOut, frameCount, pFramesRead);
    }

    /*
    Looping is a bit of a special case. When the `loop` argument is true, chaining will not work and
    only the current data source will be read from.
    */

    /* Keep reading until we've read as many frames as possible. */
    while (totalFramesProcessed < frameCount) {
        ma_uint64 framesProcessed;
        ma_uint64 framesRemaining = frameCount - totalFramesProcessed;

        /* We need to resolve the data source that we'll actually be reading from. */
        result = ma_data_source_resolve_current(pDataSource, (ma_data_source**)&pCurrentDataSource);
        if (result != MA_SUCCESS) {
            break;
        }

        if (pCurrentDataSource == NULL) {
            break;
        }

        result = ma_data_source_read_pcm_frames_within_range(pCurrentDataSource, pRunningFramesOut, framesRemaining, &framesProcessed);
        totalFramesProcessed += framesProcessed;

        /*
        If we encounted an error from the read callback, make sure it's propagated to the caller. The caller may need to know whether or not MA_BUSY is returned which is
        not necessarily considered an error.
        */
        if (result != MA_SUCCESS && result != MA_AT_END) {
            break;
        }

        /*
        We can determine if we've reached the end by checking if ma_data_source_read_pcm_frames_within_range() returned
        MA_AT_END. To loop back to the start, all we need to do is seek back to the first frame.
        */
        if (result == MA_AT_END) {
            /*
            The result needs to be reset back to MA_SUCCESS (from MA_AT_END) so that we don't
            accidentally return MA_AT_END when data has been read in prior loop iterations. at the
            end of this function, the result will be checked for MA_SUCCESS, and if the total
            number of frames processed is 0, will be explicitly set to MA_AT_END.
            */
            result = MA_SUCCESS;

            /*
            We reached the end. If we're looping, we just loop back to the start of the current
            data source. If we're not looping we need to check if we have another in the chain, and
            if so, switch to it.
            */
            if (loop) {
                if (framesProcessed == 0) {
                    emptyLoopCounter += 1;
                    if (emptyLoopCounter > 1) {
                        break;  /* Infinite loop detected. Get out. */
                    }
                } else {
                    emptyLoopCounter = 0;
                }

                result = ma_data_source_seek_to_pcm_frame(pCurrentDataSource, pCurrentDataSource->loopBegInFrames);
                if (result != MA_SUCCESS) {
                    break;  /* Failed to loop. Abort. */
                }

                /* Don't return MA_AT_END for looping sounds. */
                result = MA_SUCCESS;
            } else {
                if (pCurrentDataSource->pNext != NULL) {
                    pDataSourceBase->pCurrent = pCurrentDataSource->pNext;
                } else if (pCurrentDataSource->onGetNext != NULL) {
                    pDataSourceBase->pCurrent = pCurrentDataSource->onGetNext(pCurrentDataSource);
                    if (pDataSourceBase->pCurrent == NULL) {
                        break;  /* Our callback did not return a next data source. We're done. */
                    }
                } else {
                    /* Reached the end of the chain. We're done. */
                    break;
                }

                /* The next data source needs to be rewound to ensure data is read in looping scenarios. */
                result = ma_data_source_seek_to_pcm_frame(pDataSourceBase->pCurrent, 0);
                if (result != MA_SUCCESS) {
                    break;
                }
            }
        }

        if (pRunningFramesOut != NULL) {
            pRunningFramesOut = ma_offset_ptr(pRunningFramesOut, framesProcessed * ma_get_bytes_per_frame(format, channels));
        }
    }

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

    MA_ASSERT(!(result == MA_AT_END && totalFramesProcessed > 0));  /* We should never be returning MA_AT_END if we read some data. */

    if (result == MA_SUCCESS && totalFramesProcessed == 0) {
        result  = MA_AT_END;
    }

    return result;
}

MA_API ma_result ma_data_source_seek_pcm_frames(ma_data_source* pDataSource, ma_uint64 frameCount, ma_uint64* pFramesSeeked)
{
    return ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount, pFramesSeeked);
}

MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;

    if (pDataSourceBase == NULL) {
        return MA_SUCCESS;
    }

    if (pDataSourceBase->vtable->onSeek == NULL) {
        return MA_NOT_IMPLEMENTED;
    }

    if (frameIndex > pDataSourceBase->rangeEndInFrames) {
        return MA_INVALID_OPERATION;    /* Trying to seek to far forward. */
    }

    return pDataSourceBase->vtable->onSeek(pDataSource, pDataSourceBase->rangeBegInFrames + frameIndex);
}

MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
    ma_result result;
    ma_format format;
    ma_uint32 channels;
    ma_uint32 sampleRate;

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

    }
    if (pSampleRate != NULL) {
        *pSampleRate = sampleRate;
    }

    /* Channel map was passed in directly to the callback. This is safe due to the channelMapCap parameter. */

    return MA_SUCCESS;
}

MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor)
{
    ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
    ma_result result;
    ma_uint64 cursor;

    if (pCursor == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = 0;

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

    /* The cursor needs to be made relative to the start of the range. */
    if (cursor < pDataSourceBase->rangeBegInFrames) {   /* Safety check so we don't return some huge number. */
        *pCursor = 0;
    } else {
        *pCursor = cursor - pDataSourceBase->rangeBegInFrames;
    }

    return MA_SUCCESS;
}

MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLength)
{
    ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;

    if (pLength == NULL) {
        return MA_INVALID_ARGS;
    }

    *pLength = 0;

    if (pDataSourceBase == NULL) {

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

    ma_result result;
    ma_uint64 cursorInPCMFrames;
    ma_uint32 sampleRate;

    if (pCursor == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = 0;

    result = ma_data_source_get_cursor_in_pcm_frames(pDataSource, &cursorInPCMFrames);
    if (result != MA_SUCCESS) {
        return result;
    }

    result = ma_data_source_get_data_format(pDataSource, NULL, NULL, &sampleRate, NULL, 0);
    if (result != MA_SUCCESS) {
        return result;
    }

    *pCursor = cursorInPCMFrames / (float)sampleRate;

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

    ma_result result;
    ma_uint64 lengthInPCMFrames;
    ma_uint32 sampleRate;

    if (pLength == NULL) {
        return MA_INVALID_ARGS;
    }

    *pLength = 0;

    result = ma_data_source_get_length_in_pcm_frames(pDataSource, &lengthInPCMFrames);
    if (result != MA_SUCCESS) {
        return result;
    }

    result = ma_data_source_get_data_format(pDataSource, NULL, NULL, &sampleRate, NULL, 0);
    if (result != MA_SUCCESS) {
        return result;
    }

    *pLength = lengthInPCMFrames / (float)sampleRate;

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

{
    const ma_data_source_base* pDataSourceBase = (const ma_data_source_base*)pDataSource;

    if (pDataSource == NULL) {
        return MA_FALSE;
    }

    return c89atomic_load_32(&pDataSourceBase->isLooping);
}

MA_API ma_result ma_data_source_set_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 rangeBegInFrames, ma_uint64 rangeEndInFrames)
{
    ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
    ma_result result;
    ma_uint64 cursor;
    ma_uint64 loopBegAbsolute;
    ma_uint64 loopEndAbsolute;

    if (pDataSource == NULL) {
        return MA_INVALID_ARGS;
    }

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

            pDataSourceBase->loopEndInFrames = 0;
        }

        if (pDataSourceBase->loopEndInFrames > pDataSourceBase->rangeEndInFrames && pDataSourceBase->loopEndInFrames) {
            pDataSourceBase->loopEndInFrames = pDataSourceBase->rangeEndInFrames;
        }
    }


    /* If the new range is past the current cursor position we need to seek to it. */
    result = ma_data_source_get_cursor_in_pcm_frames(pDataSource, &cursor);
    if (result == MA_SUCCESS) {
        /* Seek to within range. Note that our seek positions here are relative to the new range. */
        if (cursor < rangeBegInFrames) {
            ma_data_source_seek_to_pcm_frame(pDataSource, 0);
        } else if (cursor > rangeEndInFrames) {
            ma_data_source_seek_to_pcm_frame(pDataSource, rangeEndInFrames - rangeBegInFrames);
        }
    } else {
        /* We failed to get the cursor position. Probably means the data source has no notion of a cursor such a noise data source. Just pretend the seeking worked. */
    }

    return MA_SUCCESS;
}

MA_API void ma_data_source_get_range_in_pcm_frames(const ma_data_source* pDataSource, ma_uint64* pRangeBegInFrames, ma_uint64* pRangeEndInFrames)
{
    const ma_data_source_base* pDataSourceBase = (const ma_data_source_base*)pDataSource;

    if (pDataSource == NULL) {
        return;
    }

    if (pRangeBegInFrames != NULL) {
        *pRangeBegInFrames = pDataSourceBase->rangeBegInFrames;
    }

    if (pRangeEndInFrames != NULL) {
        *pRangeEndInFrames = pDataSourceBase->rangeEndInFrames;
    }
}

MA_API ma_result ma_data_source_set_loop_point_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 loopBegInFrames, ma_uint64 loopEndInFrames)
{
    ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;

    if (pDataSource == NULL) {
        return MA_INVALID_ARGS;
    }

    if (loopEndInFrames < loopBegInFrames) {
        return MA_INVALID_ARGS; /* The end of the loop point must come after the beginning. */
    }

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

    pDataSourceBase->loopEndInFrames = loopEndInFrames;

    /* The end cannot exceed the range. */
    if (pDataSourceBase->loopEndInFrames > (pDataSourceBase->rangeEndInFrames - pDataSourceBase->rangeBegInFrames) && pDataSourceBase->loopEndInFrames != ~((ma_uint64)0)) {
        pDataSourceBase->loopEndInFrames = (pDataSourceBase->rangeEndInFrames - pDataSourceBase->rangeBegInFrames);
    }

    return MA_SUCCESS;
}

MA_API void ma_data_source_get_loop_point_in_pcm_frames(const ma_data_source* pDataSource, ma_uint64* pLoopBegInFrames, ma_uint64* pLoopEndInFrames)
{
    const ma_data_source_base* pDataSourceBase = (const ma_data_source_base*)pDataSource;

    if (pDataSource == NULL) {
        return;
    }

    if (pLoopBegInFrames != NULL) {
        *pLoopBegInFrames = pDataSourceBase->loopBegInFrames;
    }

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

    const ma_data_source_base* pDataSourceBase = (const ma_data_source_base*)pDataSource;

    if (pDataSource == NULL) {
        return NULL;
    }

    return pDataSourceBase->onGetNext;
}


static ma_result ma_audio_buffer_ref__data_source_on_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_audio_buffer_ref* pAudioBufferRef = (ma_audio_buffer_ref*)pDataSource;
    ma_uint64 framesRead = ma_audio_buffer_ref_read_pcm_frames(pAudioBufferRef, pFramesOut, frameCount, MA_FALSE);

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

    if (framesRead < frameCount || framesRead == 0) {
        return MA_AT_END;
    }

    return MA_SUCCESS;
}

static ma_result ma_audio_buffer_ref__data_source_on_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    return ma_audio_buffer_ref_seek_to_pcm_frame((ma_audio_buffer_ref*)pDataSource, frameIndex);
}

static ma_result ma_audio_buffer_ref__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    ma_audio_buffer_ref* pAudioBufferRef = (ma_audio_buffer_ref*)pDataSource;

    *pFormat     = pAudioBufferRef->format;
    *pChannels   = pAudioBufferRef->channels;
    *pSampleRate = pAudioBufferRef->sampleRate;
    ma_channel_map_init_standard(ma_standard_channel_map_default, pChannelMap, channelMapCap, pAudioBufferRef->channels);

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

        return MA_INVALID_ARGS;
    }

    pAudioBufferRef->cursor       = 0;
    pAudioBufferRef->sizeInFrames = sizeInFrames;
    pAudioBufferRef->pData        = pData;

    return MA_SUCCESS;
}

MA_API ma_uint64 ma_audio_buffer_ref_read_pcm_frames(ma_audio_buffer_ref* pAudioBufferRef, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop)
{
    ma_uint64 totalFramesRead = 0;

    if (pAudioBufferRef == NULL) {
        return 0;
    }

    if (frameCount == 0) {
        return 0;
    }

    while (totalFramesRead < frameCount) {
        ma_uint64 framesAvailable = pAudioBufferRef->sizeInFrames - pAudioBufferRef->cursor;
        ma_uint64 framesRemaining = frameCount - totalFramesRead;
        ma_uint64 framesToRead;

        framesToRead = framesRemaining;
        if (framesToRead > framesAvailable) {
            framesToRead = framesAvailable;
        }

        if (pFramesOut != NULL) {
            ma_copy_pcm_frames(ma_offset_ptr(pFramesOut, totalFramesRead * ma_get_bytes_per_frame(pAudioBufferRef->format, pAudioBufferRef->channels)), ma_offset_ptr(pAudioBufferRef->pData, pAudioBufferRef->cursor * ma_get_bytes_per_frame(pAudioBuffe...
        }

        totalFramesRead += framesToRead;

        pAudioBufferRef->cursor += framesToRead;
        if (pAudioBufferRef->cursor == pAudioBufferRef->sizeInFrames) {
            if (loop) {
                pAudioBufferRef->cursor = 0;
            } else {
                break;  /* We've reached the end and we're not looping. Done. */
            }
        }

        MA_ASSERT(pAudioBufferRef->cursor < pAudioBufferRef->sizeInFrames);
    }

    return totalFramesRead;
}

MA_API ma_result ma_audio_buffer_ref_seek_to_pcm_frame(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameIndex)
{
    if (pAudioBufferRef == NULL) {
        return MA_INVALID_ARGS;
    }

    if (frameIndex > pAudioBufferRef->sizeInFrames) {
        return MA_INVALID_ARGS;
    }

    pAudioBufferRef->cursor = (size_t)frameIndex;

    return MA_SUCCESS;
}

MA_API ma_result ma_audio_buffer_ref_map(ma_audio_buffer_ref* pAudioBufferRef, void** ppFramesOut, ma_uint64* pFrameCount)
{
    ma_uint64 framesAvailable;
    ma_uint64 frameCount = 0;

    if (ppFramesOut != NULL) {
        *ppFramesOut = NULL;    /* Safety. */
    }

    if (pFrameCount != NULL) {
        frameCount = *pFrameCount;
        *pFrameCount = 0;       /* Safety. */
    }

    if (pAudioBufferRef == NULL || ppFramesOut == NULL || pFrameCount == NULL) {
        return MA_INVALID_ARGS;
    }

    framesAvailable = pAudioBufferRef->sizeInFrames - pAudioBufferRef->cursor;
    if (frameCount > framesAvailable) {
        frameCount = framesAvailable;
    }

    *ppFramesOut = ma_offset_ptr(pAudioBufferRef->pData, pAudioBufferRef->cursor * ma_get_bytes_per_frame(pAudioBufferRef->format, pAudioBufferRef->channels));
    *pFrameCount = frameCount;

    return MA_SUCCESS;
}

MA_API ma_result ma_audio_buffer_ref_unmap(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameCount)
{
    ma_uint64 framesAvailable;

    if (pAudioBufferRef == NULL) {
        return MA_INVALID_ARGS;
    }

    framesAvailable = pAudioBufferRef->sizeInFrames - pAudioBufferRef->cursor;
    if (frameCount > framesAvailable) {
        return MA_INVALID_ARGS;   /* The frame count was too big. This should never happen in an unmapping. Need to make sure the caller is aware of this. */
    }

    pAudioBufferRef->cursor += frameCount;

    if (pAudioBufferRef->cursor == pAudioBufferRef->sizeInFrames) {
        return MA_AT_END;   /* Successful. Need to tell the caller that the end has been reached so that it can loop if desired. */
    } else {
        return MA_SUCCESS;
    }
}

MA_API ma_bool32 ma_audio_buffer_ref_at_end(const ma_audio_buffer_ref* pAudioBufferRef)
{
    if (pAudioBufferRef == NULL) {
        return MA_FALSE;
    }

    return pAudioBufferRef->cursor == pAudioBufferRef->sizeInFrames;
}

MA_API ma_result ma_audio_buffer_ref_get_cursor_in_pcm_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pCursor)
{
    if (pCursor == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = 0;

    if (pAudioBufferRef == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = pAudioBufferRef->cursor;

    return MA_SUCCESS;
}

MA_API ma_result ma_audio_buffer_ref_get_length_in_pcm_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pLength)
{
    if (pLength == NULL) {
        return MA_INVALID_ARGS;
    }

    *pLength = 0;

    if (pAudioBufferRef == NULL) {
        return MA_INVALID_ARGS;
    }

    *pLength = pAudioBufferRef->sizeInFrames;

    return MA_SUCCESS;
}

MA_API ma_result ma_audio_buffer_ref_get_available_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pAvailableFrames)
{
    if (pAvailableFrames == NULL) {
        return MA_INVALID_ARGS;
    }

    *pAvailableFrames = 0;

    if (pAudioBufferRef == NULL) {
        return MA_INVALID_ARGS;
    }

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

        return MA_INVALID_ARGS;
    }

    MA_ZERO_MEMORY(pAudioBuffer, sizeof(*pAudioBuffer) - sizeof(pAudioBuffer->_pExtraData));   /* Safety. Don't overwrite the extra data. */

    if (pConfig == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pConfig->sizeInFrames == 0) {
        return MA_INVALID_ARGS; /* Not allowing buffer sizes of 0 frames. */
    }

    result = ma_audio_buffer_ref_init(pConfig->format, pConfig->channels, NULL, 0, &pAudioBuffer->ref);
    if (result != MA_SUCCESS) {
        return result;
    }

    /* TODO: Version 0.12. Set this in ma_audio_buffer_ref_init() instead of here. */
    pAudioBuffer->ref.sampleRate = pConfig->sampleRate;

    ma_allocation_callbacks_init_copy(&pAudioBuffer->allocationCallbacks, &pConfig->allocationCallbacks);

    if (doCopy) {
        ma_uint64 allocationSizeInBytes;
        void* pData;

        allocationSizeInBytes = pConfig->sizeInFrames * ma_get_bytes_per_frame(pConfig->format, pConfig->channels);
        if (allocationSizeInBytes > MA_SIZE_MAX) {
            return MA_OUT_OF_MEMORY;    /* Too big. */
        }

        pData = ma_malloc((size_t)allocationSizeInBytes, &pAudioBuffer->allocationCallbacks);   /* Safe cast to size_t. */
        if (pData == NULL) {
            return MA_OUT_OF_MEMORY;
        }

        if (pConfig->pData != NULL) {
            ma_copy_pcm_frames(pData, pConfig->pData, pConfig->sizeInFrames, pConfig->format, pConfig->channels);
        } else {
            ma_silence_pcm_frames(pData, pConfig->sizeInFrames, pConfig->format, pConfig->channels);
        }

        ma_audio_buffer_ref_set_data(&pAudioBuffer->ref, pData, pConfig->sizeInFrames);
        pAudioBuffer->ownsData = MA_TRUE;
    } else {
        ma_audio_buffer_ref_set_data(&pAudioBuffer->ref, pConfig->pData, pConfig->sizeInFrames);
        pAudioBuffer->ownsData = MA_FALSE;
    }

    return MA_SUCCESS;

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


    *ppAudioBuffer = NULL;  /* Safety. */

    if (pConfig == NULL) {
        return MA_INVALID_ARGS;
    }

    innerConfig = *pConfig;
    ma_allocation_callbacks_init_copy(&innerConfig.allocationCallbacks, &pConfig->allocationCallbacks);

    allocationSizeInBytes = sizeof(*pAudioBuffer) - sizeof(pAudioBuffer->_pExtraData) + (pConfig->sizeInFrames * ma_get_bytes_per_frame(pConfig->format, pConfig->channels));
    if (allocationSizeInBytes > MA_SIZE_MAX) {
        return MA_OUT_OF_MEMORY;    /* Too big. */
    }

    pAudioBuffer = (ma_audio_buffer*)ma_malloc((size_t)allocationSizeInBytes, &innerConfig.allocationCallbacks);  /* Safe cast to size_t. */
    if (pAudioBuffer == NULL) {
        return MA_OUT_OF_MEMORY;
    }

    if (pConfig->pData != NULL) {
        ma_copy_pcm_frames(&pAudioBuffer->_pExtraData[0], pConfig->pData, pConfig->sizeInFrames, pConfig->format, pConfig->channels);
    } else {
        ma_silence_pcm_frames(&pAudioBuffer->_pExtraData[0], pConfig->sizeInFrames, pConfig->format, pConfig->channels);
    }

    innerConfig.pData = &pAudioBuffer->_pExtraData[0];

    result = ma_audio_buffer_init_ex(&innerConfig, MA_FALSE, pAudioBuffer);
    if (result != MA_SUCCESS) {
        ma_free(pAudioBuffer, &innerConfig.allocationCallbacks);
        return result;
    }

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

MA_API void ma_audio_buffer_uninit(ma_audio_buffer* pAudioBuffer)
{
    ma_audio_buffer_uninit_ex(pAudioBuffer, MA_FALSE);
}

MA_API void ma_audio_buffer_uninit_and_free(ma_audio_buffer* pAudioBuffer)
{
    ma_audio_buffer_uninit_ex(pAudioBuffer, MA_TRUE);
}

MA_API ma_uint64 ma_audio_buffer_read_pcm_frames(ma_audio_buffer* pAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop)
{
    if (pAudioBuffer == NULL) {
        return 0;
    }

    return ma_audio_buffer_ref_read_pcm_frames(&pAudioBuffer->ref, pFramesOut, frameCount, loop);
}

MA_API ma_result ma_audio_buffer_seek_to_pcm_frame(ma_audio_buffer* pAudioBuffer, ma_uint64 frameIndex)
{
    if (pAudioBuffer == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_audio_buffer_ref_seek_to_pcm_frame(&pAudioBuffer->ref, frameIndex);
}

MA_API ma_result ma_audio_buffer_map(ma_audio_buffer* pAudioBuffer, void** ppFramesOut, ma_uint64* pFrameCount)
{
    if (ppFramesOut != NULL) {
        *ppFramesOut = NULL;    /* Safety. */
    }

    if (pAudioBuffer == NULL) {
        if (pFrameCount != NULL) {
            *pFrameCount = 0;
        }

        return MA_INVALID_ARGS;
    }

    return ma_audio_buffer_ref_map(&pAudioBuffer->ref, ppFramesOut, pFrameCount);
}

MA_API ma_result ma_audio_buffer_unmap(ma_audio_buffer* pAudioBuffer, ma_uint64 frameCount)
{
    if (pAudioBuffer == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_audio_buffer_ref_unmap(&pAudioBuffer->ref, frameCount);
}

MA_API ma_bool32 ma_audio_buffer_at_end(const ma_audio_buffer* pAudioBuffer)
{
    if (pAudioBuffer == NULL) {
        return MA_FALSE;
    }

    return ma_audio_buffer_ref_at_end(&pAudioBuffer->ref);
}

MA_API ma_result ma_audio_buffer_get_cursor_in_pcm_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pCursor)
{
    if (pAudioBuffer == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_audio_buffer_ref_get_cursor_in_pcm_frames(&pAudioBuffer->ref, pCursor);
}

MA_API ma_result ma_audio_buffer_get_length_in_pcm_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pLength)
{
    if (pAudioBuffer == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_audio_buffer_ref_get_length_in_pcm_frames(&pAudioBuffer->ref, pLength);
}

MA_API ma_result ma_audio_buffer_get_available_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pAvailableFrames)
{
    if (pAvailableFrames == NULL) {
        return MA_INVALID_ARGS;
    }

    *pAvailableFrames = 0;

    if (pAudioBuffer == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_audio_buffer_ref_get_available_frames(&pAudioBuffer->ref, pAvailableFrames);
}





MA_API ma_result ma_paged_audio_buffer_data_init(ma_format format, ma_uint32 channels, ma_paged_audio_buffer_data* pData)
{
    if (pData == NULL) {
        return MA_INVALID_ARGS;

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


MA_API ma_paged_audio_buffer_page* ma_paged_audio_buffer_data_get_tail(ma_paged_audio_buffer_data* pData)
{
    if (pData == NULL) {
        return NULL;
    }

    return pData->pTail;
}

MA_API ma_result ma_paged_audio_buffer_data_get_length_in_pcm_frames(ma_paged_audio_buffer_data* pData, ma_uint64* pLength)
{
    ma_paged_audio_buffer_page* pPage;

    if (pLength == NULL) {
        return MA_INVALID_ARGS;
    }

    *pLength = 0;

    if (pData == NULL) {

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

    if (ppPage == NULL) {
        return MA_INVALID_ARGS;
    }

    *ppPage = NULL;

    if (pData == NULL) {
        return MA_INVALID_ARGS;
    }

    allocationSize = sizeof(*pPage) + (pageSizeInFrames * ma_get_bytes_per_frame(pData->format, pData->channels));
    if (allocationSize > MA_SIZE_MAX) {
        return MA_OUT_OF_MEMORY;    /* Too big. */
    }

    pPage = (ma_paged_audio_buffer_page*)ma_malloc((size_t)allocationSize, pAllocationCallbacks);   /* Safe cast to size_t. */
    if (pPage == NULL) {
        return MA_OUT_OF_MEMORY;
    }

    pPage->pNext = NULL;
    pPage->sizeInFrames = pageSizeInFrames;

    if (pInitialData != NULL) {
        ma_copy_pcm_frames(pPage->pAudioData, pInitialData, pageSizeInFrames, pData->format, pData->channels);
    }

    *ppPage = pPage;

    return MA_SUCCESS;
}

MA_API ma_result ma_paged_audio_buffer_data_free_page(ma_paged_audio_buffer_data* pData, ma_paged_audio_buffer_page* pPage, const ma_allocation_callbacks* pAllocationCallbacks)
{
    if (pData == NULL || pPage == NULL) {

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

{
    ma_paged_audio_buffer_config config;

    MA_ZERO_OBJECT(&config);
    config.pData = pData;

    return config;
}


static ma_result ma_paged_audio_buffer__data_source_on_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    return ma_paged_audio_buffer_read_pcm_frames((ma_paged_audio_buffer*)pDataSource, pFramesOut, frameCount, pFramesRead);
}

static ma_result ma_paged_audio_buffer__data_source_on_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    return ma_paged_audio_buffer_seek_to_pcm_frame((ma_paged_audio_buffer*)pDataSource, frameIndex);
}

static ma_result ma_paged_audio_buffer__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    ma_paged_audio_buffer* pPagedAudioBuffer = (ma_paged_audio_buffer*)pDataSource;

    *pFormat     = pPagedAudioBuffer->pData->format;
    *pChannels   = pPagedAudioBuffer->pData->channels;
    *pSampleRate = 0;   /* There is no notion of a sample rate with audio buffers. */
    ma_channel_map_init_standard(ma_standard_channel_map_default, pChannelMap, channelMapCap, pPagedAudioBuffer->pData->channels);

    return MA_SUCCESS;
}

static ma_result ma_paged_audio_buffer__data_source_on_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
{
    return ma_paged_audio_buffer_get_cursor_in_pcm_frames((ma_paged_audio_buffer*)pDataSource, pCursor);
}

static ma_result ma_paged_audio_buffer__data_source_on_get_length(ma_data_source* pDataSource, ma_uint64* pLength)
{
    return ma_paged_audio_buffer_get_length_in_pcm_frames((ma_paged_audio_buffer*)pDataSource, pLength);
}

static ma_data_source_vtable g_ma_paged_audio_buffer_data_source_vtable =
{
    ma_paged_audio_buffer__data_source_on_read,
    ma_paged_audio_buffer__data_source_on_seek,
    ma_paged_audio_buffer__data_source_on_get_data_format,
    ma_paged_audio_buffer__data_source_on_get_cursor,
    ma_paged_audio_buffer__data_source_on_get_length,
    NULL,   /* onSetLooping */

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


MA_API void ma_paged_audio_buffer_uninit(ma_paged_audio_buffer* pPagedAudioBuffer)
{
    if (pPagedAudioBuffer == NULL) {
        return;
    }

    /* Nothing to do. The data needs to be deleted separately. */
}

MA_API ma_result ma_paged_audio_buffer_read_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_result result = MA_SUCCESS;
    ma_uint64 totalFramesRead = 0;
    ma_format format;
    ma_uint32 channels;

    if (pPagedAudioBuffer == NULL) {
        return MA_INVALID_ARGS;
    }

    format   = pPagedAudioBuffer->pData->format;
    channels = pPagedAudioBuffer->pData->channels;

    while (totalFramesRead < frameCount) {
        /* Read from the current page. The buffer should never be in a state where this is NULL. */
        ma_uint64 framesRemainingInCurrentPage;
        ma_uint64 framesRemainingToRead = frameCount - totalFramesRead;
        ma_uint64 framesToReadThisIteration;

        MA_ASSERT(pPagedAudioBuffer->pCurrent != NULL);

        framesRemainingInCurrentPage = pPagedAudioBuffer->pCurrent->sizeInFrames - pPagedAudioBuffer->relativeCursor;

        framesToReadThisIteration = ma_min(framesRemainingInCurrentPage, framesRemainingToRead);
        ma_copy_pcm_frames(ma_offset_pcm_frames_ptr(pFramesOut, totalFramesRead, format, channels), ma_offset_pcm_frames_ptr(pPagedAudioBuffer->pCurrent->pAudioData, pPagedAudioBuffer->relativeCursor, format, channels), framesToReadThisIteration, for...
        totalFramesRead += framesToReadThisIteration;

        pPagedAudioBuffer->absoluteCursor += framesToReadThisIteration;
        pPagedAudioBuffer->relativeCursor += framesToReadThisIteration;

        /* Move to the next page if necessary. If there's no more pages, we need to return MA_AT_END. */
        MA_ASSERT(pPagedAudioBuffer->relativeCursor <= pPagedAudioBuffer->pCurrent->sizeInFrames);

        if (pPagedAudioBuffer->relativeCursor == pPagedAudioBuffer->pCurrent->sizeInFrames) {
            /* We reached the end of the page. Need to move to the next. If there's no more pages, we're done. */
            ma_paged_audio_buffer_page* pNext = (ma_paged_audio_buffer_page*)c89atomic_load_ptr(&pPagedAudioBuffer->pCurrent->pNext);
            if (pNext == NULL) {
                result = MA_AT_END;
                break;  /* We've reached the end. */

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

        }
    }

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

    return result;
}

MA_API ma_result ma_paged_audio_buffer_seek_to_pcm_frame(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64 frameIndex)
{
    if (pPagedAudioBuffer == NULL) {
        return MA_INVALID_ARGS;
    }

    if (frameIndex == pPagedAudioBuffer->absoluteCursor) {
        return MA_SUCCESS;  /* Nothing to do. */
    }

    if (frameIndex < pPagedAudioBuffer->absoluteCursor) {
        /* Moving backwards. Need to move the cursor back to the start, and then move forward. */
        pPagedAudioBuffer->pCurrent       = ma_paged_audio_buffer_data_get_head(pPagedAudioBuffer->pData);
        pPagedAudioBuffer->absoluteCursor = 0;
        pPagedAudioBuffer->relativeCursor = 0;

        /* Fall through to the forward seeking section below. */
    }

    if (frameIndex > pPagedAudioBuffer->absoluteCursor) {
        /* Moving forward. */
        ma_paged_audio_buffer_page* pPage;
        ma_uint64 runningCursor = 0;

        for (pPage = (ma_paged_audio_buffer_page*)c89atomic_load_ptr(&ma_paged_audio_buffer_data_get_head(pPagedAudioBuffer->pData)->pNext); pPage != NULL; pPage = (ma_paged_audio_buffer_page*)c89atomic_load_ptr(&pPage->pNext)) {
            ma_uint64 pageRangeBeg = runningCursor;
            ma_uint64 pageRangeEnd = pageRangeBeg + pPage->sizeInFrames;

            if (frameIndex >= pageRangeBeg) {
                if (frameIndex < pageRangeEnd || (frameIndex == pageRangeEnd && pPage == (ma_paged_audio_buffer_page*)c89atomic_load_ptr(ma_paged_audio_buffer_data_get_tail(pPagedAudioBuffer->pData)))) {  /* A small edge case - allow seeking to the v...
                    /* We found the page. */
                    pPagedAudioBuffer->pCurrent       = pPage;
                    pPagedAudioBuffer->absoluteCursor = frameIndex;
                    pPagedAudioBuffer->relativeCursor = frameIndex - pageRangeBeg;
                    return MA_SUCCESS;
                }
            }

            runningCursor = pageRangeEnd;
        }

        /* Getting here means we tried seeking too far forward. Don't change any state. */
        return MA_BAD_SEEK;
    }

    return MA_SUCCESS;
}

MA_API ma_result ma_paged_audio_buffer_get_cursor_in_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64* pCursor)
{
    if (pCursor == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = 0;   /* Safety. */

    if (pPagedAudioBuffer == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = pPagedAudioBuffer->absoluteCursor;

    return MA_SUCCESS;
}

MA_API ma_result ma_paged_audio_buffer_get_length_in_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64* pLength)
{
    return ma_paged_audio_buffer_data_get_length_in_pcm_frames(pPagedAudioBuffer->pData, pLength);
}



/**************************************************************************************************************************************************************

VFS

**************************************************************************************************************************************************************/
MA_API ma_result ma_vfs_open(ma_vfs* pVFS, const char* pFilePath, ma_uint32 openMode, ma_vfs_file* pFile)

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

        drwav_int32  stepIndex[2];
        drwav_int32  cachedFrames[16];
        drwav_uint32 cachedFrameCount;
    } ima;
} drwav;
DRWAV_API drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_ex(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, drwav_chunk_proc onChunk, void* pReadSeekUserData, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_with_metadata(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_write_sequential(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_write_sequential_pcm_frames(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_write_with_metadata(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks, drwav_metadata* pMetadata,...
DRWAV_API drwav_uint64 drwav_target_write_size_bytes(const drwav_data_format* pFormat, drwav_uint64 totalFrameCount, drwav_metadata* pMetadata, drwav_uint32 metadataCount);
DRWAV_API drwav_metadata* drwav_take_ownership_of_metadata(drwav* pWav);
DRWAV_API drwav_result drwav_uninit(drwav* pWav);
DRWAV_API size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_le(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
DRWAV_API drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64 targetFrameIndex);
DRWAV_API drwav_result drwav_get_cursor_in_pcm_frames(drwav* pWav, drwav_uint64* pCursor);
DRWAV_API drwav_result drwav_get_length_in_pcm_frames(drwav* pWav, drwav_uint64* pLength);
DRWAV_API size_t drwav_write_raw(drwav* pWav, size_t bytesToWrite, const void* pData);
DRWAV_API drwav_uint64 drwav_write_pcm_frames(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
DRWAV_API drwav_uint64 drwav_write_pcm_frames_le(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
DRWAV_API drwav_uint64 drwav_write_pcm_frames_be(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
#ifndef DR_WAV_NO_CONVERSION_API
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16le(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16be(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut);
DRWAV_API void drwav_u8_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s24_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s32_to_s16(drwav_int16* pOut, const drwav_int32* pIn, size_t sampleCount);
DRWAV_API void drwav_f32_to_s16(drwav_int16* pOut, const float* pIn, size_t sampleCount);
DRWAV_API void drwav_f64_to_s16(drwav_int16* pOut, const double* pIn, size_t sampleCount);
DRWAV_API void drwav_alaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_mulaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32le(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32be(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
DRWAV_API void drwav_u8_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s16_to_f32(float* pOut, const drwav_int16* pIn, size_t sampleCount);
DRWAV_API void drwav_s24_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s32_to_f32(float* pOut, const drwav_int32* pIn, size_t sampleCount);
DRWAV_API void drwav_f64_to_f32(float* pOut, const double* pIn, size_t sampleCount);
DRWAV_API void drwav_alaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_mulaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32le(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32be(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut);
DRWAV_API void drwav_u8_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s16_to_s32(drwav_int32* pOut, const drwav_int16* pIn, size_t sampleCount);
DRWAV_API void drwav_s24_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_f32_to_s32(drwav_int32* pOut, const float* pIn, size_t sampleCount);
DRWAV_API void drwav_f64_to_s32(drwav_int32* pOut, const double* pIn, size_t sampleCount);
DRWAV_API void drwav_alaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_mulaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
#endif
#ifndef DR_WAV_NO_STDIO
DRWAV_API drwav_bool32 drwav_init_file(drwav* pWav, const char* filename, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_ex(drwav* pWav, const char* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_w(drwav* pWav, const wchar_t* filename, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_ex_w(drwav* pWav, const wchar_t* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_with_metadata(drwav* pWav, const char* filename, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_with_metadata_w(drwav* pWav, const wchar_t* filename, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_sequential(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
#endif
DRWAV_API drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, size_t dataSize, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_ex(drwav* pWav, const void* data, size_t dataSize, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_with_metadata(drwav* pWav, const void* data, size_t dataSize, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential_pcm_frames(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
#ifndef DR_WAV_NO_CONVERSION_API
DRWAV_API drwav_int16* drwav_open_and_read_pcm_frames_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAl...
DRWAV_API float* drwav_open_and_read_pcm_frames_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocati...
DRWAV_API drwav_int32* drwav_open_and_read_pcm_frames_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAl...
#ifndef DR_WAV_NO_STDIO
DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
#endif
DRWAV_API drwav_int16* drwav_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API float* drwav_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int32* drwav_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
#endif
DRWAV_API void drwav_free(void* p, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_uint16 drwav_bytes_to_u16(const drwav_uint8* data);
DRWAV_API drwav_int16 drwav_bytes_to_s16(const drwav_uint8* data);
DRWAV_API drwav_uint32 drwav_bytes_to_u32(const drwav_uint8* data);
DRWAV_API drwav_int32 drwav_bytes_to_s32(const drwav_uint8* data);
DRWAV_API drwav_uint64 drwav_bytes_to_u64(const drwav_uint8* data);
DRWAV_API drwav_int64 drwav_bytes_to_s64(const drwav_uint8* data);
DRWAV_API float drwav_bytes_to_f32(const drwav_uint8* data);
DRWAV_API drwav_bool32 drwav_guid_equal(const drwav_uint8 a[16], const drwav_uint8 b[16]);

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

    drflac_uint32 nextL2Line;
    drflac_uint32 consumedBits;
    drflac_cache_t cacheL2[DR_FLAC_BUFFER_SIZE/sizeof(drflac_cache_t)];
    drflac_cache_t cache;
    drflac_uint16 crc16;
    drflac_cache_t crc16Cache;
    drflac_uint32 crc16CacheIgnoredBytes;
} drflac_bs;
typedef struct
{
    drflac_uint8 subframeType;
    drflac_uint8 wastedBitsPerSample;
    drflac_uint8 lpcOrder;
    drflac_int32* pSamplesS32;
} drflac_subframe;
typedef struct
{
    drflac_uint64 pcmFrameNumber;
    drflac_uint32 flacFrameNumber;
    drflac_uint32 sampleRate;
    drflac_uint16 blockSizeInPCMFrames;
    drflac_uint8 channelAssignment;
    drflac_uint8 bitsPerSample;
    drflac_uint8 crc8;
} drflac_frame_header;
typedef struct
{
    drflac_frame_header header;
    drflac_uint32 pcmFramesRemaining;
    drflac_subframe subframes[8];
} drflac_frame;
typedef struct
{
    drflac_meta_proc onMeta;
    void* pUserDataMD;
    drflac_allocation_callbacks allocationCallbacks;
    drflac_uint32 sampleRate;
    drflac_uint8 channels;
    drflac_uint8 bitsPerSample;
    drflac_uint16 maxBlockSizeInPCMFrames;
    drflac_uint64 totalPCMFrameCount;
    drflac_container container;
    drflac_uint32 seekpointCount;
    drflac_frame currentFLACFrame;
    drflac_uint64 currentPCMFrame;
    drflac_uint64 firstFLACFramePosInBytes;
    drflac__memory_stream memoryStream;
    drflac_int32* pDecodedSamples;
    drflac_seekpoint* pSeekpoints;
    void* _oggbs;
    drflac_bool32 _noSeekTableSeek    : 1;
    drflac_bool32 _noBinarySearchSeek : 1;
    drflac_bool32 _noBruteForceSeek   : 1;
    drflac_bs bs;
    drflac_uint8 pExtraData[1];
} drflac;
DRFLAC_API drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API void drflac_close(drflac* pFlac);
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut);
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut);
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut);
DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex);
#ifndef DR_FLAC_NO_STDIO
DRFLAC_API drflac* drflac_open_file(const char* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_file_with_metadata(const char* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_file_with_metadata_w(const wchar_t* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
#endif
DRFLAC_API drflac* drflac_open_memory(const void* pData, size_t dataSize, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_memory_with_metadata(const void* pData, size_t dataSize, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pA...
DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pA...
DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocati...
#ifndef DR_FLAC_NO_STDIO
DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
#endif
DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API void drflac_free(void* p, const drflac_allocation_callbacks* pAllocationCallbacks);
typedef struct
{
    drflac_uint32 countRemaining;
    const char* pRunningData;
} drflac_vorbis_comment_iterator;
DRFLAC_API void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments);
DRFLAC_API const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut);
typedef struct
{

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

    #endif
#elif defined(__WATCOMC__)
    #define DRMP3_INLINE __inline
#else
    #define DRMP3_INLINE
#endif
DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision);
DRMP3_API const char* drmp3_version_string(void);
typedef struct
{
    int frame_bytes, channels, hz, layer, bitrate_kbps;
} drmp3dec_frame_info;
typedef struct
{
    float mdct_overlap[2][9*32], qmf_state[15*2*32];
    int reserv, free_format_bytes;
    drmp3_uint8 header[4], reserv_buf[511];
} drmp3dec;
DRMP3_API void drmp3dec_init(drmp3dec *dec);
DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info);
DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples);
typedef enum
{
    drmp3_seek_origin_start,
    drmp3_seek_origin_current
} drmp3_seek_origin;
typedef struct
{
    drmp3_uint64 seekPosInBytes;
    drmp3_uint64 pcmFrameIndex;

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

    void  (* onFree)(void* p, void* pUserData);
} drmp3_allocation_callbacks;
typedef struct
{
    drmp3_uint32 channels;
    drmp3_uint32 sampleRate;
} drmp3_config;
typedef struct
{
    drmp3dec decoder;
    drmp3dec_frame_info frameInfo;
    drmp3_uint32 channels;
    drmp3_uint32 sampleRate;
    drmp3_read_proc onRead;
    drmp3_seek_proc onSeek;
    void* pUserData;
    drmp3_allocation_callbacks allocationCallbacks;
    drmp3_uint32 mp3FrameChannels;
    drmp3_uint32 mp3FrameSampleRate;
    drmp3_uint32 pcmFramesConsumedInMP3Frame;
    drmp3_uint32 pcmFramesRemainingInMP3Frame;

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

        size_t currentReadPos;
    } memory;
} drmp3;
DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks);
#ifndef DR_MP3_NO_STDIO
DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
#endif
DRMP3_API void drmp3_uninit(drmp3* pMP3);
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut);
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut);
DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex);
DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3);
DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3);
DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount);
DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints);
DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints);
DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
#ifndef DR_MP3_NO_STDIO
DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
#endif
DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks);
#ifdef __cplusplus
}
#endif
#endif
/* dr_mp3_h end */
#endif  /* MA_NO_MP3 */

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

    converterConfig.allowDynamicSampleRate = MA_FALSE;   /* Never allow dynamic sample rate conversion. Setting this to true will disable passthrough optimizations. */
    converterConfig.resampling             = pConfig->resampling;

    result = ma_data_converter_init(&converterConfig, &pDecoder->allocationCallbacks, &pDecoder->converter);
    if (result != MA_SUCCESS) {
        return result;
    }

    /*
    Now that we have the decoder we need to determine whether or not we need a heap-allocated cache. We'll
    need this if the data converter does not support calculation of the required input frame count. To
    determine support for this we'll just run a test.
    */
    {
        ma_uint64 unused;

        result = ma_data_converter_get_required_input_frame_count(&pDecoder->converter, 1, &unused);
        if (result != MA_SUCCESS) {
            /*
            We were unable to calculate the required input frame count which means we'll need to use
            a heap-allocated cache.
            */
            ma_uint64 inputCacheCapSizeInBytes;

            pDecoder->inputCacheCap = MA_DATA_CONVERTER_STACK_BUFFER_SIZE / ma_get_bytes_per_frame(internalFormat, internalChannels);

            /* Not strictly necessary, but keeping here for safety in case we change the default value of pDecoder->inputCacheCap. */
            inputCacheCapSizeInBytes = pDecoder->inputCacheCap * ma_get_bytes_per_frame(internalFormat, internalChannels);
            if (inputCacheCapSizeInBytes > MA_SIZE_MAX) {
                ma_data_converter_uninit(&pDecoder->converter, &pDecoder->allocationCallbacks);
                return MA_OUT_OF_MEMORY;
            }

            pDecoder->pInputCache = ma_malloc((size_t)inputCacheCapSizeInBytes, &pDecoder->allocationCallbacks);    /* Safe cast to size_t. */
            if (pDecoder->pInputCache == NULL) {
                ma_data_converter_uninit(&pDecoder->converter, &pDecoder->allocationCallbacks);
                return MA_OUT_OF_MEMORY;
            }

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

#if !defined(MA_NO_WAV)
    drwav dr;
#endif
} ma_wav;

MA_API ma_result ma_wav_init(ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void* pReadSeekTellUserData, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_wav* pWav);
MA_API ma_result ma_wav_init_file(const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_wav* pWav);
MA_API ma_result ma_wav_init_file_w(const wchar_t* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_wav* pWav);
MA_API ma_result ma_wav_init_memory(const void* pData, size_t dataSize, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_wav* pWav);
MA_API void ma_wav_uninit(ma_wav* pWav, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_wav_read_pcm_frames(ma_wav* pWav, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_wav_seek_to_pcm_frame(ma_wav* pWav, ma_uint64 frameIndex);
MA_API ma_result ma_wav_get_data_format(ma_wav* pWav, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_wav_get_cursor_in_pcm_frames(ma_wav* pWav, ma_uint64* pCursor);
MA_API ma_result ma_wav_get_length_in_pcm_frames(ma_wav* pWav, ma_uint64* pLength);


static ma_result ma_wav_ds_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    return ma_wav_read_pcm_frames((ma_wav*)pDataSource, pFramesOut, frameCount, pFramesRead);
}

static ma_result ma_wav_ds_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    return ma_wav_seek_to_pcm_frame((ma_wav*)pDataSource, frameIndex);
}

static ma_result ma_wav_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    return ma_wav_get_data_format((ma_wav*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
}

static ma_result ma_wav_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
{
    return ma_wav_get_cursor_in_pcm_frames((ma_wav*)pDataSource, pCursor);
}

static ma_result ma_wav_ds_get_length(ma_data_source* pDataSource, ma_uint64* pLength)
{
    return ma_wav_get_length_in_pcm_frames((ma_wav*)pDataSource, pLength);
}

static ma_data_source_vtable g_ma_wav_ds_vtable =
{
    ma_wav_ds_read,
    ma_wav_ds_seek,
    ma_wav_ds_get_data_format,
    ma_wav_ds_get_cursor,
    ma_wav_ds_get_length,
    NULL,   /* onSetLooping */

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

    #else
    {
        /* wav is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);
    }
    #endif

    ma_data_source_uninit(&pWav->ds);
}

MA_API ma_result ma_wav_read_pcm_frames(ma_wav* pWav, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    if (pFramesRead != NULL) {
        *pFramesRead = 0;
    }

    if (frameCount == 0) {
        return MA_INVALID_ARGS;
    }

    if (pWav == NULL) {
        return MA_INVALID_ARGS;
    }

    #if !defined(MA_NO_WAV)
    {
        /* We always use floating point format. */
        ma_result result = MA_SUCCESS;  /* Must be initialized to MA_SUCCESS. */
        ma_uint64 totalFramesRead = 0;
        ma_format format;

        ma_wav_get_data_format(pWav, &format, NULL, NULL, NULL, 0);

        switch (format)
        {
            case ma_format_f32:
            {
                totalFramesRead = drwav_read_pcm_frames_f32(&pWav->dr, frameCount, (float*)pFramesOut);
            } break;

            case ma_format_s16:
            {
                totalFramesRead = drwav_read_pcm_frames_s16(&pWav->dr, frameCount, (drwav_int16*)pFramesOut);
            } break;

            case ma_format_s32:
            {
                totalFramesRead = drwav_read_pcm_frames_s32(&pWav->dr, frameCount, (drwav_int32*)pFramesOut);
            } break;

            /* Fallback to a raw read. */
            case ma_format_unknown: return MA_INVALID_OPERATION; /* <-- this should never be hit because initialization would just fall back to a supported format. */
            default:
            {
                totalFramesRead = drwav_read_pcm_frames(&pWav->dr, frameCount, pFramesOut);
            } break;
        }

        /* In the future we'll update dr_wav to return MA_AT_END for us. */
        if (totalFramesRead == 0) {
            result = MA_AT_END;
        }

        if (pFramesRead != NULL) {
            *pFramesRead = totalFramesRead;

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

        }

        return result;
    }
    #else
    {
        /* wav is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);

        (void)pFramesOut;
        (void)frameCount;
        (void)pFramesRead;

        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_wav_seek_to_pcm_frame(ma_wav* pWav, ma_uint64 frameIndex)
{
    if (pWav == NULL) {
        return MA_INVALID_ARGS;
    }

    #if !defined(MA_NO_WAV)
    {
        drwav_bool32 wavResult;

        wavResult = drwav_seek_to_pcm_frame(&pWav->dr, frameIndex);
        if (wavResult != DRWAV_TRUE) {
            return MA_ERROR;
        }

        return MA_SUCCESS;
    }
    #else
    {
        /* wav is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);

        (void)frameIndex;

        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_wav_get_data_format(ma_wav* pWav, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    /* Defaults for safety. */
    if (pFormat != NULL) {

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

    }
    #else
    {
        /* wav is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);
        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_wav_get_cursor_in_pcm_frames(ma_wav* pWav, ma_uint64* pCursor)
{
    if (pCursor == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = 0;   /* Safety. */

    if (pWav == NULL) {
        return MA_INVALID_ARGS;
    }

    #if !defined(MA_NO_WAV)
    {
        drwav_result wavResult = drwav_get_cursor_in_pcm_frames(&pWav->dr, pCursor);
        if (wavResult != DRWAV_SUCCESS) {
            return (ma_result)wavResult;    /* dr_wav result codes map to miniaudio's. */
        }

        return MA_SUCCESS;
    }
    #else
    {
        /* wav is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);
        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_wav_get_length_in_pcm_frames(ma_wav* pWav, ma_uint64* pLength)
{
    if (pLength == NULL) {
        return MA_INVALID_ARGS;
    }

    *pLength = 0;   /* Safety. */

    if (pWav == NULL) {
        return MA_INVALID_ARGS;
    }

    #if !defined(MA_NO_WAV)
    {
        drwav_result wavResult = drwav_get_length_in_pcm_frames(&pWav->dr, pLength);
        if (wavResult != DRWAV_SUCCESS) {
            return (ma_result)wavResult;    /* dr_wav result codes map to miniaudio's. */
        }

        return MA_SUCCESS;
    }
    #else
    {
        /* wav is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);

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

#if !defined(MA_NO_FLAC)
    drflac* dr;
#endif
} ma_flac;

MA_API ma_result ma_flac_init(ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void* pReadSeekTellUserData, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_flac* pFlac);
MA_API ma_result ma_flac_init_file(const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_flac* pFlac);
MA_API ma_result ma_flac_init_file_w(const wchar_t* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_flac* pFlac);
MA_API ma_result ma_flac_init_memory(const void* pData, size_t dataSize, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_flac* pFlac);
MA_API void ma_flac_uninit(ma_flac* pFlac, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_flac_read_pcm_frames(ma_flac* pFlac, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_flac_seek_to_pcm_frame(ma_flac* pFlac, ma_uint64 frameIndex);
MA_API ma_result ma_flac_get_data_format(ma_flac* pFlac, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_flac_get_cursor_in_pcm_frames(ma_flac* pFlac, ma_uint64* pCursor);
MA_API ma_result ma_flac_get_length_in_pcm_frames(ma_flac* pFlac, ma_uint64* pLength);


static ma_result ma_flac_ds_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    return ma_flac_read_pcm_frames((ma_flac*)pDataSource, pFramesOut, frameCount, pFramesRead);
}

static ma_result ma_flac_ds_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    return ma_flac_seek_to_pcm_frame((ma_flac*)pDataSource, frameIndex);
}

static ma_result ma_flac_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    return ma_flac_get_data_format((ma_flac*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
}

static ma_result ma_flac_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
{
    return ma_flac_get_cursor_in_pcm_frames((ma_flac*)pDataSource, pCursor);
}

static ma_result ma_flac_ds_get_length(ma_data_source* pDataSource, ma_uint64* pLength)
{
    return ma_flac_get_length_in_pcm_frames((ma_flac*)pDataSource, pLength);
}

static ma_data_source_vtable g_ma_flac_ds_vtable =
{
    ma_flac_ds_read,
    ma_flac_ds_seek,
    ma_flac_ds_get_data_format,
    ma_flac_ds_get_cursor,
    ma_flac_ds_get_length,
    NULL,   /* onSetLooping */

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

    #else
    {
        /* flac is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);
    }
    #endif

    ma_data_source_uninit(&pFlac->ds);
}

MA_API ma_result ma_flac_read_pcm_frames(ma_flac* pFlac, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    if (pFramesRead != NULL) {
        *pFramesRead = 0;
    }

    if (frameCount == 0) {
        return MA_INVALID_ARGS;
    }

    if (pFlac == NULL) {
        return MA_INVALID_ARGS;
    }

    #if !defined(MA_NO_FLAC)
    {
        /* We always use floating point format. */
        ma_result result = MA_SUCCESS;  /* Must be initialized to MA_SUCCESS. */
        ma_uint64 totalFramesRead = 0;
        ma_format format;

        ma_flac_get_data_format(pFlac, &format, NULL, NULL, NULL, 0);

        switch (format)
        {
            case ma_format_f32:
            {
                totalFramesRead = drflac_read_pcm_frames_f32(pFlac->dr, frameCount, (float*)pFramesOut);
            } break;

            case ma_format_s16:
            {
                totalFramesRead = drflac_read_pcm_frames_s16(pFlac->dr, frameCount, (drflac_int16*)pFramesOut);
            } break;

            case ma_format_s32:
            {
                totalFramesRead = drflac_read_pcm_frames_s32(pFlac->dr, frameCount, (drflac_int32*)pFramesOut);
            } break;

            case ma_format_u8:
            case ma_format_s24:
            case ma_format_unknown:
            default:
            {
                return MA_INVALID_OPERATION;
            };
        }

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

        }

        return result;
    }
    #else
    {
        /* flac is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);

        (void)pFramesOut;
        (void)frameCount;
        (void)pFramesRead;

        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_flac_seek_to_pcm_frame(ma_flac* pFlac, ma_uint64 frameIndex)
{
    if (pFlac == NULL) {
        return MA_INVALID_ARGS;
    }

    #if !defined(MA_NO_FLAC)
    {
        drflac_bool32 flacResult;

        flacResult = drflac_seek_to_pcm_frame(pFlac->dr, frameIndex);
        if (flacResult != DRFLAC_TRUE) {
            return MA_ERROR;
        }

        return MA_SUCCESS;
    }
    #else
    {
        /* flac is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);

        (void)frameIndex;

        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_flac_get_data_format(ma_flac* pFlac, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    /* Defaults for safety. */
    if (pFormat != NULL) {

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

    }
    #else
    {
        /* flac is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);
        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_flac_get_cursor_in_pcm_frames(ma_flac* pFlac, ma_uint64* pCursor)
{
    if (pCursor == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = 0;   /* Safety. */

    if (pFlac == NULL) {
        return MA_INVALID_ARGS;
    }

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

    }
    #else
    {
        /* flac is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);
        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_flac_get_length_in_pcm_frames(ma_flac* pFlac, ma_uint64* pLength)
{
    if (pLength == NULL) {
        return MA_INVALID_ARGS;
    }

    *pLength = 0;   /* Safety. */

    if (pFlac == NULL) {
        return MA_INVALID_ARGS;
    }

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

    drmp3_uint32 seekPointCount;
    drmp3_seek_point* pSeekPoints;  /* Only used if seek table generation is used. */
#endif
} ma_mp3;

MA_API ma_result ma_mp3_init(ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void* pReadSeekTellUserData, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_mp3* pMP3);
MA_API ma_result ma_mp3_init_file(const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_mp3* pMP3);
MA_API ma_result ma_mp3_init_file_w(const wchar_t* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_mp3* pMP3);
MA_API ma_result ma_mp3_init_memory(const void* pData, size_t dataSize, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_mp3* pMP3);
MA_API void ma_mp3_uninit(ma_mp3* pMP3, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_mp3_read_pcm_frames(ma_mp3* pMP3, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_mp3_seek_to_pcm_frame(ma_mp3* pMP3, ma_uint64 frameIndex);
MA_API ma_result ma_mp3_get_data_format(ma_mp3* pMP3, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_mp3_get_cursor_in_pcm_frames(ma_mp3* pMP3, ma_uint64* pCursor);
MA_API ma_result ma_mp3_get_length_in_pcm_frames(ma_mp3* pMP3, ma_uint64* pLength);


static ma_result ma_mp3_ds_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    return ma_mp3_read_pcm_frames((ma_mp3*)pDataSource, pFramesOut, frameCount, pFramesRead);
}

static ma_result ma_mp3_ds_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    return ma_mp3_seek_to_pcm_frame((ma_mp3*)pDataSource, frameIndex);
}

static ma_result ma_mp3_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    return ma_mp3_get_data_format((ma_mp3*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
}

static ma_result ma_mp3_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
{
    return ma_mp3_get_cursor_in_pcm_frames((ma_mp3*)pDataSource, pCursor);
}

static ma_result ma_mp3_ds_get_length(ma_data_source* pDataSource, ma_uint64* pLength)
{
    return ma_mp3_get_length_in_pcm_frames((ma_mp3*)pDataSource, pLength);
}

static ma_data_source_vtable g_ma_mp3_ds_vtable =
{
    ma_mp3_ds_read,
    ma_mp3_ds_seek,
    ma_mp3_ds_get_data_format,
    ma_mp3_ds_get_cursor,
    ma_mp3_ds_get_length,
    NULL,   /* onSetLooping */

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

        MA_ASSERT(MA_FALSE);
    }
    #endif

    /* Seek points need to be freed after the MP3 decoder has been uninitialized to ensure they're no longer being referenced. */
    ma_free(pMP3->pSeekPoints, pAllocationCallbacks);

    ma_data_source_uninit(&pMP3->ds);
}

MA_API ma_result ma_mp3_read_pcm_frames(ma_mp3* pMP3, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    if (pFramesRead != NULL) {
        *pFramesRead = 0;
    }

    if (frameCount == 0) {
        return MA_INVALID_ARGS;
    }

    if (pMP3 == NULL) {
        return MA_INVALID_ARGS;
    }

    #if !defined(MA_NO_MP3)
    {
        /* We always use floating point format. */
        ma_result result = MA_SUCCESS;  /* Must be initialized to MA_SUCCESS. */
        ma_uint64 totalFramesRead = 0;
        ma_format format;

        ma_mp3_get_data_format(pMP3, &format, NULL, NULL, NULL, 0);

        switch (format)
        {
            case ma_format_f32:
            {
                totalFramesRead = drmp3_read_pcm_frames_f32(&pMP3->dr, frameCount, (float*)pFramesOut);
            } break;

            case ma_format_s16:
            {
                totalFramesRead = drmp3_read_pcm_frames_s16(&pMP3->dr, frameCount, (drmp3_int16*)pFramesOut);
            } break;

            case ma_format_u8:
            case ma_format_s24:
            case ma_format_s32:
            case ma_format_unknown:
            default:
            {
                return MA_INVALID_OPERATION;
            };

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

        }

        return result;
    }
    #else
    {
        /* mp3 is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);

        (void)pFramesOut;
        (void)frameCount;
        (void)pFramesRead;

        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_mp3_seek_to_pcm_frame(ma_mp3* pMP3, ma_uint64 frameIndex)
{
    if (pMP3 == NULL) {
        return MA_INVALID_ARGS;
    }

    #if !defined(MA_NO_MP3)
    {
        drmp3_bool32 mp3Result;

        mp3Result = drmp3_seek_to_pcm_frame(&pMP3->dr, frameIndex);
        if (mp3Result != DRMP3_TRUE) {
            return MA_ERROR;
        }

        return MA_SUCCESS;
    }
    #else
    {
        /* mp3 is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);

        (void)frameIndex;

        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_mp3_get_data_format(ma_mp3* pMP3, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    /* Defaults for safety. */
    if (pFormat != NULL) {

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

    }
    #else
    {
        /* mp3 is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);
        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_mp3_get_cursor_in_pcm_frames(ma_mp3* pMP3, ma_uint64* pCursor)
{
    if (pCursor == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = 0;   /* Safety. */

    if (pMP3 == NULL) {
        return MA_INVALID_ARGS;
    }

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

    }
    #else
    {
        /* mp3 is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);
        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_mp3_get_length_in_pcm_frames(ma_mp3* pMP3, ma_uint64* pLength)
{
    if (pLength == NULL) {
        return MA_INVALID_ARGS;
    }

    *pLength = 0;   /* Safety. */

    if (pMP3 == NULL) {
        return MA_INVALID_ARGS;
    }

    #if !defined(MA_NO_MP3)
    {
        *pLength = drmp3_get_pcm_frame_count(&pMP3->dr);

        return MA_SUCCESS;
    }
    #else
    {
        /* mp3 is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);
        return MA_NOT_IMPLEMENTED;
    }
    #endif

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

/* The size in bytes of each chunk of data to read from the Vorbis stream. */
#define MA_VORBIS_DATA_CHUNK_SIZE  4096

typedef struct
{
    ma_data_source_base ds;
    ma_read_proc onRead;
    ma_seek_proc onSeek;
    ma_tell_proc onTell;
    void* pReadSeekTellUserData;
    ma_allocation_callbacks allocationCallbacks;    /* Store the allocation callbacks within the structure because we may need to dynamically expand a buffer in ma_stbvorbis_read_pcm_frames() when using push mode. */
    ma_format format;               /* Only f32 is allowed with stb_vorbis. */
    ma_uint32 channels;
    ma_uint32 sampleRate;
    ma_uint64 cursor;
#if !defined(MA_NO_VORBIS)
    stb_vorbis* stb;
    ma_bool32 usingPushMode;
    struct
    {
        ma_uint8* pData;
        size_t dataSize;
        size_t dataCapacity;
        ma_uint32 framesConsumed;   /* The number of frames consumed in ppPacketData. */
        ma_uint32 framesRemaining;  /* The number of frames remaining in ppPacketData. */
        float** ppPacketData;
    } push;
#endif
} ma_stbvorbis;

MA_API ma_result ma_stbvorbis_init(ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void* pReadSeekTellUserData, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_stbvorbis* pVorbis);
MA_API ma_result ma_stbvorbis_init_file(const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_stbvorbis* pVorbis);
MA_API ma_result ma_stbvorbis_init_memory(const void* pData, size_t dataSize, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_stbvorbis* pVorbis);
MA_API void ma_stbvorbis_uninit(ma_stbvorbis* pVorbis, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_stbvorbis_read_pcm_frames(ma_stbvorbis* pVorbis, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_stbvorbis_seek_to_pcm_frame(ma_stbvorbis* pVorbis, ma_uint64 frameIndex);
MA_API ma_result ma_stbvorbis_get_data_format(ma_stbvorbis* pVorbis, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_stbvorbis_get_cursor_in_pcm_frames(ma_stbvorbis* pVorbis, ma_uint64* pCursor);
MA_API ma_result ma_stbvorbis_get_length_in_pcm_frames(ma_stbvorbis* pVorbis, ma_uint64* pLength);


static ma_result ma_stbvorbis_ds_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    return ma_stbvorbis_read_pcm_frames((ma_stbvorbis*)pDataSource, pFramesOut, frameCount, pFramesRead);
}

static ma_result ma_stbvorbis_ds_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    return ma_stbvorbis_seek_to_pcm_frame((ma_stbvorbis*)pDataSource, frameIndex);
}

static ma_result ma_stbvorbis_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    return ma_stbvorbis_get_data_format((ma_stbvorbis*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
}

static ma_result ma_stbvorbis_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
{
    return ma_stbvorbis_get_cursor_in_pcm_frames((ma_stbvorbis*)pDataSource, pCursor);
}

static ma_result ma_stbvorbis_ds_get_length(ma_data_source* pDataSource, ma_uint64* pLength)
{
    return ma_stbvorbis_get_length_in_pcm_frames((ma_stbvorbis*)pDataSource, pLength);
}

static ma_data_source_vtable g_ma_stbvorbis_ds_vtable =
{
    ma_stbvorbis_ds_read,
    ma_stbvorbis_ds_seek,
    ma_stbvorbis_ds_get_data_format,
    ma_stbvorbis_ds_get_cursor,
    ma_stbvorbis_ds_get_length,
    NULL,   /* onSetLooping */

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

    #else
    {
        /* vorbis is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);
    }
    #endif

    ma_data_source_uninit(&pVorbis->ds);
}

MA_API ma_result ma_stbvorbis_read_pcm_frames(ma_stbvorbis* pVorbis, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    if (pFramesRead != NULL) {
        *pFramesRead = 0;
    }

    if (frameCount == 0) {
        return MA_INVALID_ARGS;
    }

    if (pVorbis == NULL) {
        return MA_INVALID_ARGS;
    }

    #if !defined(MA_NO_VORBIS)
    {
        /* We always use floating point format. */

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

        ma_uint32 channels;

        ma_stbvorbis_get_data_format(pVorbis, &format, &channels, NULL, NULL, 0);

        if (format == ma_format_f32) {
            /* We read differently depending on whether or not we're using push mode. */
            if (pVorbis->usingPushMode) {
                /* Push mode. This is the complex case. */
                float* pFramesOutF32 = (float*)pFramesOut;

                while (totalFramesRead < frameCount) {
                    /* The first thing to do is read from any already-cached frames. */
                    ma_uint32 framesToReadFromCache = (ma_uint32)ma_min(pVorbis->push.framesRemaining, (frameCount - totalFramesRead));  /* Safe cast because pVorbis->framesRemaining is 32-bit. */

                    /* The output pointer can be null in which case we just treate it as a seek. */
                    if (pFramesOut != NULL) {
                        ma_uint64 iFrame;
                        for (iFrame = 0; iFrame < framesToReadFromCache; iFrame += 1) {
                            ma_uint32 iChannel;
                            for (iChannel = 0; iChannel < pVorbis->channels; iChannel += 1) {
                                pFramesOutF32[iChannel] = pVorbis->push.ppPacketData[iChannel][pVorbis->push.framesConsumed + iFrame];
                            }

                            pFramesOutF32 += pVorbis->channels;
                        }
                    }

                    /* Update pointers and counters. */
                    pVorbis->push.framesConsumed  += framesToReadFromCache;
                    pVorbis->push.framesRemaining -= framesToReadFromCache;
                    totalFramesRead               += framesToReadFromCache;

                    /* Don't bother reading any more frames right now if we've just finished loading. */
                    if (totalFramesRead == frameCount) {
                        break;
                    }

                    MA_ASSERT(pVorbis->push.framesRemaining == 0);

                    /* Getting here means we've run out of cached frames. We'll need to load some more. */
                    for (;;) {
                        int samplesRead = 0;
                        int consumedDataSize;

                        /* We need to case dataSize to an int, so make sure we can do it safely. */
                        if (pVorbis->push.dataSize > INT_MAX) {
                            break;  /* Too big. */
                        }

                        consumedDataSize = stb_vorbis_decode_frame_pushdata(pVorbis->stb, pVorbis->push.pData, (int)pVorbis->push.dataSize, NULL, &pVorbis->push.ppPacketData, &samplesRead);
                        if (consumedDataSize != 0) {
                            /* Successfully decoded a Vorbis frame. Consume the data. */
                            pVorbis->push.dataSize -= (size_t)consumedDataSize;
                            MA_MOVE_MEMORY(pVorbis->push.pData, ma_offset_ptr(pVorbis->push.pData, consumedDataSize), pVorbis->push.dataSize);

                            pVorbis->push.framesConsumed  = 0;
                            pVorbis->push.framesRemaining = samplesRead;

                            break;
                        } else {
                            /* Not enough data. Read more. */
                            size_t bytesRead;

                            /* Expand the data buffer if necessary. */
                            if (pVorbis->push.dataCapacity == pVorbis->push.dataSize) {
                                size_t newCap = pVorbis->push.dataCapacity + MA_VORBIS_DATA_CHUNK_SIZE;
                                ma_uint8* pNewData;

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

                        }
                    }

                    /* If we don't have a success code at this point it means we've encounted an error or the end of the file has been reached (probably the latter). */
                    if (result != MA_SUCCESS) {
                        break;
                    }
                }
            } else {
                /* Pull mode. This is the simple case, but we still need to run in a loop because stb_vorbis loves using 32-bit instead of 64-bit. */
                while (totalFramesRead < frameCount) {
                    ma_uint64 framesRemaining = (frameCount - totalFramesRead);
                    int framesRead;

                    if (framesRemaining > INT_MAX) {
                        framesRemaining = INT_MAX;
                    }

                    framesRead = stb_vorbis_get_samples_float_interleaved(pVorbis->stb, channels, (float*)ma_offset_pcm_frames_ptr(pFramesOut, totalFramesRead, format, channels), (int)framesRemaining * channels);   /* Safe cast. */
                    totalFramesRead += framesRead;

                    if (framesRead < (int)framesRemaining) {
                        break;  /* Nothing left to read. Get out. */
                    }
                }
            }
        } else {
            result = MA_INVALID_ARGS;
        }

        pVorbis->cursor += totalFramesRead;

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

        }

        return result;
    }
    #else
    {
        /* vorbis is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);

        (void)pFramesOut;
        (void)frameCount;
        (void)pFramesRead;

        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_stbvorbis_seek_to_pcm_frame(ma_stbvorbis* pVorbis, ma_uint64 frameIndex)
{
    if (pVorbis == NULL) {
        return MA_INVALID_ARGS;
    }

    #if !defined(MA_NO_VORBIS)
    {
        /* Different seeking methods depending on whether or not we're using push mode. */
        if (pVorbis->usingPushMode) {
            /* Push mode. This is the complex case. */

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

            TODO: Use seeking logic documented for stb_vorbis_flush_pushdata().
            */

            /* Seek to the start of the file to begin with. */
            result = pVorbis->onSeek(pVorbis->pReadSeekTellUserData, 0, ma_seek_origin_start);
            if (result != MA_SUCCESS) {
                return result;
            }

            stb_vorbis_flush_pushdata(pVorbis->stb);
            pVorbis->push.framesRemaining = 0;
            pVorbis->push.dataSize        = 0;

            /* Move the cursor back to the start. We'll increment this in the loop below. */
            pVorbis->cursor = 0;

            while (pVorbis->cursor < frameIndex) {
                ma_uint64 framesRead;
                ma_uint64 framesToRead = ma_countof(buffer)/pVorbis->channels;
                if (framesToRead > (frameIndex - pVorbis->cursor)) {
                    framesToRead = (frameIndex - pVorbis->cursor);
                }

                result = ma_stbvorbis_read_pcm_frames(pVorbis, buffer, framesToRead, &framesRead);
                pVorbis->cursor += framesRead;

                if (result != MA_SUCCESS) {
                    return result;
                }
            }
        } else {
            /* Pull mode. This is the simple case. */
            int vorbisResult;

            if (frameIndex > UINT_MAX) {
                return MA_INVALID_ARGS; /* Trying to seek beyond the 32-bit maximum of stb_vorbis. */
            }

            vorbisResult = stb_vorbis_seek(pVorbis->stb, (unsigned int)frameIndex);  /* Safe cast. */
            if (vorbisResult == 0) {
                return MA_ERROR;    /* See failed. */
            }

            pVorbis->cursor = frameIndex;
        }

        return MA_SUCCESS;
    }
    #else
    {
        /* vorbis is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);

        (void)frameIndex;

        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_stbvorbis_get_data_format(ma_stbvorbis* pVorbis, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    /* Defaults for safety. */
    if (pFormat != NULL) {

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

    }
    #else
    {
        /* vorbis is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);
        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_stbvorbis_get_cursor_in_pcm_frames(ma_stbvorbis* pVorbis, ma_uint64* pCursor)
{
    if (pCursor == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = 0;   /* Safety. */

    if (pVorbis == NULL) {
        return MA_INVALID_ARGS;
    }

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

    }
    #else
    {
        /* vorbis is disabled. Should never hit this since initialization would have failed. */
        MA_ASSERT(MA_FALSE);
        return MA_NOT_IMPLEMENTED;
    }
    #endif
}

MA_API ma_result ma_stbvorbis_get_length_in_pcm_frames(ma_stbvorbis* pVorbis, ma_uint64* pLength)
{
    if (pLength == NULL) {
        return MA_INVALID_ARGS;
    }

    *pLength = 0;   /* Safety. */

    if (pVorbis == NULL) {
        return MA_INVALID_ARGS;
    }

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

    MA_ASSERT(pDecoder != NULL);

    if (pConfig != NULL) {
        return ma_allocation_callbacks_init_copy(&pDecoder->allocationCallbacks, &pConfig->allocationCallbacks);
    } else {
        pDecoder->allocationCallbacks = ma_allocation_callbacks_init_default();
        return MA_SUCCESS;
    }
}

static ma_result ma_decoder__data_source_on_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    return ma_decoder_read_pcm_frames((ma_decoder*)pDataSource, pFramesOut, frameCount, pFramesRead);
}

static ma_result ma_decoder__data_source_on_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    return ma_decoder_seek_to_pcm_frame((ma_decoder*)pDataSource, frameIndex);
}

static ma_result ma_decoder__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    return ma_decoder_get_data_format((ma_decoder*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
}

static ma_result ma_decoder__data_source_on_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
{
    return ma_decoder_get_cursor_in_pcm_frames((ma_decoder*)pDataSource, pCursor);
}

static ma_result ma_decoder__data_source_on_get_length(ma_data_source* pDataSource, ma_uint64* pLength)
{
    return ma_decoder_get_length_in_pcm_frames((ma_decoder*)pDataSource, pLength);
}

static ma_data_source_vtable g_ma_decoder_data_source_vtable =
{
    ma_decoder__data_source_on_read,
    ma_decoder__data_source_on_seek,
    ma_decoder__data_source_on_get_data_format,
    ma_decoder__data_source_on_get_cursor,
    ma_decoder__data_source_on_get_length,
    NULL,   /* onSetLooping */

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

    ma_data_converter_uninit(&pDecoder->converter, &pDecoder->allocationCallbacks);
    ma_data_source_uninit(&pDecoder->ds);

    if (pDecoder->pInputCache != NULL) {
        ma_free(pDecoder->pInputCache, &pDecoder->allocationCallbacks);
    }

    return MA_SUCCESS;
}

MA_API ma_result ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_result result = MA_SUCCESS;
    ma_uint64 totalFramesReadOut;
    void* pRunningFramesOut;

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

    if (frameCount == 0) {
        return MA_INVALID_ARGS;
    }

    if (pDecoder == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pDecoder->pBackend == NULL) {
        return MA_INVALID_OPERATION;
    }

    /* Fast path. */
    if (pDecoder->converter.isPassthrough) {
        result = ma_data_source_read_pcm_frames(pDecoder->pBackend, pFramesOut, frameCount, &totalFramesReadOut);
    } else {
        /*
        Getting here means we need to do data conversion. If we're seeking forward and are _not_ doing resampling we can run this in a fast path. If we're doing resampling we
        need to run through each sample because we need to ensure it's internal cache is updated.
        */
        if (pFramesOut == NULL && pDecoder->converter.hasResampler == MA_FALSE) {
            result = ma_data_source_read_pcm_frames(pDecoder->pBackend, NULL, frameCount, &totalFramesReadOut);
        } else {
            /* Slow path. Need to run everything through the data converter. */
            ma_format internalFormat;
            ma_uint32 internalChannels;

            totalFramesReadOut = 0;
            pRunningFramesOut  = pFramesOut;

            result = ma_data_source_get_data_format(pDecoder->pBackend, &internalFormat, &internalChannels, NULL, NULL, 0);
            if (result != MA_SUCCESS) {
                return result;   /* Failed to retrieve the internal format and channel count. */
            }

            /*
            We run a different path depending on whether or not we are using a heap-allocated
            intermediary buffer or not. If the data converter does not support the calculation of
            the required number of input frames, we'll use the heap-allocated path. Otherwise we'll
            use the stack-allocated path.
            */
            if (pDecoder->pInputCache != NULL) {
                /* We don't have a way of determining the required number of input frames, so need to persistently store input data in a cache. */
                while (totalFramesReadOut < frameCount) {
                    ma_uint64 framesToReadThisIterationIn;
                    ma_uint64 framesToReadThisIterationOut;

                    /* If there's any data available in the cache, that needs to get processed first. */
                    if (pDecoder->inputCacheRemaining > 0) {
                        framesToReadThisIterationOut = (frameCount - totalFramesReadOut);
                        framesToReadThisIterationIn  = framesToReadThisIterationOut;
                        if (framesToReadThisIterationIn > pDecoder->inputCacheRemaining) {
                            framesToReadThisIterationIn = pDecoder->inputCacheRemaining;
                        }

                        result = ma_data_converter_process_pcm_frames(&pDecoder->converter, ma_offset_pcm_frames_ptr(pDecoder->pInputCache, pDecoder->inputCacheConsumed, internalFormat, internalChannels), &framesToReadThisIterationIn, pRunningFramesO...
                        if (result != MA_SUCCESS) {
                            break;
                        }

                        pDecoder->inputCacheConsumed  += framesToReadThisIterationIn;
                        pDecoder->inputCacheRemaining -= framesToReadThisIterationIn;

                        totalFramesReadOut += framesToReadThisIterationOut;

                        if (pRunningFramesOut != NULL) {
                            pRunningFramesOut = ma_offset_ptr(pRunningFramesOut, framesToReadThisIterationOut * ma_get_bytes_per_frame(pDecoder->outputFormat, pDecoder->outputChannels));
                        }

                        if (framesToReadThisIterationIn == 0 && framesToReadThisIterationOut == 0) {
                            break;  /* We're done. */
                        }
                    }

                    /* Getting here means there's no data in the cache and we need to fill it up from the data source. */
                    if (pDecoder->inputCacheRemaining == 0) {
                        pDecoder->inputCacheConsumed = 0;

                        result = ma_data_source_read_pcm_frames(pDecoder->pBackend, pDecoder->pInputCache, pDecoder->inputCacheCap, &pDecoder->inputCacheRemaining);
                        if (result != MA_SUCCESS) {
                            break;
                        }
                    }
                }
            } else {
                /* We have a way of determining the required number of input frames so just use the stack. */
                while (totalFramesReadOut < frameCount) {
                    ma_uint8 pIntermediaryBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];  /* In internal format. */
                    ma_uint64 intermediaryBufferCap = sizeof(pIntermediaryBuffer) / ma_get_bytes_per_frame(internalFormat, internalChannels);
                    ma_uint64 framesToReadThisIterationIn;
                    ma_uint64 framesReadThisIterationIn;
                    ma_uint64 framesToReadThisIterationOut;
                    ma_uint64 framesReadThisIterationOut;
                    ma_uint64 requiredInputFrameCount;

                    framesToReadThisIterationOut = (frameCount - totalFramesReadOut);
                    framesToReadThisIterationIn = framesToReadThisIterationOut;
                    if (framesToReadThisIterationIn > intermediaryBufferCap) {
                        framesToReadThisIterationIn = intermediaryBufferCap;
                    }

                    ma_data_converter_get_required_input_frame_count(&pDecoder->converter, framesToReadThisIterationOut, &requiredInputFrameCount);
                    if (framesToReadThisIterationIn > requiredInputFrameCount) {
                        framesToReadThisIterationIn = requiredInputFrameCount;
                    }

                    if (requiredInputFrameCount > 0) {
                        result = ma_data_source_read_pcm_frames(pDecoder->pBackend, pIntermediaryBuffer, framesToReadThisIterationIn, &framesReadThisIterationIn);
                    } else {
                        framesReadThisIterationIn = 0;
                    }

                    /*
                    At this point we have our decoded data in input format and now we need to convert to output format. Note that even if we didn't read any
                    input frames, we still want to try processing frames because there may some output frames generated from cached input data.
                    */
                    framesReadThisIterationOut = framesToReadThisIterationOut;
                    result = ma_data_converter_process_pcm_frames(&pDecoder->converter, pIntermediaryBuffer, &framesReadThisIterationIn, pRunningFramesOut, &framesReadThisIterationOut);
                    if (result != MA_SUCCESS) {
                        break;
                    }

                    totalFramesReadOut += framesReadThisIterationOut;

                    if (pRunningFramesOut != NULL) {
                        pRunningFramesOut = ma_offset_ptr(pRunningFramesOut, framesReadThisIterationOut * ma_get_bytes_per_frame(pDecoder->outputFormat, pDecoder->outputChannels));
                    }

                    if (framesReadThisIterationIn == 0 && framesReadThisIterationOut == 0) {
                        break;  /* We're done. */
                    }
                }
            }
        }
    }

    pDecoder->readPointerInPCMFrames += totalFramesReadOut;

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

    if (result == MA_SUCCESS && totalFramesReadOut == 0) {
        result =  MA_AT_END;
    }

    return result;
}

MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 frameIndex)
{
    if (pDecoder == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pDecoder->pBackend != NULL) {
        ma_result result;
        ma_uint64 internalFrameIndex;
        ma_uint32 internalSampleRate;
        ma_uint64 currentFrameIndex;

        result = ma_data_source_get_data_format(pDecoder->pBackend, NULL, NULL, &internalSampleRate, NULL, 0);
        if (result != MA_SUCCESS) {
            return result;  /* Failed to retrieve the internal sample rate. */
        }

        if (internalSampleRate == pDecoder->outputSampleRate) {
            internalFrameIndex = frameIndex;
        } else {
            internalFrameIndex = ma_calculate_frame_count_after_resampling(internalSampleRate, pDecoder->outputSampleRate, frameIndex);
        }

        /* Only seek if we're requesting a different frame to what we're currently sitting on. */
        ma_data_source_get_cursor_in_pcm_frames(pDecoder->pBackend, &currentFrameIndex);
        if (currentFrameIndex != internalFrameIndex) {
            result = ma_data_source_seek_to_pcm_frame(pDecoder->pBackend, internalFrameIndex);
            if (result == MA_SUCCESS) {
                pDecoder->readPointerInPCMFrames = frameIndex;
            }

            /* Reset the data converter so that any cached data in the resampler is cleared. */
            ma_data_converter_reset(&pDecoder->converter);
        }

        return result;
    }

    /* Should never get here, but if we do it means onSeekToPCMFrame was not set by the backend. */

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

        *pSampleRate = pDecoder->outputSampleRate;
    }

    if (pChannelMap != NULL) {
        ma_data_converter_get_output_channel_map(&pDecoder->converter, pChannelMap, channelMapCap);
    }

    return MA_SUCCESS;
}

MA_API ma_result ma_decoder_get_cursor_in_pcm_frames(ma_decoder* pDecoder, ma_uint64* pCursor)
{
    if (pCursor == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = 0;

    if (pDecoder == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = pDecoder->readPointerInPCMFrames;

    return MA_SUCCESS;
}

MA_API ma_result ma_decoder_get_length_in_pcm_frames(ma_decoder* pDecoder, ma_uint64* pLength)
{
    if (pLength == NULL) {
        return MA_INVALID_ARGS;
    }

    *pLength = 0;

    if (pDecoder == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pDecoder->pBackend != NULL) {
        ma_result result;
        ma_uint64 internalLengthInPCMFrames;
        ma_uint32 internalSampleRate;

        result = ma_data_source_get_length_in_pcm_frames(pDecoder->pBackend, &internalLengthInPCMFrames);
        if (result != MA_SUCCESS) {
            return result;  /* Failed to retrieve the internal length. */
        }

        result = ma_data_source_get_data_format(pDecoder->pBackend, NULL, NULL, &internalSampleRate, NULL, 0);
        if (result != MA_SUCCESS) {
            return result;   /* Failed to retrieve the internal sample rate. */
        }

        if (internalSampleRate == pDecoder->outputSampleRate) {
            *pLength = internalLengthInPCMFrames;
        } else {
            *pLength = ma_calculate_frame_count_after_resampling(pDecoder->outputSampleRate, internalSampleRate, internalLengthInPCMFrames);
        }

        return MA_SUCCESS;
    } else {
        return MA_NO_BACKEND;
    }
}

MA_API ma_result ma_decoder_get_available_frames(ma_decoder* pDecoder, ma_uint64* pAvailableFrames)
{
    ma_result result;
    ma_uint64 totalFrameCount;

    if (pAvailableFrames == NULL) {
        return MA_INVALID_ARGS;
    }

    *pAvailableFrames = 0;

    if (pDecoder == NULL) {
        return MA_INVALID_ARGS;
    }

    result = ma_decoder_get_length_in_pcm_frames(pDecoder, &totalFrameCount);
    if (result != MA_SUCCESS) {
        return result;
    }

    if (totalFrameCount <= pDecoder->readPointerInPCMFrames) {
        *pAvailableFrames = 0;
    } else {
        *pAvailableFrames = totalFrameCount - pDecoder->readPointerInPCMFrames;
    }

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

{
    ma_result result;
    ma_uint64 totalFrameCount;
    ma_uint64 bpf;
    ma_uint64 dataCapInFrames;
    void* pPCMFramesOut;

    MA_ASSERT(pDecoder != NULL);

    totalFrameCount = 0;
    bpf = ma_get_bytes_per_frame(pDecoder->outputFormat, pDecoder->outputChannels);

    /* The frame count is unknown until we try reading. Thus, we just run in a loop. */
    dataCapInFrames = 0;
    pPCMFramesOut = NULL;
    for (;;) {
        ma_uint64 frameCountToTryReading;
        ma_uint64 framesJustRead;

        /* Make room if there's not enough. */
        if (totalFrameCount == dataCapInFrames) {
            void* pNewPCMFramesOut;
            ma_uint64 newDataCapInFrames = dataCapInFrames*2;
            if (newDataCapInFrames == 0) {
                newDataCapInFrames = 4096;
            }

            if ((newDataCapInFrames * bpf) > MA_SIZE_MAX) {

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

            pNewPCMFramesOut = (void*)ma_realloc(pPCMFramesOut, (size_t)(newDataCapInFrames * bpf), &pDecoder->allocationCallbacks);
            if (pNewPCMFramesOut == NULL) {
                ma_free(pPCMFramesOut, &pDecoder->allocationCallbacks);
                return MA_OUT_OF_MEMORY;
            }

            dataCapInFrames = newDataCapInFrames;
            pPCMFramesOut = pNewPCMFramesOut;
        }

        frameCountToTryReading = dataCapInFrames - totalFrameCount;
        MA_ASSERT(frameCountToTryReading > 0);

        result = ma_decoder_read_pcm_frames(pDecoder, (ma_uint8*)pPCMFramesOut + (totalFrameCount * bpf), frameCountToTryReading, &framesJustRead);
        totalFrameCount += framesJustRead;

        if (result != MA_SUCCESS) {
            break;
        }

        if (framesJustRead < frameCountToTryReading) {
            break;
        }
    }


    if (pConfigOut != NULL) {
        pConfigOut->format     = pDecoder->outputFormat;
        pConfigOut->channels   = pDecoder->outputChannels;
        pConfigOut->sampleRate = pDecoder->outputSampleRate;
    }

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


    MA_ASSERT(pEncoder != NULL);

    pWav = (drwav*)pEncoder->pInternalEncoder;
    MA_ASSERT(pWav != NULL);

    drwav_uninit(pWav);
    ma_free(pWav, &pEncoder->config.allocationCallbacks);
}

static ma_result ma_encoder__on_write_pcm_frames_wav(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount, ma_uint64* pFramesWritten)
{
    drwav* pWav;
    ma_uint64 framesWritten;

    MA_ASSERT(pEncoder != NULL);

    pWav = (drwav*)pEncoder->pInternalEncoder;
    MA_ASSERT(pWav != NULL);

    framesWritten = drwav_write_pcm_frames(pWav, frameCount, pFramesIn);

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

    return MA_SUCCESS;
}
#endif

MA_API ma_encoder_config ma_encoder_config_init(ma_encoding_format encodingFormat, ma_format format, ma_uint32 channels, ma_uint32 sampleRate)
{
    ma_encoder_config config;

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

    pEncoder->onSeek    = onSeek;
    pEncoder->pUserData = pUserData;

    switch (pEncoder->config.encodingFormat)
    {
        case ma_encoding_format_wav:
        {
        #if defined(MA_HAS_WAV)
            pEncoder->onInit           = ma_encoder__on_init_wav;
            pEncoder->onUninit         = ma_encoder__on_uninit_wav;
            pEncoder->onWritePCMFrames = ma_encoder__on_write_pcm_frames_wav;
        #else
            result = MA_NO_BACKEND;
        #endif
        } break;

        default:
        {
            result = MA_INVALID_ARGS;
        } break;
    }

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

    }

    /* If we have a file handle, close it. */
    if (pEncoder->onWrite == ma_encoder__on_write_vfs) {
        ma_vfs_or_default_close(pEncoder->data.vfs.pVFS, pEncoder->data.vfs.file);
        pEncoder->data.vfs.file = NULL;
    }
}


MA_API ma_result ma_encoder_write_pcm_frames(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount, ma_uint64* pFramesWritten)
{
    if (pFramesWritten != NULL) {
        *pFramesWritten = 0;
    }

    if (pEncoder == NULL || pFramesIn == NULL) {
        return MA_INVALID_ARGS;
    }

    return pEncoder->onWritePCMFrames(pEncoder, pFramesIn, frameCount, pFramesWritten);
}
#endif  /* MA_NO_ENCODING */



/**************************************************************************************************************************************************************

Generation

**************************************************************************************************************************************************************/

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

    config.format     = format;
    config.channels   = channels;
    config.sampleRate = sampleRate;
    config.type       = type;
    config.amplitude  = amplitude;
    config.frequency  = frequency;

    return config;
}

static ma_result ma_waveform__data_source_on_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    return ma_waveform_read_pcm_frames((ma_waveform*)pDataSource, pFramesOut, frameCount, pFramesRead);
}

static ma_result ma_waveform__data_source_on_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    return ma_waveform_seek_to_pcm_frame((ma_waveform*)pDataSource, frameIndex);
}

static ma_result ma_waveform__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    ma_waveform* pWaveform = (ma_waveform*)pDataSource;

    *pFormat     = pWaveform->config.format;
    *pChannels   = pWaveform->config.channels;
    *pSampleRate = pWaveform->config.sampleRate;
    ma_channel_map_init_standard(ma_standard_channel_map_default, pChannelMap, channelMapCap, pWaveform->config.channels);

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

    r = 2 * (f - 0.5);

    return (float)(r * amplitude);
}

static ma_int16 ma_waveform_sawtooth_s16(double time, double amplitude)
{
    return ma_pcm_sample_f32_to_s16(ma_waveform_sawtooth_f32(time, amplitude));
}

static void ma_waveform_read_pcm_frames__sine(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint64 iChannel;
    ma_uint32 bps = ma_get_bytes_per_sample(pWaveform->config.format);
    ma_uint32 bpf = bps * pWaveform->config.channels;

    MA_ASSERT(pWaveform  != NULL);
    MA_ASSERT(pFramesOut != NULL);

    if (pWaveform->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_sine_f32(pWaveform->time, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutF32[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else if (pWaveform->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            ma_int16 s = ma_waveform_sine_s16(pWaveform->time, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutS16[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else {
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_sine_f32(pWaveform->time, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pWaveform->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
            }
        }
    }
}

static void ma_waveform_read_pcm_frames__square(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint64 iChannel;
    ma_uint32 bps = ma_get_bytes_per_sample(pWaveform->config.format);
    ma_uint32 bpf = bps * pWaveform->config.channels;

    MA_ASSERT(pWaveform  != NULL);
    MA_ASSERT(pFramesOut != NULL);

    if (pWaveform->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_square_f32(pWaveform->time, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutF32[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else if (pWaveform->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            ma_int16 s = ma_waveform_square_s16(pWaveform->time, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutS16[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else {
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_square_f32(pWaveform->time, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pWaveform->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
            }
        }
    }
}

static void ma_waveform_read_pcm_frames__triangle(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint64 iChannel;
    ma_uint32 bps = ma_get_bytes_per_sample(pWaveform->config.format);
    ma_uint32 bpf = bps * pWaveform->config.channels;

    MA_ASSERT(pWaveform  != NULL);
    MA_ASSERT(pFramesOut != NULL);

    if (pWaveform->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_triangle_f32(pWaveform->time, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutF32[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else if (pWaveform->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            ma_int16 s = ma_waveform_triangle_s16(pWaveform->time, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutS16[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else {
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_triangle_f32(pWaveform->time, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pWaveform->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
            }
        }
    }
}

static void ma_waveform_read_pcm_frames__sawtooth(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint64 iChannel;
    ma_uint32 bps = ma_get_bytes_per_sample(pWaveform->config.format);
    ma_uint32 bpf = bps * pWaveform->config.channels;

    MA_ASSERT(pWaveform  != NULL);
    MA_ASSERT(pFramesOut != NULL);

    if (pWaveform->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_sawtooth_f32(pWaveform->time, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutF32[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else if (pWaveform->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            ma_int16 s = ma_waveform_sawtooth_s16(pWaveform->time, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                pFramesOutS16[iFrame*pWaveform->config.channels + iChannel] = s;
            }
        }
    } else {
        for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
            float s = ma_waveform_sawtooth_f32(pWaveform->time, pWaveform->config.amplitude);
            pWaveform->time += pWaveform->advance;

            for (iChannel = 0; iChannel < pWaveform->config.channels; iChannel += 1) {
                ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pWaveform->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
            }
        }
    }
}

MA_API ma_result ma_waveform_read_pcm_frames(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    if (pFramesRead != NULL) {
        *pFramesRead = 0;
    }

    if (frameCount == 0) {
        return MA_INVALID_ARGS;
    }

    if (pWaveform == NULL) {
        return MA_INVALID_ARGS;
    }

    if (pFramesOut != NULL) {
        switch (pWaveform->config.type)
        {
            case ma_waveform_type_sine:
            {
                ma_waveform_read_pcm_frames__sine(pWaveform, pFramesOut, frameCount);
            } break;

            case ma_waveform_type_square:
            {
                ma_waveform_read_pcm_frames__square(pWaveform, pFramesOut, frameCount);
            } break;

            case ma_waveform_type_triangle:
            {
                ma_waveform_read_pcm_frames__triangle(pWaveform, pFramesOut, frameCount);
            } break;

            case ma_waveform_type_sawtooth:
            {
                ma_waveform_read_pcm_frames__sawtooth(pWaveform, pFramesOut, frameCount);
            } break;

            default: return MA_INVALID_OPERATION;   /* Unknown waveform type. */
        }
    } else {
        pWaveform->time += pWaveform->advance * (ma_int64)frameCount; /* Cast to int64 required for VC6. Won't affect anything in practice. */
    }

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

    return MA_SUCCESS;
}

MA_API ma_result ma_waveform_seek_to_pcm_frame(ma_waveform* pWaveform, ma_uint64 frameIndex)
{
    if (pWaveform == NULL) {
        return MA_INVALID_ARGS;
    }

    pWaveform->time = pWaveform->advance * (ma_int64)frameIndex;    /* Casting for VC6. Won't be an issue in practice. */

    return MA_SUCCESS;
}


MA_API ma_noise_config ma_noise_config_init(ma_format format, ma_uint32 channels, ma_noise_type type, ma_int32 seed, double amplitude)
{
    ma_noise_config config;
    MA_ZERO_OBJECT(&config);

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

    config.amplitude = amplitude;

    if (config.seed == 0) {
        config.seed = MA_DEFAULT_LCG_SEED;
    }

    return config;
}


static ma_result ma_noise__data_source_on_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    return ma_noise_read_pcm_frames((ma_noise*)pDataSource, pFramesOut, frameCount, pFramesRead);
}

static ma_result ma_noise__data_source_on_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    /* No-op. Just pretend to be successful. */
    (void)pDataSource;
    (void)frameIndex;
    return MA_SUCCESS;
}

static ma_result ma_noise__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    ma_noise* pNoise = (ma_noise*)pDataSource;

    *pFormat     = pNoise->config.format;
    *pChannels   = pNoise->config.channels;
    *pSampleRate = 0;   /* There is no notion of sample rate with noise generation. */

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

static MA_INLINE float ma_noise_f32_white(ma_noise* pNoise)
{
    return (float)(ma_lcg_rand_f64(&pNoise->lcg) * pNoise->config.amplitude);
}

static MA_INLINE ma_int16 ma_noise_s16_white(ma_noise* pNoise)
{
    return ma_pcm_sample_f32_to_s16(ma_noise_f32_white(pNoise));
}

static MA_INLINE ma_uint64 ma_noise_read_pcm_frames__white(ma_noise* pNoise, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint32 iChannel;
    const ma_uint32 channels = pNoise->config.channels;
    MA_ASSUME(channels > 0);

    if (pNoise->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                float s = ma_noise_f32_white(pNoise);
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    pFramesOutF32[iFrame*channels + iChannel] = s;
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    pFramesOutF32[iFrame*channels + iChannel] = ma_noise_f32_white(pNoise);
                }
            }
        }
    } else if (pNoise->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                ma_int16 s = ma_noise_s16_white(pNoise);
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    pFramesOutS16[iFrame*channels + iChannel] = s;
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    pFramesOutS16[iFrame*channels + iChannel] = ma_noise_s16_white(pNoise);
                }
            }
        }
    } else {
        const ma_uint32 bps = ma_get_bytes_per_sample(pNoise->config.format);
        const ma_uint32 bpf = bps * channels;

        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                float s = ma_noise_f32_white(pNoise);
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pNoise->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    float s = ma_noise_f32_white(pNoise);
                    ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pNoise->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
                }
            }
        }
    }

    return frameCount;
}


static MA_INLINE unsigned int ma_tzcnt32(unsigned int x)
{
    unsigned int n;

    /* Special case for odd numbers since they should happen about half the time. */
    if (x & 0x1)  {
        return 0;

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

    result /= 10;

    return (float)(result * pNoise->config.amplitude);
}

static MA_INLINE ma_int16 ma_noise_s16_pink(ma_noise* pNoise, ma_uint32 iChannel)
{
    return ma_pcm_sample_f32_to_s16(ma_noise_f32_pink(pNoise, iChannel));
}

static MA_INLINE ma_uint64 ma_noise_read_pcm_frames__pink(ma_noise* pNoise, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint32 iChannel;
    const ma_uint32 channels = pNoise->config.channels;
    MA_ASSUME(channels > 0);

    if (pNoise->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                float s = ma_noise_f32_pink(pNoise, 0);
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    pFramesOutF32[iFrame*channels + iChannel] = s;
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    pFramesOutF32[iFrame*channels + iChannel] = ma_noise_f32_pink(pNoise, iChannel);
                }
            }
        }
    } else if (pNoise->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                ma_int16 s = ma_noise_s16_pink(pNoise, 0);
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    pFramesOutS16[iFrame*channels + iChannel] = s;
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    pFramesOutS16[iFrame*channels + iChannel] = ma_noise_s16_pink(pNoise, iChannel);
                }
            }
        }
    } else {
        const ma_uint32 bps = ma_get_bytes_per_sample(pNoise->config.format);
        const ma_uint32 bpf = bps * channels;

        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                float s = ma_noise_f32_pink(pNoise, 0);
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pNoise->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    float s = ma_noise_f32_pink(pNoise, iChannel);
                    ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pNoise->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
                }
            }
        }
    }

    return frameCount;
}


static MA_INLINE float ma_noise_f32_brownian(ma_noise* pNoise, ma_uint32 iChannel)
{
    double result;

    result = (ma_lcg_rand_f64(&pNoise->lcg) + pNoise->state.brownian.accumulation[iChannel]);
    result /= 1.005; /* Don't escape the -1..1 range on average. */

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

    result /= 20;

    return (float)(result * pNoise->config.amplitude);
}

static MA_INLINE ma_int16 ma_noise_s16_brownian(ma_noise* pNoise, ma_uint32 iChannel)
{
    return ma_pcm_sample_f32_to_s16(ma_noise_f32_brownian(pNoise, iChannel));
}

static MA_INLINE ma_uint64 ma_noise_read_pcm_frames__brownian(ma_noise* pNoise, void* pFramesOut, ma_uint64 frameCount)
{
    ma_uint64 iFrame;
    ma_uint32 iChannel;
    const ma_uint32 channels = pNoise->config.channels;
    MA_ASSUME(channels > 0);

    if (pNoise->config.format == ma_format_f32) {
        float* pFramesOutF32 = (float*)pFramesOut;
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                float s = ma_noise_f32_brownian(pNoise, 0);
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    pFramesOutF32[iFrame*channels + iChannel] = s;
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    pFramesOutF32[iFrame*channels + iChannel] = ma_noise_f32_brownian(pNoise, iChannel);
                }
            }
        }
    } else if (pNoise->config.format == ma_format_s16) {
        ma_int16* pFramesOutS16 = (ma_int16*)pFramesOut;
        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                ma_int16 s = ma_noise_s16_brownian(pNoise, 0);
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    pFramesOutS16[iFrame*channels + iChannel] = s;
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    pFramesOutS16[iFrame*channels + iChannel] = ma_noise_s16_brownian(pNoise, iChannel);
                }
            }
        }
    } else {
        const ma_uint32 bps = ma_get_bytes_per_sample(pNoise->config.format);
        const ma_uint32 bpf = bps * channels;

        if (pNoise->config.duplicateChannels) {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                float s = ma_noise_f32_brownian(pNoise, 0);
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pNoise->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
                }
            }
        } else {
            for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
                for (iChannel = 0; iChannel < channels; iChannel += 1) {
                    float s = ma_noise_f32_brownian(pNoise, iChannel);
                    ma_pcm_convert(ma_offset_ptr(pFramesOut, iFrame*bpf + iChannel*bps), pNoise->config.format, &s, ma_format_f32, 1, ma_dither_mode_none);
                }
            }
        }
    }

    return frameCount;
}

MA_API ma_result ma_noise_read_pcm_frames(ma_noise* pNoise, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_uint64 framesRead = 0;

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

    if (frameCount == 0) {
        return MA_INVALID_ARGS;
    }

    if (pNoise == NULL) {
        return MA_INVALID_ARGS;
    }

    /* The output buffer is allowed to be NULL. Since we aren't tracking cursors or anything we can just do nothing and pretend to be successful. */
    if (pFramesOut == NULL) {
        framesRead = frameCount;
    } else {
        switch (pNoise->config.type) {
            case ma_noise_type_white:    framesRead = ma_noise_read_pcm_frames__white   (pNoise, pFramesOut, frameCount); break;
            case ma_noise_type_pink:     framesRead = ma_noise_read_pcm_frames__pink    (pNoise, pFramesOut, frameCount); break;
            case ma_noise_type_brownian: framesRead = ma_noise_read_pcm_frames__brownian(pNoise, pFramesOut, frameCount); break;
            default: return MA_INVALID_OPERATION;   /* Unknown noise type. */
        }
    }

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

    return MA_SUCCESS;
}
#endif /* MA_NO_GENERATION */



#ifndef MA_NO_RESOURCE_MANAGER
#ifndef MA_RESOURCE_MANAGER_PAGE_SIZE_IN_MILLISECONDS

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


    /*
    Initialization of the connector is when we can fire the init notification. This will give the application access to
    the format/channels/rate of the data source.
    */
    if (result == MA_SUCCESS) {
        /*
        Make sure the looping state is set before returning in order to handle the case where the
        loop state was set on the data buffer before the connector was initialized.
        */
        ma_data_source_set_range_in_pcm_frames(pDataBuffer, pConfig->rangeBegInPCMFrames, pConfig->rangeEndInPCMFrames);
        ma_data_source_set_loop_point_in_pcm_frames(pDataBuffer, pConfig->loopPointBegInPCMFrames, pConfig->loopPointEndInPCMFrames);
        ma_data_source_set_looping(pDataBuffer, pConfig->isLooping);

        pDataBuffer->isConnectorInitialized = MA_TRUE;

        if (pInitNotification != NULL) {
            ma_async_notification_signal(pInitNotification);
        }

        if (pInitFence != NULL) {
            ma_fence_release(pInitFence);

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

        return result;
    }

    /*
    At this point we have the decoder and we now need to initialize the data supply. This will
    be either a decoded buffer, or a decoded paged buffer. A regular buffer is just one big heap
    allocated buffer, whereas a paged buffer is a linked list of paged-sized buffers. The latter
    is used when the length of a sound is unknown until a full decode has been performed.
    */
    if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH) == 0) {
        result = ma_decoder_get_length_in_pcm_frames(pDecoder, &totalFrameCount);
        if (result != MA_SUCCESS) {
            return result;
        }
    } else {
        totalFrameCount = 0;
    }

    if (totalFrameCount > 0) {
        /* It's a known length. The data supply is a regular decoded buffer. */
        ma_uint64 dataSizeInBytes;
        void* pData;

        dataSizeInBytes = totalFrameCount * ma_get_bytes_per_frame(pDecoder->outputFormat, pDecoder->outputChannels);
        if (dataSizeInBytes > MA_SIZE_MAX) {
            ma_decoder_uninit(pDecoder);
            ma_free(pDecoder, &pResourceManager->config.allocationCallbacks);
            return MA_TOO_BIG;
        }

        pData = ma_malloc((size_t)dataSizeInBytes, &pResourceManager->config.allocationCallbacks);
        if (pData == NULL) {
            ma_decoder_uninit(pDecoder);
            ma_free(pDecoder, &pResourceManager->config.allocationCallbacks);
            return MA_OUT_OF_MEMORY;
        }

        /* The buffer needs to be initialized to silence in case the caller reads from it. */
        ma_silence_pcm_frames(pData, totalFrameCount, pDecoder->outputFormat, pDecoder->outputChannels);

        /* Data has been allocated and the data supply can now be initialized. */
        pDataBufferNode->data.backend.decoded.pData             = pData;
        pDataBufferNode->data.backend.decoded.totalFrameCount   = totalFrameCount;
        pDataBufferNode->data.backend.decoded.format            = pDecoder->outputFormat;
        pDataBufferNode->data.backend.decoded.channels          = pDecoder->outputChannels;
        pDataBufferNode->data.backend.decoded.sampleRate        = pDecoder->outputSampleRate;
        pDataBufferNode->data.backend.decoded.decodedFrameCount = 0;
        ma_resource_manager_data_buffer_node_set_data_supply_type(pDataBufferNode, ma_resource_manager_data_supply_type_decoded);  /* <-- Must be set last. */
    } else {

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


    *ppDecoder = pDecoder;

    return MA_SUCCESS;
}

static ma_result ma_resource_manager_data_buffer_node_decode_next_page(ma_resource_manager* pResourceManager, ma_resource_manager_data_buffer_node* pDataBufferNode, ma_decoder* pDecoder)
{
    ma_result result = MA_SUCCESS;
    ma_uint64 pageSizeInFrames;
    ma_uint64 framesToTryReading;
    ma_uint64 framesRead;

    MA_ASSERT(pResourceManager != NULL);
    MA_ASSERT(pDataBufferNode  != NULL);
    MA_ASSERT(pDecoder         != NULL);

    /* We need to know the size of a page in frames to know how many frames to decode. */
    pageSizeInFrames = MA_RESOURCE_MANAGER_PAGE_SIZE_IN_MILLISECONDS * (pDecoder->outputSampleRate/1000);
    framesToTryReading = pageSizeInFrames;

    /*
    Here is where we do the decoding of the next page. We'll run a slightly different path depending
    on whether or not we're using a flat or paged buffer because the allocation of the page differs
    between the two. For a flat buffer it's an offset to an already-allocated buffer. For a paged
    buffer, we need to allocate a new page and attach it to the linked list.
    */
    switch (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBufferNode))
    {
        case ma_resource_manager_data_supply_type_decoded:
        {
            /* The destination buffer is an offset to the existing buffer. Don't read more than we originally retrieved when we first initialized the decoder. */
            void* pDst;
            ma_uint64 framesRemaining = pDataBufferNode->data.backend.decoded.totalFrameCount - pDataBufferNode->data.backend.decoded.decodedFrameCount;
            if (framesToTryReading > framesRemaining) {
                framesToTryReading = framesRemaining;
            }

            if (framesToTryReading > 0) {
                pDst = ma_offset_ptr(
                    pDataBufferNode->data.backend.decoded.pData,
                    pDataBufferNode->data.backend.decoded.decodedFrameCount * ma_get_bytes_per_frame(pDataBufferNode->data.backend.decoded.format, pDataBufferNode->data.backend.decoded.channels)
                );
                MA_ASSERT(pDst != NULL);

                result = ma_decoder_read_pcm_frames(pDecoder, pDst, framesToTryReading, &framesRead);
                if (framesRead > 0) {
                    pDataBufferNode->data.backend.decoded.decodedFrameCount += framesRead;
                }
            } else {
                framesRead = 0;
            }
        } break;

        case ma_resource_manager_data_supply_type_decoded_paged:
        {
            /* The destination buffer is a freshly allocated page. */
            ma_paged_audio_buffer_page* pPage;

            result = ma_paged_audio_buffer_data_allocate_page(&pDataBufferNode->data.backend.decodedPaged.data, framesToTryReading, NULL, &pResourceManager->config.allocationCallbacks, &pPage);
            if (result != MA_SUCCESS) {
                return result;
            }

            result = ma_decoder_read_pcm_frames(pDecoder, pPage->pAudioData, framesToTryReading, &framesRead);
            if (framesRead > 0) {
                pPage->sizeInFrames = framesRead;

                result = ma_paged_audio_buffer_data_append_page(&pDataBufferNode->data.backend.decodedPaged.data, pPage);
                if (result == MA_SUCCESS) {
                    pDataBufferNode->data.backend.decodedPaged.decodedFrameCount += framesRead;
                } else {
                    /* Failed to append the page. Just abort and set the status to MA_AT_END. */
                    ma_paged_audio_buffer_data_free_page(&pDataBufferNode->data.backend.decodedPaged.data, pPage, &pResourceManager->config.allocationCallbacks);
                    result = MA_AT_END;
                }
            } else {
                /* No frames were read. Free the page and just set the status to MA_AT_END. */
                ma_paged_audio_buffer_data_free_page(&pDataBufferNode->data.backend.decodedPaged.data, pPage, &pResourceManager->config.allocationCallbacks);
                result = MA_AT_END;
            }
        } break;

        case ma_resource_manager_data_supply_type_encoded:
        case ma_resource_manager_data_supply_type_unknown:
        default:
        {
            /* Unexpected data supply type. */
            ma_log_postf(ma_resource_manager_get_log(pResourceManager), MA_LOG_LEVEL_ERROR, "Unexpected data supply type (%d) when decoding page.", ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBufferNode));
            return MA_ERROR;
        };
    }

    if (result == MA_SUCCESS && framesRead == 0) {
        result = MA_AT_END;
    }

    return result;
}

static ma_result ma_resource_manager_data_buffer_node_acquire_critical_section(ma_resource_manager* pResourceManager, const char* pFilePath, const wchar_t* pFilePathW, ma_uint32 hashedName32, ma_uint32 flags, const ma_resource_manager_data_supply* pE...
{
    ma_result result = MA_SUCCESS;
    ma_resource_manager_data_buffer_node* pDataBufferNode = NULL;

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

}



static ma_uint32 ma_resource_manager_data_buffer_next_execution_order(ma_resource_manager_data_buffer* pDataBuffer)
{
    MA_ASSERT(pDataBuffer != NULL);
    return c89atomic_fetch_add_32(&pDataBuffer->executionCounter, 1);
}

static ma_result ma_resource_manager_data_buffer_cb__read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    return ma_resource_manager_data_buffer_read_pcm_frames((ma_resource_manager_data_buffer*)pDataSource, pFramesOut, frameCount, pFramesRead);
}

static ma_result ma_resource_manager_data_buffer_cb__seek_to_pcm_frame(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    return ma_resource_manager_data_buffer_seek_to_pcm_frame((ma_resource_manager_data_buffer*)pDataSource, frameIndex);
}

static ma_result ma_resource_manager_data_buffer_cb__get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    return ma_resource_manager_data_buffer_get_data_format((ma_resource_manager_data_buffer*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
}

static ma_result ma_resource_manager_data_buffer_cb__get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor)
{
    return ma_resource_manager_data_buffer_get_cursor_in_pcm_frames((ma_resource_manager_data_buffer*)pDataSource, pCursor);
}

static ma_result ma_resource_manager_data_buffer_cb__get_length_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLength)
{
    return ma_resource_manager_data_buffer_get_length_in_pcm_frames((ma_resource_manager_data_buffer*)pDataSource, pLength);
}

static ma_result ma_resource_manager_data_buffer_cb__set_looping(ma_data_source* pDataSource, ma_bool32 isLooping)
{
    ma_resource_manager_data_buffer* pDataBuffer = (ma_resource_manager_data_buffer*)pDataSource;
    MA_ASSERT(pDataBuffer != NULL);

    c89atomic_exchange_32(&pDataBuffer->isLooping, isLooping);

    /* The looping state needs to be set on the connector as well or else looping won't work when we read audio data. */
    ma_data_source_set_looping(ma_resource_manager_data_buffer_get_connector(pDataBuffer), isLooping);

    return MA_SUCCESS;
}

static ma_data_source_vtable g_ma_resource_manager_data_buffer_vtable =
{
    ma_resource_manager_data_buffer_cb__read_pcm_frames,
    ma_resource_manager_data_buffer_cb__seek_to_pcm_frame,
    ma_resource_manager_data_buffer_cb__get_data_format,
    ma_resource_manager_data_buffer_cb__get_cursor_in_pcm_frames,
    ma_resource_manager_data_buffer_cb__get_length_in_pcm_frames,
    ma_resource_manager_data_buffer_cb__set_looping,
    0
};

static ma_result ma_resource_manager_data_buffer_init_ex_internal(ma_resource_manager* pResourceManager, const ma_resource_manager_data_source_config* pConfig, ma_uint32 hashedName32, ma_resource_manager_data_buffer* pDataBuffer)
{
    ma_result result = MA_SUCCESS;
    ma_resource_manager_data_buffer_node* pDataBufferNode;
    ma_data_source_config dataSourceConfig;
    ma_bool32 async;

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

        }

        if (result != MA_SUCCESS) {
            ma_resource_manager_data_buffer_node_unacquire(pResourceManager, pDataBufferNode, NULL, NULL);
            goto done;
        }
    }
done:
    if (result == MA_SUCCESS) {
        if (pConfig->initialSeekPointInPCMFrames > 0) {
            ma_resource_manager_data_buffer_seek_to_pcm_frame(pDataBuffer, pConfig->initialSeekPointInPCMFrames);
        }
    }

    ma_resource_manager_pipeline_notifications_release_all_fences(&notifications);

    return result;
}

MA_API ma_result ma_resource_manager_data_buffer_init_ex(ma_resource_manager* pResourceManager, const ma_resource_manager_data_source_config* pConfig, ma_resource_manager_data_buffer* pDataBuffer)
{

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

            ma_resource_manager_inline_notification_uninit(&notification);
            return result;
        }

        ma_resource_manager_inline_notification_wait_and_uninit(&notification);
    }

    return result;
}

MA_API ma_result ma_resource_manager_data_buffer_read_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_result result = MA_SUCCESS;
    ma_uint64 framesRead = 0;
    ma_bool32 isDecodedBufferBusy = MA_FALSE;

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

    if (frameCount == 0) {
        return MA_INVALID_ARGS;
    }

    /*
    We cannot be using the data buffer after it's been uninitialized. If you trigger this assert it means you're trying to read from the data buffer after
    it's been uninitialized or is in the process of uninitializing.
    */
    MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE);

    /* If the node is not initialized we need to abort with a busy code. */
    if (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode) == ma_resource_manager_data_supply_type_unknown) {
        return MA_BUSY; /* Still loading. */
    }

    if (pDataBuffer->seekToCursorOnNextRead) {
        pDataBuffer->seekToCursorOnNextRead = MA_FALSE;

        result = ma_data_source_seek_to_pcm_frame(ma_resource_manager_data_buffer_get_connector(pDataBuffer), pDataBuffer->seekTargetInPCMFrames);
        if (result != MA_SUCCESS) {
            return result;
        }
    }

    /*
    For decoded buffers (not paged) we need to check beforehand how many frames we have available. We cannot
    exceed this amount. We'll read as much as we can, and then return MA_BUSY.
    */
    if (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode) == ma_resource_manager_data_supply_type_decoded) {
        ma_uint64 availableFrames;

        isDecodedBufferBusy = (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_BUSY);

        if (ma_resource_manager_data_buffer_get_available_frames(pDataBuffer, &availableFrames) == MA_SUCCESS) {
            /* Don't try reading more than the available frame count. */
            if (frameCount > availableFrames) {
                frameCount = availableFrames;

                /*
                If there's no frames available we want to set the status to MA_AT_END. The logic below
                will check if the node is busy, and if so, change it to MA_BUSY. The reason we do this
                is because we don't want to call `ma_data_source_read_pcm_frames()` if the frame count
                is 0 because that'll result in a situation where it's possible MA_AT_END won't get
                returned.
                */
                if (frameCount == 0) {
                    result = MA_AT_END;
                }
            } else {
                isDecodedBufferBusy = MA_FALSE; /* We have enough frames available in the buffer to avoid a MA_BUSY status. */
            }
        }
    }

    /* Don't attempt to read anything if we've got no frames available. */
    if (frameCount > 0) {
        result = ma_data_source_read_pcm_frames(ma_resource_manager_data_buffer_get_connector(pDataBuffer), pFramesOut, frameCount, &framesRead);
    }

    /*
    If we returned MA_AT_END, but the node is still loading, we don't want to return that code or else the caller will interpret the sound
    as at the end and terminate decoding.
    */
    if (result == MA_AT_END) {
        if (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_BUSY) {
            result = MA_BUSY;
        }
    }

    if (isDecodedBufferBusy) {
        result = MA_BUSY;
    }

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

    if (result == MA_SUCCESS && framesRead == 0) {
        result  = MA_AT_END;
    }

    return result;
}

MA_API ma_result ma_resource_manager_data_buffer_seek_to_pcm_frame(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64 frameIndex)
{
    ma_result result;

    /* We cannot be using the data source after it's been uninitialized. */
    MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE);

    /* If we haven't yet got a connector we need to abort. */
    if (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode) == ma_resource_manager_data_supply_type_unknown) {
        pDataBuffer->seekTargetInPCMFrames = frameIndex;
        pDataBuffer->seekToCursorOnNextRead = MA_TRUE;
        return MA_BUSY; /* Still loading. */
    }

    result = ma_data_source_seek_to_pcm_frame(ma_resource_manager_data_buffer_get_connector(pDataBuffer), frameIndex);
    if (result != MA_SUCCESS) {
        return result;
    }

    pDataBuffer->seekTargetInPCMFrames = ~(ma_uint64)0; /* <-- For identification purposes. */
    pDataBuffer->seekToCursorOnNextRead = MA_FALSE;

    return MA_SUCCESS;
}

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

        };

        default:
        {
            /* Unknown supply type. Should never hit this. */
            return MA_INVALID_ARGS;
        }
    }
}

MA_API ma_result ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pCursor)
{
    /* We cannot be using the data source after it's been uninitialized. */
    MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE);

    if (pDataBuffer == NULL || pCursor == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = 0;

    switch (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode))
    {
        case ma_resource_manager_data_supply_type_encoded:
        {
            return ma_decoder_get_cursor_in_pcm_frames(&pDataBuffer->connector.decoder, pCursor);
        };

        case ma_resource_manager_data_supply_type_decoded:
        {
            return ma_audio_buffer_get_cursor_in_pcm_frames(&pDataBuffer->connector.buffer, pCursor);
        };

        case ma_resource_manager_data_supply_type_decoded_paged:
        {
            return ma_paged_audio_buffer_get_cursor_in_pcm_frames(&pDataBuffer->connector.pagedBuffer, pCursor);
        };

        case ma_resource_manager_data_supply_type_unknown:
        {
            return MA_BUSY;
        };

        default:
        {
            return MA_INVALID_ARGS;
        }
    }
}

MA_API ma_result ma_resource_manager_data_buffer_get_length_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pLength)
{
    /* We cannot be using the data source after it's been uninitialized. */
    MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE);

    if (pDataBuffer == NULL || pLength == NULL) {
        return MA_INVALID_ARGS;
    }

    if (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode) == ma_resource_manager_data_supply_type_unknown) {
        return MA_BUSY; /* Still loading. */
    }

    return ma_data_source_get_length_in_pcm_frames(ma_resource_manager_data_buffer_get_connector(pDataBuffer), pLength);
}

MA_API ma_result ma_resource_manager_data_buffer_result(const ma_resource_manager_data_buffer* pDataBuffer)
{
    if (pDataBuffer == NULL) {
        return MA_INVALID_ARGS;
    }

    return (ma_result)c89atomic_load_i32((ma_result*)&pDataBuffer->result);    /* Need a naughty const-cast here. */
}

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

MA_API ma_result ma_resource_manager_data_buffer_set_looping(ma_resource_manager_data_buffer* pDataBuffer, ma_bool32 isLooping)
{
    return ma_data_source_set_looping(pDataBuffer, isLooping);
}

MA_API ma_bool32 ma_resource_manager_data_buffer_is_looping(const ma_resource_manager_data_buffer* pDataBuffer)
{
    return ma_data_source_is_looping(pDataBuffer);
}

MA_API ma_result ma_resource_manager_data_buffer_get_available_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pAvailableFrames)
{
    if (pAvailableFrames == NULL) {
        return MA_INVALID_ARGS;
    }

    *pAvailableFrames = 0;

    if (pDataBuffer == NULL) {
        return MA_INVALID_ARGS;
    }

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

            return MA_BUSY;
        } else {
            return MA_INVALID_OPERATION;    /* No connector. */
        }
    }

    switch (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode))
    {
        case ma_resource_manager_data_supply_type_encoded:
        {
            return ma_decoder_get_available_frames(&pDataBuffer->connector.decoder, pAvailableFrames);
        };

        case ma_resource_manager_data_supply_type_decoded:
        {
            return ma_audio_buffer_get_available_frames(&pDataBuffer->connector.buffer, pAvailableFrames);
        };

        case ma_resource_manager_data_supply_type_decoded_paged:
        {
            ma_uint64 cursor;
            ma_paged_audio_buffer_get_cursor_in_pcm_frames(&pDataBuffer->connector.pagedBuffer, &cursor);

            if (pDataBuffer->pNode->data.backend.decodedPaged.decodedFrameCount > cursor) {
                *pAvailableFrames = pDataBuffer->pNode->data.backend.decodedPaged.decodedFrameCount - cursor;
            } else {
                *pAvailableFrames = 0;
            }

            return MA_SUCCESS;
        };

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

{
    return ma_resource_manager_data_buffer_node_acquire(pResourceManager, NULL, pFilePath, 0, flags, NULL, NULL, NULL, NULL);
}


static ma_result ma_resource_manager_register_data(ma_resource_manager* pResourceManager, const char* pName, const wchar_t* pNameW, ma_resource_manager_data_supply* pExistingData)
{
    return ma_resource_manager_data_buffer_node_acquire(pResourceManager, pName, pNameW, 0, 0, pExistingData, NULL, NULL, NULL);
}

static ma_result ma_resource_manager_register_decoded_data_internal(ma_resource_manager* pResourceManager, const char* pName, const wchar_t* pNameW, const void* pData, ma_uint64 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate)
{
    ma_resource_manager_data_supply data;
    data.type                            = ma_resource_manager_data_supply_type_decoded;
    data.backend.decoded.pData           = pData;
    data.backend.decoded.totalFrameCount = frameCount;
    data.backend.decoded.format          = format;
    data.backend.decoded.channels        = channels;
    data.backend.decoded.sampleRate      = sampleRate;

    return ma_resource_manager_register_data(pResourceManager, pName, pNameW, &data);
}

MA_API ma_result ma_resource_manager_register_decoded_data(ma_resource_manager* pResourceManager, const char* pName, const void* pData, ma_uint64 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate)
{
    return ma_resource_manager_register_decoded_data_internal(pResourceManager, pName, NULL, pData, frameCount, format, channels, sampleRate);
}

MA_API ma_result ma_resource_manager_register_decoded_data_w(ma_resource_manager* pResourceManager, const wchar_t* pName, const void* pData, ma_uint64 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate)
{
    return ma_resource_manager_register_decoded_data_internal(pResourceManager, NULL, pName, pData, frameCount, format, channels, sampleRate);
}


static ma_result ma_resource_manager_register_encoded_data_internal(ma_resource_manager* pResourceManager, const char* pName, const wchar_t* pNameW, const void* pData, size_t sizeInBytes)
{
    ma_resource_manager_data_supply data;
    data.type                        = ma_resource_manager_data_supply_type_encoded;
    data.backend.encoded.pData       = pData;
    data.backend.encoded.sizeInBytes = sizeInBytes;

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

    return c89atomic_load_32((ma_bool32*)&pDataStream->isDecoderAtEnd);
}

static ma_uint32 ma_resource_manager_data_stream_seek_counter(const ma_resource_manager_data_stream* pDataStream)
{
    MA_ASSERT(pDataStream != NULL);
    return c89atomic_load_32((ma_uint32*)&pDataStream->seekCounter);
}


static ma_result ma_resource_manager_data_stream_cb__read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    return ma_resource_manager_data_stream_read_pcm_frames((ma_resource_manager_data_stream*)pDataSource, pFramesOut, frameCount, pFramesRead);
}

static ma_result ma_resource_manager_data_stream_cb__seek_to_pcm_frame(ma_data_source* pDataSource, ma_uint64 frameIndex)
{
    return ma_resource_manager_data_stream_seek_to_pcm_frame((ma_resource_manager_data_stream*)pDataSource, frameIndex);
}

static ma_result ma_resource_manager_data_stream_cb__get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    return ma_resource_manager_data_stream_get_data_format((ma_resource_manager_data_stream*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
}

static ma_result ma_resource_manager_data_stream_cb__get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor)
{
    return ma_resource_manager_data_stream_get_cursor_in_pcm_frames((ma_resource_manager_data_stream*)pDataSource, pCursor);
}

static ma_result ma_resource_manager_data_stream_cb__get_length_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLength)
{
    return ma_resource_manager_data_stream_get_length_in_pcm_frames((ma_resource_manager_data_stream*)pDataSource, pLength);
}

static ma_result ma_resource_manager_data_stream_cb__set_looping(ma_data_source* pDataSource, ma_bool32 isLooping)
{
    ma_resource_manager_data_stream* pDataStream = (ma_resource_manager_data_stream*)pDataSource;
    MA_ASSERT(pDataStream != NULL);

    c89atomic_exchange_32(&pDataStream->isLooping, isLooping);

    return MA_SUCCESS;
}

static ma_data_source_vtable g_ma_resource_manager_data_stream_vtable =
{
    ma_resource_manager_data_stream_cb__read_pcm_frames,
    ma_resource_manager_data_stream_cb__seek_to_pcm_frame,
    ma_resource_manager_data_stream_cb__get_data_format,
    ma_resource_manager_data_stream_cb__get_cursor_in_pcm_frames,
    ma_resource_manager_data_stream_cb__get_length_in_pcm_frames,
    ma_resource_manager_data_stream_cb__set_looping,
    MA_DATA_SOURCE_SELF_MANAGED_RANGE_AND_LOOP_POINT
};

static void ma_resource_manager_data_stream_set_absolute_cursor(ma_resource_manager_data_stream* pDataStream, ma_uint64 absoluteCursor)
{
    /* Loop if possible. */
    if (absoluteCursor > pDataStream->totalLengthInPCMFrames && pDataStream->totalLengthInPCMFrames > 0) {
        absoluteCursor = absoluteCursor % pDataStream->totalLengthInPCMFrames;
    }

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

    result = ma_data_source_init(&dataSourceConfig, &pDataStream->ds);
    if (result != MA_SUCCESS) {
        ma_resource_manager_pipeline_notifications_signal_all_notifications(&notifications);
        return result;
    }

    pDataStream->pResourceManager = pResourceManager;
    pDataStream->flags            = pConfig->flags;
    pDataStream->result           = MA_BUSY;

    ma_data_source_set_range_in_pcm_frames(pDataStream, pConfig->rangeBegInPCMFrames, pConfig->rangeEndInPCMFrames);
    ma_data_source_set_loop_point_in_pcm_frames(pDataStream, pConfig->loopPointBegInPCMFrames, pConfig->loopPointEndInPCMFrames);
    ma_data_source_set_looping(pDataStream, pConfig->isLooping);

    if (pResourceManager == NULL || (pConfig->pFilePath == NULL && pConfig->pFilePathW == NULL)) {
        ma_resource_manager_pipeline_notifications_signal_all_notifications(&notifications);
        return MA_INVALID_ARGS;
    }

    /* We want all access to the VFS and the internal decoder to happen on the job thread just to keep things easier to manage for the VFS.  */

    /* We need a copy of the file path. We should probably make this more efficient, but for now we'll do a transient memory allocation. */

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

    job.data.resourceManager.freeDataStream.pDoneFence        = NULL;
    ma_resource_manager_post_job(pDataStream->pResourceManager, &job);

    /* We need to wait for the job to finish processing before we return. */
    ma_resource_manager_inline_notification_wait_and_uninit(&freeEvent);

    return MA_SUCCESS;
}


static ma_uint32 ma_resource_manager_data_stream_get_page_size_in_frames(ma_resource_manager_data_stream* pDataStream)
{
    MA_ASSERT(pDataStream != NULL);
    MA_ASSERT(pDataStream->isDecoderInitialized == MA_TRUE);

    return MA_RESOURCE_MANAGER_PAGE_SIZE_IN_MILLISECONDS * (pDataStream->decoder.outputSampleRate/1000);
}

static void* ma_resource_manager_data_stream_get_page_data_pointer(ma_resource_manager_data_stream* pDataStream, ma_uint32 pageIndex, ma_uint32 relativeCursor)
{
    MA_ASSERT(pDataStream != NULL);
    MA_ASSERT(pDataStream->isDecoderInitialized == MA_TRUE);
    MA_ASSERT(pageIndex == 0 || pageIndex == 1);

    return ma_offset_ptr(pDataStream->pPageData, ((ma_resource_manager_data_stream_get_page_size_in_frames(pDataStream) * pageIndex) + relativeCursor) * ma_get_bytes_per_frame(pDataStream->decoder.outputFormat, pDataStream->decoder.outputChannels));
}

static void ma_resource_manager_data_stream_fill_page(ma_resource_manager_data_stream* pDataStream, ma_uint32 pageIndex)
{
    ma_result result = MA_SUCCESS;
    ma_uint64 pageSizeInFrames;
    ma_uint64 totalFramesReadForThisPage = 0;
    void* pPageData = ma_resource_manager_data_stream_get_page_data_pointer(pDataStream, pageIndex, 0);

    pageSizeInFrames = ma_resource_manager_data_stream_get_page_size_in_frames(pDataStream);

    /* The decoder needs to inherit the stream's looping and range state. */
    {
        ma_uint64 rangeBeg;
        ma_uint64 rangeEnd;
        ma_uint64 loopPointBeg;
        ma_uint64 loopPointEnd;

        ma_data_source_set_looping(&pDataStream->decoder, ma_resource_manager_data_stream_is_looping(pDataStream));

        ma_data_source_get_range_in_pcm_frames(pDataStream, &rangeBeg, &rangeEnd);
        ma_data_source_set_range_in_pcm_frames(&pDataStream->decoder, rangeBeg, rangeEnd);

        ma_data_source_get_loop_point_in_pcm_frames(pDataStream, &loopPointBeg, &loopPointEnd);
        ma_data_source_set_loop_point_in_pcm_frames(&pDataStream->decoder, loopPointBeg, loopPointEnd);
    }

    /* Just read straight from the decoder. It will deal with ranges and looping for us. */
    result = ma_data_source_read_pcm_frames(&pDataStream->decoder, pPageData, pageSizeInFrames, &totalFramesReadForThisPage);
    if (result == MA_AT_END || totalFramesReadForThisPage < pageSizeInFrames) {
        c89atomic_exchange_32(&pDataStream->isDecoderAtEnd, MA_TRUE);
    }

    c89atomic_exchange_32(&pDataStream->pageFrameCount[pageIndex], (ma_uint32)totalFramesReadForThisPage);
    c89atomic_exchange_32(&pDataStream->isPageValid[pageIndex], MA_TRUE);
}

static void ma_resource_manager_data_stream_fill_pages(ma_resource_manager_data_stream* pDataStream)
{

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

    MA_ASSERT(pDataStream != NULL);

    for (iPage = 0; iPage < 2; iPage += 1) {
        ma_resource_manager_data_stream_fill_page(pDataStream, iPage);
    }
}


static ma_result ma_resource_manager_data_stream_map(ma_resource_manager_data_stream* pDataStream, void** ppFramesOut, ma_uint64* pFrameCount)
{
    ma_uint64 framesAvailable;
    ma_uint64 frameCount = 0;

    /* We cannot be using the data source after it's been uninitialized. */
    MA_ASSERT(ma_resource_manager_data_stream_result(pDataStream) != MA_UNAVAILABLE);

    if (pFrameCount != NULL) {
        frameCount = *pFrameCount;
        *pFrameCount = 0;
    }
    if (ppFramesOut != NULL) {
        *ppFramesOut = NULL;
    }

    if (pDataStream == NULL || ppFramesOut == NULL || pFrameCount == NULL) {
        return MA_INVALID_ARGS;
    }

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

        return MA_INVALID_OPERATION;
    }

    /* Don't attempt to read while we're in the middle of seeking. Tell the caller that we're busy. */
    if (ma_resource_manager_data_stream_seek_counter(pDataStream) > 0) {
        return MA_BUSY;
    }

    /* If the page we're on is invalid it means we've caught up to the job thread. */
    if (c89atomic_load_32(&pDataStream->isPageValid[pDataStream->currentPageIndex]) == MA_FALSE) {
        framesAvailable = 0;
    } else {
        /*
        The page we're on is valid so we must have some frames available. We need to make sure that we don't overflow into the next page, even if it's valid. The reason is
        that the unmap process will only post an update for one page at a time. Keeping mapping tied to page boundaries makes this simpler.
        */
        ma_uint32 currentPageFrameCount = c89atomic_load_32(&pDataStream->pageFrameCount[pDataStream->currentPageIndex]);
        MA_ASSERT(currentPageFrameCount >= pDataStream->relativeCursor);

        framesAvailable = currentPageFrameCount - pDataStream->relativeCursor;
    }

    /* If there's no frames available and the result is set to MA_AT_END we need to return MA_AT_END. */
    if (framesAvailable == 0) {
        if (ma_resource_manager_data_stream_is_decoder_at_end(pDataStream)) {
            return MA_AT_END;
        } else {
            return MA_BUSY; /* There are no frames available, but we're not marked as EOF so we might have caught up to the job thread. Need to return MA_BUSY and wait for more data. */
        }
    }

    MA_ASSERT(framesAvailable > 0);

    if (frameCount > framesAvailable) {
        frameCount = framesAvailable;
    }

    *ppFramesOut = ma_resource_manager_data_stream_get_page_data_pointer(pDataStream, pDataStream->currentPageIndex, pDataStream->relativeCursor);
    *pFrameCount = frameCount;

    return MA_SUCCESS;
}

static ma_result ma_resource_manager_data_stream_unmap(ma_resource_manager_data_stream* pDataStream, ma_uint64 frameCount)
{
    ma_uint32 newRelativeCursor;
    ma_uint32 pageSizeInFrames;
    ma_job job;

    /* We cannot be using the data source after it's been uninitialized. */
    MA_ASSERT(ma_resource_manager_data_stream_result(pDataStream) != MA_UNAVAILABLE);

    if (pDataStream == NULL) {
        return MA_INVALID_ARGS;
    }

    if (ma_resource_manager_data_stream_result(pDataStream) != MA_SUCCESS) {
        return MA_INVALID_OPERATION;
    }

    /* The frame count should always fit inside a 32-bit integer. */
    if (frameCount > 0xFFFFFFFF) {
        return MA_INVALID_ARGS;
    }

    pageSizeInFrames = ma_resource_manager_data_stream_get_page_size_in_frames(pDataStream);

    /* The absolute cursor needs to be updated for ma_resource_manager_data_stream_get_cursor_in_pcm_frames(). */
    ma_resource_manager_data_stream_set_absolute_cursor(pDataStream, c89atomic_load_64(&pDataStream->absoluteCursor) + frameCount);

    /* Here is where we need to check if we need to load a new page, and if so, post a job to load it. */
    newRelativeCursor = pDataStream->relativeCursor + (ma_uint32)frameCount;

    /* If the new cursor has flowed over to the next page we need to mark the old one as invalid and post an event for it. */
    if (newRelativeCursor >= pageSizeInFrames) {
        newRelativeCursor -= pageSizeInFrames;

        /* Here is where we post the job start decoding. */
        job = ma_job_init(MA_JOB_TYPE_RESOURCE_MANAGER_PAGE_DATA_STREAM);
        job.order = ma_resource_manager_data_stream_next_execution_order(pDataStream);
        job.data.resourceManager.pageDataStream.pDataStream = pDataStream;
        job.data.resourceManager.pageDataStream.pageIndex   = pDataStream->currentPageIndex;

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

        pDataStream->currentPageIndex = (pDataStream->currentPageIndex + 1) & 0x01;
        return ma_resource_manager_post_job(pDataStream->pResourceManager, &job);
    } else {
        /* We haven't moved into a new page so we can just move the cursor forward. */
        pDataStream->relativeCursor = newRelativeCursor;
        return MA_SUCCESS;
    }
}


MA_API ma_result ma_resource_manager_data_stream_read_pcm_frames(ma_resource_manager_data_stream* pDataStream, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_result result = MA_SUCCESS;
    ma_uint64 totalFramesProcessed;
    ma_format format;
    ma_uint32 channels;

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

    if (frameCount == 0) {
        return MA_INVALID_ARGS;
    }

    /* We cannot be using the data source after it's been uninitialized. */
    MA_ASSERT(ma_resource_manager_data_stream_result(pDataStream) != MA_UNAVAILABLE);

    if (pDataStream == NULL) {
        return MA_INVALID_ARGS;
    }

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


    /* Don't attempt to read while we're in the middle of seeking. Tell the caller that we're busy. */
    if (ma_resource_manager_data_stream_seek_counter(pDataStream) > 0) {
        return MA_BUSY;
    }

    ma_resource_manager_data_stream_get_data_format(pDataStream, &format, &channels, NULL, NULL, 0);

    /* Reading is implemented in terms of map/unmap. We need to run this in a loop because mapping is clamped against page boundaries. */
    totalFramesProcessed = 0;
    while (totalFramesProcessed < frameCount) {
        void* pMappedFrames;
        ma_uint64 mappedFrameCount;

        mappedFrameCount = frameCount - totalFramesProcessed;
        result = ma_resource_manager_data_stream_map(pDataStream, &pMappedFrames, &mappedFrameCount);
        if (result != MA_SUCCESS) {
            break;
        }

        /* Copy the mapped data to the output buffer if we have one. It's allowed for pFramesOut to be NULL in which case a relative forward seek is performed. */
        if (pFramesOut != NULL) {
            ma_copy_pcm_frames(ma_offset_pcm_frames_ptr(pFramesOut, totalFramesProcessed, format, channels), pMappedFrames, mappedFrameCount, format, channels);
        }

        totalFramesProcessed += mappedFrameCount;

        result = ma_resource_manager_data_stream_unmap(pDataStream, mappedFrameCount);
        if (result != MA_SUCCESS) {
            break;  /* This is really bad - will only get an error here if we failed to post a job to the queue for loading the next page. */
        }
    }

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

        *pFramesRead = totalFramesProcessed;
    }

    if (result == MA_SUCCESS && totalFramesProcessed == 0) {
        result  = MA_AT_END;
    }

    return result;
}

MA_API ma_result ma_resource_manager_data_stream_seek_to_pcm_frame(ma_resource_manager_data_stream* pDataStream, ma_uint64 frameIndex)
{
    ma_job job;
    ma_result streamResult;

    streamResult = ma_resource_manager_data_stream_result(pDataStream);

    /* We cannot be using the data source after it's been uninitialized. */
    MA_ASSERT(streamResult != MA_UNAVAILABLE);

    if (pDataStream == NULL) {
        return MA_INVALID_ARGS;
    }

    if (streamResult != MA_SUCCESS && streamResult != MA_BUSY) {
        return MA_INVALID_OPERATION;
    }

    /* If we're not already seeking and we're sitting on the same frame, just make this a no-op. */
    if (c89atomic_load_32(&pDataStream->seekCounter) == 0) {
        if (c89atomic_load_64(&pDataStream->absoluteCursor) == frameIndex) {
            return MA_SUCCESS;
        }
    }


    /* Increment the seek counter first to indicate to read_paged_pcm_frames() and map_paged_pcm_frames() that we are in the middle of a seek and MA_BUSY should be returned. */
    c89atomic_fetch_add_32(&pDataStream->seekCounter, 1);

    /* Update the absolute cursor so that ma_resource_manager_data_stream_get_cursor_in_pcm_frames() returns the new position. */
    ma_resource_manager_data_stream_set_absolute_cursor(pDataStream, frameIndex);

    /*
    We need to clear our currently loaded pages so that the stream starts playback from the new seek point as soon as possible. These are for the purpose of the public
    API and will be ignored by the seek job. The seek job will operate on the assumption that both pages have been marked as invalid and the cursor is at the start of
    the first page.
    */
    pDataStream->relativeCursor   = 0;
    pDataStream->currentPageIndex = 0;
    c89atomic_exchange_32(&pDataStream->isPageValid[0], MA_FALSE);
    c89atomic_exchange_32(&pDataStream->isPageValid[1], MA_FALSE);

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

    /* Make sure the data stream is not marked as at the end or else if we seek in response to hitting the end, we won't be able to read any more data. */
    c89atomic_exchange_32(&pDataStream->isDecoderAtEnd, MA_FALSE);

    /*
    The public API is not allowed to touch the internal decoder so we need to use a job to perform the seek. When seeking, the job thread will assume both pages
    are invalid and any content contained within them will be discarded and replaced with newly decoded data.
    */
    job = ma_job_init(MA_JOB_TYPE_RESOURCE_MANAGER_SEEK_DATA_STREAM);
    job.order = ma_resource_manager_data_stream_next_execution_order(pDataStream);
    job.data.resourceManager.seekDataStream.pDataStream = pDataStream;
    job.data.resourceManager.seekDataStream.frameIndex  = frameIndex;
    return ma_resource_manager_post_job(pDataStream->pResourceManager, &job);
}

MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_manager_data_stream* pDataStream, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    /* We cannot be using the data source after it's been uninitialized. */
    MA_ASSERT(ma_resource_manager_data_stream_result(pDataStream) != MA_UNAVAILABLE);

    if (pFormat != NULL) {
        *pFormat = ma_format_unknown;

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

        return MA_INVALID_OPERATION;
    }

    /*
    We're being a little bit naughty here and accessing the internal decoder from the public API. The output data format is constant, and we've defined this function
    such that the application is responsible for ensuring it's not called while uninitializing so it should be safe.
    */
    return ma_data_source_get_data_format(&pDataStream->decoder, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
}

MA_API ma_result ma_resource_manager_data_stream_get_cursor_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pCursor)
{
    ma_result result;

    if (pCursor == NULL) {
        return MA_INVALID_ARGS;
    }

    *pCursor = 0;

    /* We cannot be using the data source after it's been uninitialized. */

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

    result = ma_resource_manager_data_stream_result(pDataStream);
    if (result != MA_SUCCESS && result != MA_BUSY) {
        return MA_INVALID_OPERATION;
    }

    *pCursor = c89atomic_load_64(&pDataStream->absoluteCursor);

    return MA_SUCCESS;
}

MA_API ma_result ma_resource_manager_data_stream_get_length_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pLength)
{
    ma_result streamResult;

    if (pLength == NULL) {
        return MA_INVALID_ARGS;
    }

    *pLength = 0;

    streamResult = ma_resource_manager_data_stream_result(pDataStream);

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


    if (pDataStream == NULL) {
        return MA_INVALID_ARGS;
    }

    if (streamResult != MA_SUCCESS) {
        return streamResult;
    }

    /*
    We most definitely do not want to be calling ma_decoder_get_length_in_pcm_frames() directly. Instead we want to use a cached value that we
    calculated when we initialized it on the job thread.
    */
    *pLength = pDataStream->totalLengthInPCMFrames;
    if (*pLength == 0) {
        return MA_NOT_IMPLEMENTED;  /* Some decoders may not have a known length. */
    }

    return MA_SUCCESS;
}

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


MA_API ma_bool32 ma_resource_manager_data_stream_is_looping(const ma_resource_manager_data_stream* pDataStream)
{
    if (pDataStream == NULL) {
        return MA_FALSE;
    }

    return c89atomic_load_32((ma_bool32*)&pDataStream->isLooping);   /* Naughty const-cast. Value won't change from here in practice (maybe from another thread). */
}

MA_API ma_result ma_resource_manager_data_stream_get_available_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pAvailableFrames)
{
    ma_uint32 pageIndex0;
    ma_uint32 pageIndex1;
    ma_uint32 relativeCursor;
    ma_uint64 availableFrames;

    if (pAvailableFrames == NULL) {
        return MA_INVALID_ARGS;
    }

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

    }

    /* All we need to is uninitialize the underlying data buffer or data stream. */
    if ((pDataSource->flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM) != 0) {
        return ma_resource_manager_data_stream_uninit(&pDataSource->backend.stream);
    } else {
        return ma_resource_manager_data_buffer_uninit(&pDataSource->backend.buffer);
    }
}

MA_API ma_result ma_resource_manager_data_source_read_pcm_frames(ma_resource_manager_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    /* Safety. */
    if (pFramesRead != NULL) {
        *pFramesRead = 0;
    }

    if (pDataSource == NULL) {
        return MA_INVALID_ARGS;
    }

    if ((pDataSource->flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM) != 0) {
        return ma_resource_manager_data_stream_read_pcm_frames(&pDataSource->backend.stream, pFramesOut, frameCount, pFramesRead);
    } else {
        return ma_resource_manager_data_buffer_read_pcm_frames(&pDataSource->backend.buffer, pFramesOut, frameCount, pFramesRead);
    }
}

MA_API ma_result ma_resource_manager_data_source_seek_to_pcm_frame(ma_resource_manager_data_source* pDataSource, ma_uint64 frameIndex)
{
    if (pDataSource == NULL) {
        return MA_INVALID_ARGS;
    }

    if ((pDataSource->flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM) != 0) {
        return ma_resource_manager_data_stream_seek_to_pcm_frame(&pDataSource->backend.stream, frameIndex);
    } else {
        return ma_resource_manager_data_buffer_seek_to_pcm_frame(&pDataSource->backend.buffer, frameIndex);
    }
}

MA_API ma_result ma_resource_manager_data_source_map(ma_resource_manager_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount)
{
    if (pDataSource == NULL) {
        return MA_INVALID_ARGS;
    }

    if ((pDataSource->flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM) != 0) {
        return ma_resource_manager_data_stream_map(&pDataSource->backend.stream, ppFramesOut, pFrameCount);
    } else {
        return MA_NOT_IMPLEMENTED;  /* Mapping not supported with data buffers. */
    }
}

MA_API ma_result ma_resource_manager_data_source_unmap(ma_resource_manager_data_source* pDataSource, ma_uint64 frameCount)
{
    if (pDataSource == NULL) {
        return MA_INVALID_ARGS;
    }

    if ((pDataSource->flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM) != 0) {
        return ma_resource_manager_data_stream_unmap(&pDataSource->backend.stream, frameCount);
    } else {
        return MA_NOT_IMPLEMENTED;  /* Mapping not supported with data buffers. */
    }
}

MA_API ma_result ma_resource_manager_data_source_get_data_format(ma_resource_manager_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    if (pDataSource == NULL) {
        return MA_INVALID_ARGS;
    }

    if ((pDataSource->flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM) != 0) {
        return ma_resource_manager_data_stream_get_data_format(&pDataSource->backend.stream, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
    } else {
        return ma_resource_manager_data_buffer_get_data_format(&pDataSource->backend.buffer, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
    }
}

MA_API ma_result ma_resource_manager_data_source_get_cursor_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pCursor)
{
    if (pDataSource == NULL) {
        return MA_INVALID_ARGS;
    }

    if ((pDataSource->flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM) != 0) {
        return ma_resource_manager_data_stream_get_cursor_in_pcm_frames(&pDataSource->backend.stream, pCursor);
    } else {
        return ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(&pDataSource->backend.buffer, pCursor);
    }
}

MA_API ma_result ma_resource_manager_data_source_get_length_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pLength)
{
    if (pDataSource == NULL) {
        return MA_INVALID_ARGS;
    }

    if ((pDataSource->flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM) != 0) {
        return ma_resource_manager_data_stream_get_length_in_pcm_frames(&pDataSource->backend.stream, pLength);
    } else {
        return ma_resource_manager_data_buffer_get_length_in_pcm_frames(&pDataSource->backend.buffer, pLength);
    }
}

MA_API ma_result ma_resource_manager_data_source_result(const ma_resource_manager_data_source* pDataSource)
{
    if (pDataSource == NULL) {
        return MA_INVALID_ARGS;
    }

    if ((pDataSource->flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM) != 0) {

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

        return MA_FALSE;
    }

    if ((pDataSource->flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM) != 0) {
        return ma_resource_manager_data_stream_is_looping(&pDataSource->backend.stream);
    } else {
        return ma_resource_manager_data_buffer_is_looping(&pDataSource->backend.buffer);
    }
}

MA_API ma_result ma_resource_manager_data_source_get_available_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pAvailableFrames)
{
    if (pAvailableFrames == NULL) {
        return MA_INVALID_ARGS;
    }

    *pAvailableFrames = 0;

    if (pDataSource == NULL) {
        return MA_INVALID_ARGS;
    }

    if ((pDataSource->flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM) != 0) {
        return ma_resource_manager_data_stream_get_available_frames(&pDataSource->backend.stream, pAvailableFrames);
    } else {
        return ma_resource_manager_data_buffer_get_available_frames(&pDataSource->backend.buffer, pAvailableFrames);
    }
}


MA_API ma_result ma_resource_manager_post_job(ma_resource_manager* pResourceManager, const ma_job* pJob)
{
    if (pResourceManager == NULL) {
        return MA_INVALID_ARGS;
    }

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

        result = ma_decoder_init_vfs(pResourceManager->config.pVFS, pJob->data.resourceManager.loadDataStream.pFilePath, &decoderConfig, &pDataStream->decoder);
    } else {
        result = ma_decoder_init_vfs_w(pResourceManager->config.pVFS, pJob->data.resourceManager.loadDataStream.pFilePathW, &decoderConfig, &pDataStream->decoder);
    }
    if (result != MA_SUCCESS) {
        goto done;
    }

    /* Retrieve the total length of the file before marking the decoder are loaded. */
    if ((pDataStream->flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH) == 0) {
        result = ma_decoder_get_length_in_pcm_frames(&pDataStream->decoder, &pDataStream->totalLengthInPCMFrames);
        if (result != MA_SUCCESS) {
            goto done;  /* Failed to retrieve the length. */
        }
    } else {
        pDataStream->totalLengthInPCMFrames = 0;
    }

    /*
    Only mark the decoder as initialized when the length of the decoder has been retrieved because that can possibly require a scan over the whole file
    and we don't want to have another thread trying to access the decoder while it's scanning.
    */
    pDataStream->isDecoderInitialized = MA_TRUE;

    /* We have the decoder so we can now initialize our page buffer. */
    pageBufferSizeInBytes = ma_resource_manager_data_stream_get_page_size_in_frames(pDataStream) * 2 * ma_get_bytes_per_frame(pDataStream->decoder.outputFormat, pDataStream->decoder.outputChannels);

    pDataStream->pPageData = ma_malloc(pageBufferSizeInBytes, &pResourceManager->config.allocationCallbacks);
    if (pDataStream->pPageData == NULL) {
        ma_decoder_uninit(&pDataStream->decoder);
        result = MA_OUT_OF_MEMORY;
        goto done;
    }

    /* Seek to our initial seek point before filling the initial pages. */
    ma_decoder_seek_to_pcm_frame(&pDataStream->decoder, pJob->data.resourceManager.loadDataStream.initialSeekPoint);

    /* We have our decoder and our page buffer, so now we need to fill our pages. */
    ma_resource_manager_data_stream_fill_pages(pDataStream);

    /* And now we're done. We want to make sure the result is MA_SUCCESS. */
    result = MA_SUCCESS;

done:
    ma_free(pJob->data.resourceManager.loadDataStream.pFilePath,  &pResourceManager->config.allocationCallbacks);
    ma_free(pJob->data.resourceManager.loadDataStream.pFilePathW, &pResourceManager->config.allocationCallbacks);

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

        return ma_resource_manager_post_job(pResourceManager, pJob);    /* Out of order. */
    }

    /* For streams the status should be MA_SUCCESS for this to do anything. */
    if (ma_resource_manager_data_stream_result(pDataStream) != MA_SUCCESS || pDataStream->isDecoderInitialized == MA_FALSE) {
        result = MA_INVALID_OPERATION;
        goto done;
    }

    /*
    With seeking we just assume both pages are invalid and the relative frame cursor at position 0. This is basically exactly the same as loading, except
    instead of initializing the decoder, we seek to a frame.
    */
    ma_decoder_seek_to_pcm_frame(&pDataStream->decoder, pJob->data.resourceManager.seekDataStream.frameIndex);

    /* After seeking we'll need to reload the pages. */
    ma_resource_manager_data_stream_fill_pages(pDataStream);

    /* We need to let the public API know that we're done seeking. */
    c89atomic_fetch_sub_32(&pDataStream->seekCounter, 1);

done:
    c89atomic_fetch_add_32(&pDataStream->executionPointer, 1);
    return result;

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

#endif  /* MA_NO_RESOURCE_MANAGER */


#ifndef MA_NO_NODE_GRAPH
/* 10ms @ 48K = 480. Must never exceed 65535. */
#ifndef MA_DEFAULT_NODE_CACHE_CAP_IN_FRAMES_PER_BUS
#define MA_DEFAULT_NODE_CACHE_CAP_IN_FRAMES_PER_BUS 480
#endif


static ma_result ma_node_read_pcm_frames(ma_node* pNode, ma_uint32 outputBusIndex, float* pFramesOut, ma_uint32 frameCount, ma_uint32* pFramesRead, ma_uint64 globalTime);

MA_API void ma_debug_fill_pcm_frames_with_sine_wave(float* pFramesOut, ma_uint32 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate)
{
    #ifndef MA_NO_GENERATION
    {
        ma_waveform_config waveformConfig;
        ma_waveform waveform;

        waveformConfig = ma_waveform_config_init(format, channels, sampleRate, ma_waveform_type_sine, 1.0, 400);
        ma_waveform_init(&waveformConfig, &waveform);
        ma_waveform_read_pcm_frames(&waveform, pFramesOut, frameCount, NULL);
    }
    #else
    {
        (void)pFramesOut;
        (void)frameCount;
        (void)format;
        (void)channels;
        (void)sampleRate;
        #if defined(MA_DEBUG_OUTPUT)
        {
            #if _MSC_VER
                #pragma message ("ma_debug_fill_pcm_frames_with_sine_wave() will do nothing because MA_NO_GENERATION is enabled.")
            #endif
        }
        #endif
    }
    #endif
}



static ma_result ma_mix_pcm_frames_f32(float* pDst, const float* pSrc, ma_uint64 frameCount, ma_uint32 channels, float volume)
{
    ma_uint64 iSample;
    ma_uint64 sampleCount;

    if (pDst == NULL || pSrc == NULL || channels == 0) {
        return MA_INVALID_ARGS;
    }

    if (volume == 0) {
        return MA_SUCCESS;  /* No changes if the volume is 0. */
    }

    sampleCount = frameCount * channels;

    if (volume == 1) {
        for (iSample = 0; iSample < sampleCount; iSample += 1) {
            pDst[iSample] += pSrc[iSample];
        }
    } else {
        for (iSample = 0; iSample < sampleCount; iSample += 1) {
            pDst[iSample] += ma_apply_volume_unclipped_f32(pSrc[iSample], volume);
        }
    }

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


#if 0
static ma_bool32 ma_node_graph_is_reading(ma_node_graph* pNodeGraph)
{
    MA_ASSERT(pNodeGraph != NULL);
    return c89atomic_load_32(&pNodeGraph->isReading);
}
#endif


static void ma_node_graph_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_node_graph* pNodeGraph = (ma_node_graph*)pNode;
    ma_uint64 framesRead;

    ma_node_graph_read_pcm_frames(pNodeGraph, ppFramesOut[0], *pFrameCountOut, &framesRead);

    *pFrameCountOut = (ma_uint32)framesRead;    /* Safe cast. */

    (void)ppFramesIn;
    (void)pFrameCountIn;
}

static ma_node_vtable g_node_graph_node_vtable =
{
    ma_node_graph_node_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    0,      /* 0 input buses. */
    1,      /* 1 output bus. */
    0       /* Flags. */
};

static void ma_node_graph_endpoint_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    MA_ASSERT(pNode != NULL);
    MA_ASSERT(ma_node_get_input_bus_count(pNode)  == 1);
    MA_ASSERT(ma_node_get_output_bus_count(pNode) == 1);

    /* Input channel count needs to be the same as the output channel count. */
    MA_ASSERT(ma_node_get_input_channels(pNode, 0) == ma_node_get_output_channels(pNode, 0));

    /* We don't need to do anything here because it's a passthrough. */
    (void)pNode;
    (void)ppFramesIn;
    (void)pFrameCountIn;
    (void)ppFramesOut;
    (void)pFrameCountOut;

#if 0
    /* The data has already been mixed. We just need to move it to the output buffer. */
    if (ppFramesIn != NULL) {
        ma_copy_pcm_frames(ppFramesOut[0], ppFramesIn[0], *pFrameCountOut, ma_format_f32, ma_node_get_output_channels(pNode, 0));
    }
#endif
}

static ma_node_vtable g_node_graph_endpoint_vtable =
{
    ma_node_graph_endpoint_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    1,      /* 1 input bus. */
    1,      /* 1 output bus. */
    MA_NODE_FLAG_PASSTHROUGH    /* Flags. The endpoint is a passthrough. */
};

MA_API ma_result ma_node_graph_init(const ma_node_graph_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_node_graph* pNodeGraph)
{
    ma_result result;
    ma_node_config baseConfig;

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


MA_API ma_node* ma_node_graph_get_endpoint(ma_node_graph* pNodeGraph)
{
    if (pNodeGraph == NULL) {
        return NULL;
    }

    return &pNodeGraph->endpoint;
}

MA_API ma_result ma_node_graph_read_pcm_frames(ma_node_graph* pNodeGraph, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_result result = MA_SUCCESS;
    ma_uint64 totalFramesRead;
    ma_uint32 channels;

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

    if (pNodeGraph == NULL) {
        return MA_INVALID_ARGS;
    }

    channels = ma_node_get_output_channels(&pNodeGraph->endpoint, 0);


    /* We'll be nice and try to do a full read of all frameCount frames. */
    totalFramesRead = 0;
    while (totalFramesRead < frameCount) {
        ma_uint32 framesJustRead;
        ma_uint64 framesToRead = frameCount - totalFramesRead;

        if (framesToRead > 0xFFFFFFFF) {
            framesToRead = 0xFFFFFFFF;
        }

        ma_node_graph_set_is_reading(pNodeGraph, MA_TRUE);
        {
            result = ma_node_read_pcm_frames(&pNodeGraph->endpoint, 0, (float*)ma_offset_pcm_frames_ptr(pFramesOut, totalFramesRead, ma_format_f32, channels), (ma_uint32)framesToRead, &framesJustRead, ma_node_get_time(&pNodeGraph->endpoint));
        }
        ma_node_graph_set_is_reading(pNodeGraph, MA_FALSE);

        totalFramesRead += framesJustRead;

        if (result != MA_SUCCESS) {
            break;
        }

        /* Abort if we weren't able to read any frames or else we risk getting stuck in a loop. */
        if (framesJustRead == 0) {
            break;
        }
    }

    /* Let's go ahead and silence any leftover frames just for some added safety to ensure the caller doesn't try emitting garbage out of the speakers. */
    if (totalFramesRead < frameCount) {
        ma_silence_pcm_frames(ma_offset_pcm_frames_ptr(pFramesOut, totalFramesRead, ma_format_f32, channels), (frameCount - totalFramesRead), ma_format_f32, channels);
    }

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

    return result;
}

MA_API ma_uint32 ma_node_graph_get_channels(const ma_node_graph* pNodeGraph)

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

    return pNext;
}

static ma_node_output_bus* ma_node_input_bus_first(ma_node_input_bus* pInputBus)
{
    return ma_node_input_bus_next(pInputBus, &pInputBus->head);
}



static ma_result ma_node_input_bus_read_pcm_frames(ma_node* pInputNode, ma_node_input_bus* pInputBus, float* pFramesOut, ma_uint32 frameCount, ma_uint32* pFramesRead, ma_uint64 globalTime)
{
    ma_result result = MA_SUCCESS;
    ma_node_output_bus* pOutputBus;
    ma_node_output_bus* pFirst;
    ma_uint32 inputChannels;
    ma_bool32 doesOutputBufferHaveContent = MA_FALSE;

    /*
    This will be called from the audio thread which means we can't be doing any locking. Basically,
    this function will not perfom any locking, whereas attaching and detaching will, but crafted in

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

    to always iterate in a forward direction.

    In order to process any data we need to first read from all input buses. That's where this
    function comes in. This iterates over each of the attachments and accumulates/mixes them. We
    also convert the channels to the nodes output channel count before mixing. We want to do this
    channel conversion so that the caller of this function can invoke the processing callback
    without having to do it themselves.

    When we iterate over each of the attachments on the input bus, we need to read as much data as
    we can from each of them so that we don't end up with holes between each of the attachments. To
    do this, we need to read from each attachment in a loop and read as many frames as we can, up
    to `frameCount`.
    */
    MA_ASSERT(pInputNode  != NULL);
    MA_ASSERT(pFramesRead != NULL); /* pFramesRead is critical and must always be specified. On input it's undefined and on output it'll be set to the number of frames actually read. */

    *pFramesRead = 0;   /* Safety. */

    inputChannels = ma_node_input_bus_get_channels(pInputBus);

    /*
    We need to be careful with how we call ma_node_input_bus_first() and ma_node_input_bus_next(). They
    are both critical to our lock-free thread-safety system. We can only call ma_node_input_bus_first()
    once per iteration, however we have an optimization to checks whether or not it's the first item in
    the list. We therefore need to store a pointer to the first item rather than repeatedly calling
    ma_node_input_bus_first(). It's safe to keep hold of this pointer, so long as we don't dereference it
    after calling ma_node_input_bus_next(), which we won't be.
    */
    pFirst = ma_node_input_bus_first(pInputBus);
    if (pFirst == NULL) {
        return MA_SUCCESS;  /* No attachments. Read nothing. */
    }

    for (pOutputBus = pFirst; pOutputBus != NULL; pOutputBus = ma_node_input_bus_next(pInputBus, pOutputBus)) {
        ma_uint32 framesProcessed = 0;
        ma_bool32 isSilentOutput = MA_FALSE;

        MA_ASSERT(pOutputBus->pNode != NULL);

        isSilentOutput = (((ma_node_base*)pOutputBus->pNode)->vtable->flags & MA_NODE_FLAG_SILENT_OUTPUT) != 0;

        if (pFramesOut != NULL) {
            /* Read. */
            float temp[MA_DATA_CONVERTER_STACK_BUFFER_SIZE / sizeof(float)];
            ma_uint32 tempCapInFrames = ma_countof(temp) / inputChannels;

            while (framesProcessed < frameCount) {
                float* pRunningFramesOut;
                ma_uint32 framesToRead;
                ma_uint32 framesJustRead;

                framesToRead = frameCount - framesProcessed;
                if (framesToRead > tempCapInFrames) {
                    framesToRead = tempCapInFrames;
                }

                pRunningFramesOut = ma_offset_pcm_frames_ptr_f32(pFramesOut, framesProcessed, inputChannels);

                if (doesOutputBufferHaveContent == MA_FALSE) {
                    /* Fast path. First attachment. We just read straight into the output buffer (no mixing required). */
                    result = ma_node_read_pcm_frames(pOutputBus->pNode, pOutputBus->outputBusIndex, pRunningFramesOut, framesToRead, &framesJustRead, globalTime + framesProcessed);
                } else {
                    /* Slow path. Not the first attachment. Mixing required. */
                    result = ma_node_read_pcm_frames(pOutputBus->pNode, pOutputBus->outputBusIndex, temp, framesToRead, &framesJustRead, globalTime + framesProcessed);
                    if (result == MA_SUCCESS || result == MA_AT_END) {
                        if (isSilentOutput == MA_FALSE) {   /* Don't mix if the node outputs silence. */
                            ma_mix_pcm_frames_f32(pRunningFramesOut, temp, framesJustRead, inputChannels, /*volume*/1);
                        }
                    }
                }

                framesProcessed += framesJustRead;

                /* If we reached the end or otherwise failed to read any data we need to finish up with this output node. */
                if (result != MA_SUCCESS) {
                    break;
                }

                /* If we didn't read anything, abort so we don't get stuck in a loop. */
                if (framesJustRead == 0) {
                    break;
                }
            }

            /* If it's the first attachment we didn't do any mixing. Any leftover samples need to be silenced. */
            if (pOutputBus == pFirst && framesProcessed < frameCount) {
                ma_silence_pcm_frames(ma_offset_pcm_frames_ptr(pFramesOut, framesProcessed, ma_format_f32, inputChannels), (frameCount - framesProcessed), ma_format_f32, inputChannels);
            }

            if (isSilentOutput == MA_FALSE) {
                doesOutputBufferHaveContent = MA_TRUE;
            }
        } else {
            /* Seek. */
            ma_node_read_pcm_frames(pOutputBus->pNode, pOutputBus->outputBusIndex, NULL, frameCount, &framesProcessed, globalTime);
        }
    }

    /* If we didn't output anything, output silence. */
    if (doesOutputBufferHaveContent == MA_FALSE && pFramesOut != NULL) {
        ma_silence_pcm_frames(pFramesOut, frameCount, ma_format_f32, inputChannels);
    }

    /* In this path we always "process" the entire amount. */
    *pFramesRead = frameCount;

    return result;
}


MA_API ma_node_config ma_node_config_init(void)
{
    ma_node_config config;

    MA_ZERO_OBJECT(&config);

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

    Cached audio data.

    We need to allocate memory for a caching both input and output data. We have an optimization
    where no caching is necessary for specific conditions:

        - The node has 0 inputs and 1 output.

    When a node meets the above conditions, no cache is allocated.

    The size choice for this buffer is a little bit finicky. We don't want to be too wasteful by
    allocating too much, but at the same time we want it be large enough so that enough frames can
    be processed for each call to ma_node_read_pcm_frames() so that it keeps things efficient. For
    now I'm going with 10ms @ 48K which is 480 frames per bus. This is configurable at compile
    time. It might also be worth investigating whether or not this can be configured at run time.
    */
    if (inputBusCount == 0 && outputBusCount == 1) {
        /* Fast path. No cache needed. */
        pHeapLayout->cachedDataOffset = MA_SIZE_MAX;
    } else {
        /* Slow path. Cache needed. */
        size_t cachedDataSizeInBytes = 0;
        ma_uint32 iBus;

        for (iBus = 0; iBus < inputBusCount; iBus += 1) {
            cachedDataSizeInBytes += pNodeGraph->nodeCacheCapInFrames * ma_get_bytes_per_frame(ma_format_f32, pConfig->pInputChannels[iBus]);
        }

        for (iBus = 0; iBus < outputBusCount; iBus += 1) {
            cachedDataSizeInBytes += pNodeGraph->nodeCacheCapInFrames * ma_get_bytes_per_frame(ma_format_f32, pConfig->pOutputChannels[iBus]);
        }

        pHeapLayout->cachedDataOffset = pHeapLayout->sizeInBytes;
        pHeapLayout->sizeInBytes += ma_align_64(cachedDataSizeInBytes);
    }


    /*
    Not technically part of the heap, but we can output the input and output bus counts so we can
    avoid a redundant call to ma_node_translate_bus_counts().

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

    }


    /* The cached data needs to be initialized to silence (or a sine wave tone if we're debugging). */
    if (pNodeBase->pCachedData != NULL) {
        ma_uint32 iBus;

    #if 1   /* Toggle this between 0 and 1 to turn debugging on or off. 1 = fill with a sine wave for debugging; 0 = fill with silence. */
        /* For safety we'll go ahead and default the buffer to silence. */
        for (iBus = 0; iBus < ma_node_get_input_bus_count(pNodeBase); iBus += 1) {
            ma_silence_pcm_frames(ma_node_get_cached_input_ptr(pNode, iBus), pNodeBase->cachedDataCapInFramesPerBus, ma_format_f32, ma_node_input_bus_get_channels(&pNodeBase->pInputBuses[iBus]));
        }
        for (iBus = 0; iBus < ma_node_get_output_bus_count(pNodeBase); iBus += 1) {
            ma_silence_pcm_frames(ma_node_get_cached_output_ptr(pNode, iBus), pNodeBase->cachedDataCapInFramesPerBus, ma_format_f32, ma_node_output_bus_get_channels(&pNodeBase->pOutputBuses[iBus]));
        }
    #else
        /* For debugging. Default to a sine wave. */
        for (iBus = 0; iBus < ma_node_get_input_bus_count(pNodeBase); iBus += 1) {
            ma_debug_fill_pcm_frames_with_sine_wave(ma_node_get_cached_input_ptr(pNode, iBus), pNodeBase->cachedDataCapInFramesPerBus, ma_format_f32, ma_node_input_bus_get_channels(&pNodeBase->pInputBuses[iBus]), 48000);
        }
        for (iBus = 0; iBus < ma_node_get_output_bus_count(pNodeBase); iBus += 1) {
            ma_debug_fill_pcm_frames_with_sine_wave(ma_node_get_cached_output_ptr(pNode, iBus), pNodeBase->cachedDataCapInFramesPerBus, ma_format_f32, ma_node_output_bus_get_channels(&pNodeBase->pOutputBuses[iBus]), 48000);
        }
    #endif
    }

    return MA_SUCCESS;
}

MA_API ma_result ma_node_init(ma_node_graph* pNodeGraph, const ma_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_node* pNode)
{
    ma_result result;

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

        return MA_INVALID_ARGS;
    }

    c89atomic_exchange_64(&((ma_node_base*)pNode)->localTime, localTime);

    return MA_SUCCESS;
}



static void ma_node_process_pcm_frames_internal(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_node_base* pNodeBase = (ma_node_base*)pNode;

    MA_ASSERT(pNode != NULL);

    if (pNodeBase->vtable->onProcess) {
        pNodeBase->vtable->onProcess(pNode, ppFramesIn, pFrameCountIn, ppFramesOut, pFrameCountOut);
    }
}

static ma_result ma_node_read_pcm_frames(ma_node* pNode, ma_uint32 outputBusIndex, float* pFramesOut, ma_uint32 frameCount, ma_uint32* pFramesRead, ma_uint64 globalTime)
{
    ma_node_base* pNodeBase = (ma_node_base*)pNode;
    ma_result result = MA_SUCCESS;
    ma_uint32 iInputBus;
    ma_uint32 iOutputBus;
    ma_uint32 inputBusCount;
    ma_uint32 outputBusCount;
    ma_uint32 totalFramesRead = 0;
    float* ppFramesIn[MA_MAX_NODE_BUS_COUNT];
    float* ppFramesOut[MA_MAX_NODE_BUS_COUNT];
    ma_uint64 globalTimeBeg;
    ma_uint64 globalTimeEnd;
    ma_uint64 startTime;
    ma_uint64 stopTime;
    ma_uint32 timeOffsetBeg;
    ma_uint32 timeOffsetEnd;
    ma_uint32 frameCountIn;
    ma_uint32 frameCountOut;

    /*
    pFramesRead is mandatory. It must be used to determine how many frames were read. It's normal and
    expected that the number of frames read may be different to that requested. Therefore, the caller
    must look at this value to correctly determine how many frames were read.
    */
    MA_ASSERT(pFramesRead != NULL); /* <-- If you've triggered this assert, you're using this function wrong. You *must* use this variable and inspect it after the call returns. */
    if (pFramesRead == NULL) {
        return MA_INVALID_ARGS;
    }

    *pFramesRead = 0;   /* Safety. */

    if (pNodeBase == NULL) {
        return MA_INVALID_ARGS;
    }

    if (outputBusIndex >= ma_node_get_output_bus_count(pNodeBase)) {
        return MA_INVALID_ARGS; /* Invalid output bus index. */
    }

    /* Don't do anything if we're in a stopped state. */
    if (ma_node_get_state_by_time_range(pNode, globalTime, globalTime + frameCount) != ma_node_state_started) {
        return MA_SUCCESS;  /* We're in a stopped state. This is not an error - we just need to not read anything. */
    }


    globalTimeBeg = globalTime;
    globalTimeEnd = globalTime + frameCount;
    startTime = ma_node_get_state_time(pNode, ma_node_state_started);
    stopTime  = ma_node_get_state_time(pNode, ma_node_state_stopped);

    /*
    At this point we know that we are inside our start/stop times. However, we may need to adjust
    our frame count and output pointer to accomodate since we could be straddling the time period
    that this function is getting called for.

    It's possible (and likely) that the start time does not line up with the output buffer. We
    therefore need to offset it by a number of frames to accomodate. The same thing applies for
    the stop time.
    */
    timeOffsetBeg = (globalTimeBeg < startTime) ? (ma_uint32)(globalTimeEnd - startTime) : 0;
    timeOffsetEnd = (globalTimeEnd > stopTime)  ? (ma_uint32)(globalTimeEnd - stopTime)  : 0;

    /* Trim based on the start offset. We need to silence the start of the buffer. */
    if (timeOffsetBeg > 0) {
        ma_silence_pcm_frames(pFramesOut, timeOffsetBeg, ma_format_f32, ma_node_get_output_channels(pNode, outputBusIndex));
        pFramesOut += timeOffsetBeg * ma_node_get_output_channels(pNode, outputBusIndex);
        frameCount -= timeOffsetBeg;
    }

    /* Trim based on the end offset. We don't need to silence the tail section because we'll just have a reduced value written to pFramesRead. */
    if (timeOffsetEnd > 0) {
        frameCount -= timeOffsetEnd;
    }


    /* We run on different paths depending on the bus counts. */
    inputBusCount  = ma_node_get_input_bus_count(pNode);
    outputBusCount = ma_node_get_output_bus_count(pNode);

    /*
    Run a simplified path when there are no inputs and one output. In this case there's nothing to
    actually read and we can go straight to output. This is a very common scenario because the vast
    majority of data source nodes will use this setup so this optimization I think is worthwhile.
    */
    if (inputBusCount == 0 && outputBusCount == 1) {
        /* Fast path. No need to read from input and no need for any caching. */
        frameCountIn  = 0;
        frameCountOut = frameCount;    /* Just read as much as we can. The callback will return what was actually read. */

        ppFramesOut[0] = pFramesOut;
        ma_node_process_pcm_frames_internal(pNode, NULL, &frameCountIn, ppFramesOut, &frameCountOut);
        totalFramesRead = frameCountOut;
    } else {
        /* Slow path. Need to read input data. */
        if ((pNodeBase->vtable->flags & MA_NODE_FLAG_PASSTHROUGH) != 0) {
            /*
            Fast path. We're running a passthrough. We need to read directly into the output buffer, but
            still fire the callback so that event handling and trigger nodes can do their thing. Since
            it's a passthrough there's no need for any kind of caching logic.
            */
            MA_ASSERT(outputBusCount == inputBusCount);
            MA_ASSERT(outputBusCount == 1);
            MA_ASSERT(outputBusIndex == 0);

            /* We just read directly from input bus to output buffer, and then afterwards fire the callback. */
            ppFramesOut[0] = pFramesOut;
            ppFramesIn[0] = ppFramesOut[0];

            result = ma_node_input_bus_read_pcm_frames(pNodeBase, &pNodeBase->pInputBuses[0], ppFramesIn[0], frameCount, &totalFramesRead, globalTime);
            if (result == MA_SUCCESS) {
                /* Even though it's a passthrough, we still need to fire the callback. */
                frameCountIn  = totalFramesRead;
                frameCountOut = totalFramesRead;

                if (totalFramesRead > 0) {
                    ma_node_process_pcm_frames_internal(pNode, (const float**)ppFramesIn, &frameCountIn, ppFramesOut, &frameCountOut);  /* From GCC: expected 'const float **' but argument is of type 'float **'. Shouldn't this be implicit? Excplicit c...
                }

                /*
                A passthrough should never have modified the input and output frame counts. If you're
                triggering these assers you need to fix your processing callback.
                */
                MA_ASSERT(frameCountIn  == totalFramesRead);
                MA_ASSERT(frameCountOut == totalFramesRead);
            }
        } else {
            /* Slow path. Need to do caching. */
            ma_uint32 framesToProcessIn;
            ma_uint32 framesToProcessOut;
            ma_bool32 consumeNullInput = MA_FALSE;

            /*
            We use frameCount as a basis for the number of frames to read since that's what's being
            requested, however we still need to clamp it to whatever can fit in the cache.

            This will also be used as the basis for determining how many input frames to read. This is
            not ideal because it can result in too many input frames being read which introduces latency.
            To solve this, nodes can implement an optional callback called onGetRequiredInputFrameCount
            which is used as hint to miniaudio as to how many input frames it needs to read at a time. This
            callback is completely optional, and if it's not set, miniaudio will assume `frameCount`.

            This function will be called multiple times for each period of time, once for each output node.
            We cannot read from each input node each time this function is called. Instead we need to check
            whether or not this is first output bus to be read from for this time period, and if so, read
            from our input data.

            To determine whether or not we're ready to read data, we check a flag. There will be one flag
            for each output. When the flag is set, it means data has been read previously and that we're
            ready to advance time forward for our input nodes by reading fresh data.
            */
            framesToProcessOut = frameCount;
            if (framesToProcessOut > pNodeBase->cachedDataCapInFramesPerBus) {
                framesToProcessOut = pNodeBase->cachedDataCapInFramesPerBus;
            }

            framesToProcessIn  = frameCount;
            if (pNodeBase->vtable->onGetRequiredInputFrameCount) {
                pNodeBase->vtable->onGetRequiredInputFrameCount(pNode, framesToProcessOut, &framesToProcessIn); /* <-- It does not matter if this fails. */
            }
            if (framesToProcessIn > pNodeBase->cachedDataCapInFramesPerBus) {
                framesToProcessIn = pNodeBase->cachedDataCapInFramesPerBus;
            }


            MA_ASSERT(framesToProcessIn  <= 0xFFFF);
            MA_ASSERT(framesToProcessOut <= 0xFFFF);

            if (ma_node_output_bus_has_read(&pNodeBase->pOutputBuses[outputBusIndex])) {
                /* Getting here means we need to do another round of processing. */
                pNodeBase->cachedFrameCountOut = 0;

                for (;;) {
                    frameCountOut = 0;

                    /*
                    We need to prepare our output frame pointers for processing. In the same iteration we need
                    to mark every output bus as unread so that future calls to this function for different buses
                    for the current time period don't pull in data when they should instead be reading from cache.
                    */
                    for (iOutputBus = 0; iOutputBus < outputBusCount; iOutputBus += 1) {
                        ma_node_output_bus_set_has_read(&pNodeBase->pOutputBuses[iOutputBus], MA_FALSE); /* <-- This is what tells the next calls to this function for other output buses for this time period to read from cache instead of pulling in mo...
                        ppFramesOut[iOutputBus] = ma_node_get_cached_output_ptr(pNode, iOutputBus);
                    }

                    /* We only need to read from input buses if there isn't already some data in the cache. */
                    if (pNodeBase->cachedFrameCountIn == 0) {
                        ma_uint32 maxFramesReadIn = 0;

                        /* Here is where we pull in data from the input buses. This is what will trigger an advance in time. */
                        for (iInputBus = 0; iInputBus < inputBusCount; iInputBus += 1) {
                            ma_uint32 framesRead;

                            /* The first thing to do is get the offset within our bulk allocation to store this input data. */
                            ppFramesIn[iInputBus] = ma_node_get_cached_input_ptr(pNode, iInputBus);

                            /* Once we've determined our destination pointer we can read. Note that we must inspect the number of frames read and fill any leftovers with silence for safety. */
                            result = ma_node_input_bus_read_pcm_frames(pNodeBase, &pNodeBase->pInputBuses[iInputBus], ppFramesIn[iInputBus], framesToProcessIn, &framesRead, globalTime);
                            if (result != MA_SUCCESS) {
                                /* It doesn't really matter if we fail because we'll just fill with silence. */
                                framesRead = 0; /* Just for safety, but I don't think it's really needed. */
                            }

                            /* TODO: Minor optimization opportunity here. If no frames were read and the buffer is already filled with silence, no need to re-silence it. */
                            /* Any leftover frames need to silenced for safety. */
                            if (framesRead < framesToProcessIn) {
                                ma_silence_pcm_frames(ppFramesIn[iInputBus] + (framesRead * ma_node_get_input_channels(pNodeBase, iInputBus)), (framesToProcessIn - framesRead), ma_format_f32, ma_node_get_input_channels(pNodeBase, iInputBus));
                            }

                            maxFramesReadIn = ma_max(maxFramesReadIn, framesRead);
                        }

                        /* This was a fresh load of input data so reset our consumption counter. */
                        pNodeBase->consumedFrameCountIn = 0;

                        /*
                        We don't want to keep processing if there's nothing to process, so set the number of cached
                        input frames to the maximum number we read from each attachment (the lesser will be padded
                        with silence). If we didn't read anything, this will be set to 0 and the entire buffer will
                        have been assigned to silence. This being equal to 0 is an important property for us because
                        it allows us to detect when NULL can be passed into the processing callback for the input
                        buffer for the purpose of continuous processing.
                        */
                        pNodeBase->cachedFrameCountIn = (ma_uint16)maxFramesReadIn;
                    } else {
                        /* We don't need to read anything, but we do need to prepare our input frame pointers. */
                        for (iInputBus = 0; iInputBus < inputBusCount; iInputBus += 1) {
                            ppFramesIn[iInputBus] = ma_node_get_cached_input_ptr(pNode, iInputBus) + (pNodeBase->consumedFrameCountIn * ma_node_get_input_channels(pNodeBase, iInputBus));
                        }
                    }

                    /*
                    At this point we have our input data so now we need to do some processing. Sneaky little
                    optimization here - we can set the pointer to the output buffer for this output bus so
                    that the final copy into the output buffer is done directly by onProcess().
                    */
                    if (pFramesOut != NULL) {
                        ppFramesOut[outputBusIndex] = ma_offset_pcm_frames_ptr_f32(pFramesOut, pNodeBase->cachedFrameCountOut, ma_node_get_output_channels(pNode, outputBusIndex));
                    }


                    /* Give the processing function the entire capacity of the output buffer. */
                    frameCountOut = (framesToProcessOut - pNodeBase->cachedFrameCountOut);

                    /*
                    We need to treat nodes with continuous processing a little differently. For these ones,
                    we always want to fire the callback with the requested number of frames, regardless of
                    pNodeBase->cachedFrameCountIn, which could be 0. Also, we want to check if we can pass
                    in NULL for the input buffer to the callback.
                    */
                    if ((pNodeBase->vtable->flags & MA_NODE_FLAG_CONTINUOUS_PROCESSING) != 0) {
                        /* We're using continuous processing. Make sure we specify the whole frame count at all times. */
                        frameCountIn = framesToProcessIn;    /* Give the processing function as much input data as we've got in the buffer, including any silenced padding from short reads. */

                        if ((pNodeBase->vtable->flags & MA_NODE_FLAG_ALLOW_NULL_INPUT) != 0 && pNodeBase->consumedFrameCountIn == 0 && pNodeBase->cachedFrameCountIn == 0) {
                            consumeNullInput = MA_TRUE;
                        } else {
                            consumeNullInput = MA_FALSE;
                        }

                        /*
                        Since we're using continuous processing we're always passing in a full frame count
                        regardless of how much input data was read. If this is greater than what we read as
                        input, we'll end up with an underflow. We instead need to make sure our cached frame
                        count is set to the number of frames we'll be passing to the data callback. Not
                        doing this will result in an underflow when we "consume" the cached data later on.

                        Note that this check needs to be done after the "consumeNullInput" check above because
                        we use the property of cachedFrameCountIn being 0 to determine whether or not we
                        should be passing in a null pointer to the processing callback for when the node is
                        configured with MA_NODE_FLAG_ALLOW_NULL_INPUT.
                        */
                        if (pNodeBase->cachedFrameCountIn < (ma_uint16)frameCountIn) {
                            pNodeBase->cachedFrameCountIn = (ma_uint16)frameCountIn;
                        }
                    } else {
                        frameCountIn = pNodeBase->cachedFrameCountIn;  /* Give the processing function as much valid input data as we've got. */
                        consumeNullInput = MA_FALSE;
                    }

                    /*
                    Process data slightly differently depending on whether or not we're consuming NULL
                    input (checked just above).
                    */
                    if (consumeNullInput) {
                        ma_node_process_pcm_frames_internal(pNode, NULL, &frameCountIn, ppFramesOut, &frameCountOut);
                    } else {
                        /*
                        We want to skip processing if there's no input data, but we can only do that safely if
                        we know that there is no chance of any output frames being produced. If continuous
                        processing is being used, this won't be a problem because the input frame count will
                        always be non-0. However, if continuous processing is *not* enabled and input and output
                        data is processed at different rates, we still need to process that last input frame
                        because there could be a few excess output frames needing to be produced from cached
                        data. The `MA_NODE_FLAG_DIFFERENT_PROCESSING_RATES` flag is used as the indicator for
                        determining whether or not we need to process the node even when there are no input
                        frames available right now.
                        */
                        if (frameCountIn > 0 || (pNodeBase->vtable->flags & MA_NODE_FLAG_DIFFERENT_PROCESSING_RATES) != 0) {
                            ma_node_process_pcm_frames_internal(pNode, (const float**)ppFramesIn, &frameCountIn, ppFramesOut, &frameCountOut);    /* From GCC: expected 'const float **' but argument is of type 'float **'. Shouldn't this be implicit? E...
                        } else {
                            frameCountOut = 0;  /* No data was processed. */
                        }
                    }

                    /*
                    Thanks to our sneaky optimization above we don't need to do any data copying directly into
                    the output buffer - the onProcess() callback just did that for us. We do, however, need to
                    apply the number of input and output frames that were processed. Note that due to continuous
                    processing above, we need to do explicit checks here. If we just consumed a NULL input
                    buffer it means that no actual input data was processed from the internal buffers and we
                    don't want to be modifying any counters.
                    */
                    if (consumeNullInput == MA_FALSE) {
                        pNodeBase->consumedFrameCountIn += (ma_uint16)frameCountIn;
                        pNodeBase->cachedFrameCountIn   -= (ma_uint16)frameCountIn;
                    }

                    /* The cached output frame count is always equal to what we just read. */
                    pNodeBase->cachedFrameCountOut += (ma_uint16)frameCountOut;

                    /* If we couldn't process any data, we're done. The loop needs to be terminated here or else we'll get stuck in a loop. */
                    if (pNodeBase->cachedFrameCountOut == framesToProcessOut || (frameCountOut == 0 && frameCountIn == 0)) {
                        break;
                    }
                }
            } else {
                /*
                We're not needing to read anything from the input buffer so just read directly from our
                already-processed data.
                */
                if (pFramesOut != NULL) {
                    ma_copy_pcm_frames(pFramesOut, ma_node_get_cached_output_ptr(pNodeBase, outputBusIndex), pNodeBase->cachedFrameCountOut, ma_format_f32, ma_node_get_output_channels(pNodeBase, outputBusIndex));
                }
            }

            /* The number of frames read is always equal to the number of cached output frames. */
            totalFramesRead = pNodeBase->cachedFrameCountOut;

            /* Now that we've read the data, make sure our read flag is set. */
            ma_node_output_bus_set_has_read(&pNodeBase->pOutputBuses[outputBusIndex], MA_TRUE);
        }
    }
    
    /* Apply volume, if necessary. */
    ma_apply_volume_factor_f32(pFramesOut, totalFramesRead * ma_node_get_output_channels(pNodeBase, outputBusIndex), ma_node_output_bus_get_volume(&pNodeBase->pOutputBuses[outputBusIndex]));

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

    ma_data_source_node_config config;

    MA_ZERO_OBJECT(&config);
    config.nodeConfig  = ma_node_config_init();
    config.pDataSource = pDataSource;

    return config;
}


static void ma_data_source_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_data_source_node* pDataSourceNode = (ma_data_source_node*)pNode;
    ma_format format;
    ma_uint32 channels;
    ma_uint32 frameCount;
    ma_uint64 framesRead = 0;

    MA_ASSERT(pDataSourceNode != NULL);
    MA_ASSERT(pDataSourceNode->pDataSource != NULL);
    MA_ASSERT(ma_node_get_input_bus_count(pDataSourceNode)  == 0);
    MA_ASSERT(ma_node_get_output_bus_count(pDataSourceNode) == 1);

    /* We don't want to read from ppFramesIn at all. Instead we read from the data source. */
    (void)ppFramesIn;
    (void)pFrameCountIn;

    frameCount = *pFrameCountOut;

    /* miniaudio should never be calling this with a frame count of zero. */
    MA_ASSERT(frameCount > 0);

    if (ma_data_source_get_data_format(pDataSourceNode->pDataSource, &format, &channels, NULL, NULL, 0) == MA_SUCCESS) { /* <-- Don't care about sample rate here. */
        /* The node graph system requires samples be in floating point format. This is checked in ma_data_source_node_init(). */
        MA_ASSERT(format == ma_format_f32);
        (void)format;   /* Just to silence some static analysis tools. */

        ma_data_source_read_pcm_frames(pDataSourceNode->pDataSource, ppFramesOut[0], frameCount, &framesRead);
    }

    *pFrameCountOut = (ma_uint32)framesRead;
}

static ma_node_vtable g_ma_data_source_node_vtable =
{
    ma_data_source_node_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    0,      /* 0 input buses. */
    1,      /* 1 output bus. */
    0
};

MA_API ma_result ma_data_source_node_init(ma_node_graph* pNodeGraph, const ma_data_source_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source_node* pDataSourceNode)
{
    ma_result result;
    ma_format format;   /* For validating the format, which must be ma_format_f32. */

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

    ma_splitter_node_config config;

    MA_ZERO_OBJECT(&config);
    config.nodeConfig = ma_node_config_init();
    config.channels   = channels;

    return config;
}


static void ma_splitter_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_node_base* pNodeBase = (ma_node_base*)pNode;
    ma_uint32 iOutputBus;
    ma_uint32 channels;

    MA_ASSERT(pNodeBase != NULL);
    MA_ASSERT(ma_node_get_input_bus_count(pNodeBase)  == 1);
    MA_ASSERT(ma_node_get_output_bus_count(pNodeBase) >= 2);

    /* We don't need to consider the input frame count - it'll be the same as the output frame count and we process everything. */
    (void)pFrameCountIn;

    /* NOTE: This assumes the same number of channels for all inputs and outputs. This was checked in ma_splitter_node_init(). */
    channels = ma_node_get_input_channels(pNodeBase, 0);

    /* Splitting is just copying the first input bus and copying it over to each output bus. */
    for (iOutputBus = 0; iOutputBus < ma_node_get_output_bus_count(pNodeBase); iOutputBus += 1) {
        ma_copy_pcm_frames(ppFramesOut[iOutputBus], ppFramesIn[0], *pFrameCountOut, ma_format_f32, channels);
    }
}

static ma_node_vtable g_ma_splitter_node_vtable =
{
    ma_splitter_node_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    1,      /* 1 input bus. */
    2,      /* 2 output buses. */
    0
};

MA_API ma_result ma_splitter_node_init(ma_node_graph* pNodeGraph, const ma_splitter_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_splitter_node* pSplitterNode)
{
    ma_result result;
    ma_node_config baseConfig;

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

MA_API ma_biquad_node_config ma_biquad_node_config_init(ma_uint32 channels, float b0, float b1, float b2, float a0, float a1, float a2)
{
    ma_biquad_node_config config;

    config.nodeConfig = ma_node_config_init();
    config.biquad = ma_biquad_config_init(ma_format_f32, channels, b0, b1, b2, a0, a1, a2);

    return config;
}

static void ma_biquad_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_biquad_node* pLPFNode = (ma_biquad_node*)pNode;

    MA_ASSERT(pNode != NULL);
    (void)pFrameCountIn;

    ma_biquad_process_pcm_frames(&pLPFNode->biquad, ppFramesOut[0], ppFramesIn[0], *pFrameCountOut);
}

static ma_node_vtable g_ma_biquad_node_vtable =
{
    ma_biquad_node_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    1,      /* One input. */
    1,      /* One output. */
    0       /* Default flags. */
};

MA_API ma_result ma_biquad_node_init(ma_node_graph* pNodeGraph, const ma_biquad_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_biquad_node* pNode)
{
    ma_result result;
    ma_node_config baseNodeConfig;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

MA_API ma_lpf_node_config ma_lpf_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, ma_uint32 order)
{
    ma_lpf_node_config config;

    config.nodeConfig = ma_node_config_init();
    config.lpf = ma_lpf_config_init(ma_format_f32, channels, sampleRate, cutoffFrequency, order);

    return config;
}

static void ma_lpf_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_lpf_node* pLPFNode = (ma_lpf_node*)pNode;

    MA_ASSERT(pNode != NULL);
    (void)pFrameCountIn;

    ma_lpf_process_pcm_frames(&pLPFNode->lpf, ppFramesOut[0], ppFramesIn[0], *pFrameCountOut);
}

static ma_node_vtable g_ma_lpf_node_vtable =
{
    ma_lpf_node_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    1,      /* One input. */
    1,      /* One output. */
    0       /* Default flags. */
};

MA_API ma_result ma_lpf_node_init(ma_node_graph* pNodeGraph, const ma_lpf_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_lpf_node* pNode)
{
    ma_result result;
    ma_node_config baseNodeConfig;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

MA_API ma_hpf_node_config ma_hpf_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, ma_uint32 order)
{
    ma_hpf_node_config config;

    config.nodeConfig = ma_node_config_init();
    config.hpf = ma_hpf_config_init(ma_format_f32, channels, sampleRate, cutoffFrequency, order);

    return config;
}

static void ma_hpf_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_hpf_node* pHPFNode = (ma_hpf_node*)pNode;

    MA_ASSERT(pNode != NULL);
    (void)pFrameCountIn;

    ma_hpf_process_pcm_frames(&pHPFNode->hpf, ppFramesOut[0], ppFramesIn[0], *pFrameCountOut);
}

static ma_node_vtable g_ma_hpf_node_vtable =
{
    ma_hpf_node_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    1,      /* One input. */
    1,      /* One output. */
    0       /* Default flags. */
};

MA_API ma_result ma_hpf_node_init(ma_node_graph* pNodeGraph, const ma_hpf_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_hpf_node* pNode)
{
    ma_result result;
    ma_node_config baseNodeConfig;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

MA_API ma_bpf_node_config ma_bpf_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, ma_uint32 order)
{
    ma_bpf_node_config config;

    config.nodeConfig = ma_node_config_init();
    config.bpf = ma_bpf_config_init(ma_format_f32, channels, sampleRate, cutoffFrequency, order);

    return config;
}

static void ma_bpf_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_bpf_node* pBPFNode = (ma_bpf_node*)pNode;

    MA_ASSERT(pNode != NULL);
    (void)pFrameCountIn;

    ma_bpf_process_pcm_frames(&pBPFNode->bpf, ppFramesOut[0], ppFramesIn[0], *pFrameCountOut);
}

static ma_node_vtable g_ma_bpf_node_vtable =
{
    ma_bpf_node_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    1,      /* One input. */
    1,      /* One output. */
    0       /* Default flags. */
};

MA_API ma_result ma_bpf_node_init(ma_node_graph* pNodeGraph, const ma_bpf_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_bpf_node* pNode)
{
    ma_result result;
    ma_node_config baseNodeConfig;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

MA_API ma_notch_node_config ma_notch_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double q, double frequency)
{
    ma_notch_node_config config;

    config.nodeConfig = ma_node_config_init();
    config.notch = ma_notch2_config_init(ma_format_f32, channels, sampleRate, q, frequency);

    return config;
}

static void ma_notch_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_notch_node* pBPFNode = (ma_notch_node*)pNode;

    MA_ASSERT(pNode != NULL);
    (void)pFrameCountIn;

    ma_notch2_process_pcm_frames(&pBPFNode->notch, ppFramesOut[0], ppFramesIn[0], *pFrameCountOut);
}

static ma_node_vtable g_ma_notch_node_vtable =
{
    ma_notch_node_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    1,      /* One input. */
    1,      /* One output. */
    0       /* Default flags. */
};

MA_API ma_result ma_notch_node_init(ma_node_graph* pNodeGraph, const ma_notch_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_notch_node* pNode)
{
    ma_result result;
    ma_node_config baseNodeConfig;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

MA_API ma_peak_node_config ma_peak_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double q, double frequency)
{
    ma_peak_node_config config;

    config.nodeConfig = ma_node_config_init();
    config.peak = ma_peak2_config_init(ma_format_f32, channels, sampleRate, gainDB, q, frequency);

    return config;
}

static void ma_peak_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_peak_node* pBPFNode = (ma_peak_node*)pNode;

    MA_ASSERT(pNode != NULL);
    (void)pFrameCountIn;

    ma_peak2_process_pcm_frames(&pBPFNode->peak, ppFramesOut[0], ppFramesIn[0], *pFrameCountOut);
}

static ma_node_vtable g_ma_peak_node_vtable =
{
    ma_peak_node_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    1,      /* One input. */
    1,      /* One output. */
    0       /* Default flags. */
};

MA_API ma_result ma_peak_node_init(ma_node_graph* pNodeGraph, const ma_peak_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_peak_node* pNode)
{
    ma_result result;
    ma_node_config baseNodeConfig;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

MA_API ma_loshelf_node_config ma_loshelf_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double q, double frequency)
{
    ma_loshelf_node_config config;

    config.nodeConfig = ma_node_config_init();
    config.loshelf = ma_loshelf2_config_init(ma_format_f32, channels, sampleRate, gainDB, q, frequency);

    return config;
}

static void ma_loshelf_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_loshelf_node* pBPFNode = (ma_loshelf_node*)pNode;

    MA_ASSERT(pNode != NULL);
    (void)pFrameCountIn;

    ma_loshelf2_process_pcm_frames(&pBPFNode->loshelf, ppFramesOut[0], ppFramesIn[0], *pFrameCountOut);
}

static ma_node_vtable g_ma_loshelf_node_vtable =
{
    ma_loshelf_node_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    1,      /* One input. */
    1,      /* One output. */
    0       /* Default flags. */
};

MA_API ma_result ma_loshelf_node_init(ma_node_graph* pNodeGraph, const ma_loshelf_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_loshelf_node* pNode)
{
    ma_result result;
    ma_node_config baseNodeConfig;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

MA_API ma_hishelf_node_config ma_hishelf_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double q, double frequency)
{
    ma_hishelf_node_config config;

    config.nodeConfig = ma_node_config_init();
    config.hishelf = ma_hishelf2_config_init(ma_format_f32, channels, sampleRate, gainDB, q, frequency);

    return config;
}

static void ma_hishelf_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_hishelf_node* pBPFNode = (ma_hishelf_node*)pNode;

    MA_ASSERT(pNode != NULL);
    (void)pFrameCountIn;

    ma_hishelf2_process_pcm_frames(&pBPFNode->hishelf, ppFramesOut[0], ppFramesIn[0], *pFrameCountOut);
}

static ma_node_vtable g_ma_hishelf_node_vtable =
{
    ma_hishelf_node_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    1,      /* One input. */
    1,      /* One output. */
    0       /* Default flags. */
};

MA_API ma_result ma_hishelf_node_init(ma_node_graph* pNodeGraph, const ma_hishelf_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_hishelf_node* pNode)
{
    ma_result result;
    ma_node_config baseNodeConfig;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

{
    ma_delay_node_config config;

    config.nodeConfig = ma_node_config_init();
    config.delay = ma_delay_config_init(channels, sampleRate, delayInFrames, decay);

    return config;
}


static void ma_delay_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_delay_node* pDelayNode = (ma_delay_node*)pNode;

    (void)pFrameCountIn;

    ma_delay_process_pcm_frames(&pDelayNode->delay, ppFramesOut[0], ppFramesIn[0], *pFrameCountOut);
}

static ma_node_vtable g_ma_delay_node_vtable =
{
    ma_delay_node_process_pcm_frames,
    NULL,
    1,  /* 1 input channels. */
    1,  /* 1 output channel. */
    MA_NODE_FLAG_CONTINUOUS_PROCESSING  /* Delay requires continuous processing to ensure the tail get's processed. */
};

MA_API ma_result ma_delay_node_init(ma_node_graph* pNodeGraph, const ma_delay_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_delay_node* pDelayNode)
{
    ma_result result;
    ma_node_config baseConfig;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    return !c89atomic_load_explicit_32(&pEngineNode->isPitchDisabled, c89atomic_memory_order_acquire);
}

static ma_bool32 ma_engine_node_is_spatialization_enabled(const ma_engine_node* pEngineNode)
{
    MA_ASSERT(pEngineNode != NULL);

    return !c89atomic_load_explicit_32(&pEngineNode->isSpatializationDisabled, c89atomic_memory_order_acquire);
}

static ma_uint64 ma_engine_node_get_required_input_frame_count(const ma_engine_node* pEngineNode, ma_uint64 outputFrameCount)
{
    ma_uint64 inputFrameCount = 0;

    if (ma_engine_node_is_pitching_enabled(pEngineNode)) {
        ma_result result = ma_linear_resampler_get_required_input_frame_count(&pEngineNode->resampler, outputFrameCount, &inputFrameCount);
        if (result != MA_SUCCESS) {
            inputFrameCount = 0;
        }
    } else {
        inputFrameCount = outputFrameCount;    /* No resampling, so 1:1. */
    }

    return inputFrameCount;
}

static void ma_engine_node_process_pcm_frames__general(ma_engine_node* pEngineNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    ma_uint32 frameCountIn;
    ma_uint32 frameCountOut;
    ma_uint32 totalFramesProcessedIn;
    ma_uint32 totalFramesProcessedOut;
    ma_uint32 channelsIn;
    ma_uint32 channelsOut;
    ma_bool32 isPitchingEnabled;
    ma_bool32 isFadingEnabled;
    ma_bool32 isSpatializationEnabled;
    ma_bool32 isPanningEnabled;

    frameCountIn  = *pFrameCountIn;
    frameCountOut = *pFrameCountOut;

    channelsIn  = ma_spatializer_get_input_channels(&pEngineNode->spatializer);
    channelsOut = ma_spatializer_get_output_channels(&pEngineNode->spatializer);

    totalFramesProcessedIn  = 0;
    totalFramesProcessedOut = 0;

    isPitchingEnabled       = ma_engine_node_is_pitching_enabled(pEngineNode);
    isFadingEnabled         = pEngineNode->fader.volumeBeg != 1 || pEngineNode->fader.volumeEnd != 1;
    isSpatializationEnabled = ma_engine_node_is_spatialization_enabled(pEngineNode);
    isPanningEnabled        = pEngineNode->panner.pan != 0 && channelsOut != 1;

    /* Keep going while we've still got data available for processing. */
    while (totalFramesProcessedOut < frameCountOut) {
        /*
        We need to process in a specific order. We always do resampling first because it's likely
        we're going to be increasing the channel count after spatialization. Also, I want to do
        fading based on the output sample rate.

        We'll first read into a buffer from the resampler. Then we'll do all processing that
        operates on the on the input channel count. We'll then get the spatializer to output to
        the output buffer and then do all effects from that point directly in the output buffer
        in-place.

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        when the pitch is 1, we'll get a glitch when we move away from 1, back to 1, and then
        away from 1 again. We'll want to implement any pitch=1 optimizations in the resampler
        itself.

        There's a small optimization here that we'll utilize since it might be a fairly common
        case. When the input and output channel counts are the same, we'll read straight into the
        output buffer from the resampler and do everything in-place.
        */
        const float* pRunningFramesIn;
        float* pRunningFramesOut;
        float* pWorkingBuffer;   /* This is the buffer that we'll be processing frames in. This is in input channels. */
        float temp[MA_DATA_CONVERTER_STACK_BUFFER_SIZE / sizeof(float)];
        ma_uint32 tempCapInFrames = ma_countof(temp) / channelsIn;
        ma_uint32 framesAvailableIn;
        ma_uint32 framesAvailableOut;
        ma_uint32 framesJustProcessedIn;
        ma_uint32 framesJustProcessedOut;
        ma_bool32 isWorkingBufferValid = MA_FALSE;

        framesAvailableIn  = frameCountIn  - totalFramesProcessedIn;
        framesAvailableOut = frameCountOut - totalFramesProcessedOut;

        pRunningFramesIn  = ma_offset_pcm_frames_const_ptr_f32(ppFramesIn[0], totalFramesProcessedIn, channelsIn);
        pRunningFramesOut = ma_offset_pcm_frames_ptr_f32(ppFramesOut[0], totalFramesProcessedOut, channelsOut);

        if (channelsIn == channelsOut) {
            /* Fast path. Channel counts are the same. No need for an intermediary input buffer. */
            pWorkingBuffer = pRunningFramesOut;
        } else {
            /* Slow path. Channel counts are different. Need to use an intermediary input buffer. */
            pWorkingBuffer = temp;
            if (framesAvailableOut > tempCapInFrames) {
                framesAvailableOut = tempCapInFrames;
            }
        }

        /* First is resampler. */
        if (isPitchingEnabled) {
            ma_uint64 resampleFrameCountIn  = framesAvailableIn;
            ma_uint64 resampleFrameCountOut = framesAvailableOut;

            ma_linear_resampler_process_pcm_frames(&pEngineNode->resampler, pRunningFramesIn, &resampleFrameCountIn, pWorkingBuffer, &resampleFrameCountOut);
            isWorkingBufferValid = MA_TRUE;

            framesJustProcessedIn  = (ma_uint32)resampleFrameCountIn;
            framesJustProcessedOut = (ma_uint32)resampleFrameCountOut;
        } else {
            framesJustProcessedIn  = ma_min(framesAvailableIn, framesAvailableOut);
            framesJustProcessedOut = framesJustProcessedIn; /* When no resampling is being performed, the number of output frames is the same as input frames. */
        }

        /* Fading. */
        if (isFadingEnabled) {
            if (isWorkingBufferValid) {
                ma_fader_process_pcm_frames(&pEngineNode->fader, pWorkingBuffer, pWorkingBuffer, framesJustProcessedOut);   /* In-place processing. */
            } else {
                ma_fader_process_pcm_frames(&pEngineNode->fader, pWorkingBuffer, pRunningFramesIn, framesJustProcessedOut);
                isWorkingBufferValid = MA_TRUE;
            }
        }

        /*
        If at this point we still haven't actually done anything with the working buffer we need
        to just read straight from the input buffer.
        */
        if (isWorkingBufferValid == MA_FALSE) {
            pWorkingBuffer = (float*)pRunningFramesIn;  /* Naughty const cast, but it's safe at this point because we won't ever be writing to it from this point out. */

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            /*
            When determining the listener to use, we first check to see if the sound is pinned to a
            specific listener. If so, we use that. Otherwise we just use the closest listener.
            */
            if (pEngineNode->pinnedListenerIndex != MA_LISTENER_INDEX_CLOSEST && pEngineNode->pinnedListenerIndex < ma_engine_get_listener_count(pEngineNode->pEngine)) {
                iListener = pEngineNode->pinnedListenerIndex;
            } else {
                iListener = ma_engine_find_closest_listener(pEngineNode->pEngine, pEngineNode->spatializer.position.x, pEngineNode->spatializer.position.y, pEngineNode->spatializer.position.z);
            }

            ma_spatializer_process_pcm_frames(&pEngineNode->spatializer, &pEngineNode->pEngine->listeners[iListener], pRunningFramesOut, pWorkingBuffer, framesJustProcessedOut);
        } else {
            /* No spatialization, but we still need to do channel conversion. */
            if (channelsIn == channelsOut) {
                /* No channel conversion required. Just copy straight to the output buffer. */
                ma_copy_pcm_frames(pRunningFramesOut, pWorkingBuffer, framesJustProcessedOut, ma_format_f32, channelsOut);
            } else {
                /* Channel conversion required. TODO: Add support for channel maps here. */
                ma_channel_map_apply_f32(pRunningFramesOut, NULL, channelsOut, pWorkingBuffer, NULL, channelsIn, framesJustProcessedOut, ma_channel_mix_mode_simple, pEngineNode->pEngine->monoExpansionMode);
            }
        }

        /* At this point we can guarantee that the output buffer contains valid data. We can process everything in place now. */

        /* Panning. */
        if (isPanningEnabled) {
            ma_panner_process_pcm_frames(&pEngineNode->panner, pRunningFramesOut, pRunningFramesOut, framesJustProcessedOut);   /* In-place processing. */
        }

        /* We're done for this chunk. */
        totalFramesProcessedIn  += framesJustProcessedIn;
        totalFramesProcessedOut += framesJustProcessedOut;

        /* If we didn't process any output frames this iteration it means we've either run out of input data, or run out of room in the output buffer. */
        if (framesJustProcessedOut == 0) {
            break;
        }
    }

    /* At this point we're done processing. */
    *pFrameCountIn  = totalFramesProcessedIn;
    *pFrameCountOut = totalFramesProcessedOut;
}

static void ma_engine_node_process_pcm_frames__sound(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    /* For sounds, we need to first read from the data source. Then we need to apply the engine effects (pan, pitch, fades, etc.). */
    ma_result result = MA_SUCCESS;
    ma_sound* pSound = (ma_sound*)pNode;
    ma_uint32 frameCount = *pFrameCountOut;
    ma_uint32 totalFramesRead = 0;
    ma_format dataSourceFormat;
    ma_uint32 dataSourceChannels;
    ma_uint8 temp[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
    ma_uint32 tempCapInFrames;
    ma_uint64 seekTarget;

    /* This is a data source node which means no input buses. */
    (void)ppFramesIn;
    (void)pFrameCountIn;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    /* If we're marked at the end we need to stop the sound and do nothing. */
    if (ma_sound_at_end(pSound)) {
        ma_sound_stop(pSound);
        *pFrameCountOut = 0;
        return;
    }

    /* If we're seeking, do so now before reading. */
    seekTarget = c89atomic_load_64(&pSound->seekTarget);
    if (seekTarget != MA_SEEK_TARGET_NONE) {
        ma_data_source_seek_to_pcm_frame(pSound->pDataSource, seekTarget);

        /* Any time-dependant effects need to have their times updated. */
        ma_node_set_time(pSound, seekTarget);

        c89atomic_exchange_64(&pSound->seekTarget, MA_SEEK_TARGET_NONE);
    }

    /*
    We want to update the pitch once. For sounds, this can be either at the start or at the end. If
    we don't force this to only ever be updating once, we could end up in a situation where
    retrieving the required input frame count ends up being different to what we actually retrieve.
    What could happen is that the required input frame count is calculated, the pitch is update,
    and then this processing function is called resulting in a different number of input frames
    being processed. Do not call this in ma_engine_node_process_pcm_frames__general() or else
    you'll hit the aforementioned bug.
    */
    ma_engine_node_update_pitch_if_required(&pSound->engineNode);

    /*
    For the convenience of the caller, we're doing to allow data sources to use non-floating-point formats and channel counts that differ
    from the main engine.
    */
    result = ma_data_source_get_data_format(pSound->pDataSource, &dataSourceFormat, &dataSourceChannels, NULL, NULL, 0);
    if (result == MA_SUCCESS) {
        tempCapInFrames = sizeof(temp) / ma_get_bytes_per_frame(dataSourceFormat, dataSourceChannels);

        /* Keep reading until we've read as much as was requested or we reach the end of the data source. */
        while (totalFramesRead < frameCount) {
            ma_uint32 framesRemaining = frameCount - totalFramesRead;
            ma_uint32 framesToRead;
            ma_uint64 framesJustRead;
            ma_uint32 frameCountIn;
            ma_uint32 frameCountOut;
            const float* pRunningFramesIn;
            float* pRunningFramesOut;

            /*
            The first thing we need to do is read into the temporary buffer. We can calculate exactly
            how many input frames we'll need after resampling.
            */
            framesToRead = (ma_uint32)ma_engine_node_get_required_input_frame_count(&pSound->engineNode, framesRemaining);
            if (framesToRead > tempCapInFrames) {
                framesToRead = tempCapInFrames;
            }

            result = ma_data_source_read_pcm_frames(pSound->pDataSource, temp, framesToRead, &framesJustRead);

            /* If we reached the end of the sound we'll want to mark it as at the end and stop it. This should never be returned for looping sounds. */
            if (result == MA_AT_END) {
                c89atomic_exchange_32(&pSound->atEnd, MA_TRUE); /* This will be set to false in ma_sound_start(). */
            }

            pRunningFramesOut = ma_offset_pcm_frames_ptr_f32(ppFramesOut[0], totalFramesRead, ma_engine_get_channels(ma_sound_get_engine(pSound)));

            frameCountIn = (ma_uint32)framesJustRead;
            frameCountOut = framesRemaining;

            /* Convert if necessary. */
            if (dataSourceFormat == ma_format_f32) {
                /* Fast path. No data conversion necessary. */
                pRunningFramesIn = (float*)temp;
                ma_engine_node_process_pcm_frames__general(&pSound->engineNode, &pRunningFramesIn, &frameCountIn, &pRunningFramesOut, &frameCountOut);
            } else {
                /* Slow path. Need to do sample format conversion to f32. If we give the f32 buffer the same count as the first temp buffer, we're guaranteed it'll be large enough. */
                float tempf32[MA_DATA_CONVERTER_STACK_BUFFER_SIZE]; /* Do not do `MA_DATA_CONVERTER_STACK_BUFFER_SIZE/sizeof(float)` here like we've done in other places. */
                ma_convert_pcm_frames_format(tempf32, ma_format_f32, temp, dataSourceFormat, framesJustRead, dataSourceChannels, ma_dither_mode_none);

                /* Now that we have our samples in f32 format we can process like normal. */
                pRunningFramesIn = tempf32;
                ma_engine_node_process_pcm_frames__general(&pSound->engineNode, &pRunningFramesIn, &frameCountIn, &pRunningFramesOut, &frameCountOut);
            }

            /* We should have processed all of our input frames since we calculated the required number of input frames at the top. */
            MA_ASSERT(frameCountIn == framesJustRead);
            totalFramesRead += (ma_uint32)frameCountOut;   /* Safe cast. */

            if (result != MA_SUCCESS || ma_sound_at_end(pSound)) {
                break;  /* Might have reached the end. */
            }
        }
    }

    *pFrameCountOut = totalFramesRead;
}

static void ma_engine_node_process_pcm_frames__group(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
{
    /*
    Make sure the pitch is updated before trying to read anything. It's important that this is done
    only once and not in ma_engine_node_process_pcm_frames__general(). The reason for this is that
    ma_engine_node_process_pcm_frames__general() will call ma_engine_node_get_required_input_frame_count(),
    and if another thread modifies the pitch just after that call it can result in a glitch due to
    the input rate changing.
    */
    ma_engine_node_update_pitch_if_required((ma_engine_node*)pNode);

    /* For groups, the input data has already been read and we just need to apply the effect. */
    ma_engine_node_process_pcm_frames__general((ma_engine_node*)pNode, ppFramesIn, pFrameCountIn, ppFramesOut, pFrameCountOut);
}

static ma_result ma_engine_node_get_required_input_frame_count__group(ma_node* pNode, ma_uint32 outputFrameCount, ma_uint32* pInputFrameCount)
{
    ma_uint64 inputFrameCount;

    MA_ASSERT(pInputFrameCount != NULL);

    /* Our pitch will affect this calculation. We need to update it. */
    ma_engine_node_update_pitch_if_required((ma_engine_node*)pNode);

    inputFrameCount = ma_engine_node_get_required_input_frame_count((ma_engine_node*)pNode, outputFrameCount);
    if (inputFrameCount > 0xFFFFFFFF) {
        inputFrameCount = 0xFFFFFFFF;    /* Will never happen because miniaudio will only ever process in relatively small chunks. */
    }

    *pInputFrameCount = (ma_uint32)inputFrameCount;

    return MA_SUCCESS;
}


static ma_node_vtable g_ma_engine_node_vtable__sound =
{
    ma_engine_node_process_pcm_frames__sound,
    NULL,   /* onGetRequiredInputFrameCount */
    0,      /* Sounds are data source nodes which means they have zero inputs (their input is drawn from the data source itself). */
    1,      /* Sounds have one output bus. */
    0       /* Default flags. */
};

static ma_node_vtable g_ma_engine_node_vtable__group =
{
    ma_engine_node_process_pcm_frames__group,
    ma_engine_node_get_required_input_frame_count__group,
    1,      /* Groups have one input bus. */
    1,      /* Groups have one output bus. */
    MA_NODE_FLAG_DIFFERENT_PROCESSING_RATES /* The engine node does resampling so should let miniaudio know about it. */
};



static ma_node_config ma_engine_node_base_node_config_init(const ma_engine_node_config* pConfig)
{
    ma_node_config baseNodeConfig;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN


    MA_ZERO_OBJECT(&config);
    config.listenerCount     = 1;   /* Always want at least one listener. */
    config.monoExpansionMode = ma_mono_expansion_mode_default;

    return config;
}


#if !defined(MA_NO_DEVICE_IO)
static void ma_engine_data_callback_internal(ma_device* pDevice, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount)
{
    ma_engine* pEngine = (ma_engine*)pDevice->pUserData;

    (void)pFramesIn;

    /*
    Experiment: Try processing a resource manager job if we're on the Emscripten build.

    This serves two purposes:

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    #if !defined(MA_NO_RESOURCE_MANAGER) && defined(MA_EMSCRIPTEN)
    {
        if (pEngine->pResourceManager != NULL) {
            if ((pEngine->pResourceManager->config.flags & MA_RESOURCE_MANAGER_FLAG_NO_THREADING) != 0) {
                ma_resource_manager_process_next_job(pEngine->pResourceManager);
            }
        }
    }
    #endif

    ma_engine_read_pcm_frames(pEngine, pFramesOut, frameCount, NULL);
}
#endif

MA_API ma_result ma_engine_init(const ma_engine_config* pConfig, ma_engine* pEngine)
{
    ma_result result;
    ma_node_graph_config nodeGraphConfig;
    ma_engine_config engineConfig;
    ma_spatializer_listener_config listenerConfig;
    ma_uint32 iListener;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN


            deviceConfig = ma_device_config_init(ma_device_type_playback);
            deviceConfig.playback.pDeviceID        = engineConfig.pPlaybackDeviceID;
            deviceConfig.playback.format           = ma_format_f32;
            deviceConfig.playback.channels         = engineConfig.channels;
            deviceConfig.sampleRate                = engineConfig.sampleRate;
            deviceConfig.dataCallback              = ma_engine_data_callback_internal;
            deviceConfig.pUserData                 = pEngine;
            deviceConfig.periodSizeInFrames        = engineConfig.periodSizeInFrames;
            deviceConfig.periodSizeInMilliseconds  = engineConfig.periodSizeInMilliseconds;
            deviceConfig.noPreSilencedOutputBuffer = MA_TRUE;    /* We'll always be outputting to every frame in the callback so there's no need for a pre-silenced buffer. */
            deviceConfig.noClip                    = MA_TRUE;    /* The engine will do clipping itself. */

            if (engineConfig.pContext == NULL) {
                ma_context_config contextConfig = ma_context_config_init();
                contextConfig.allocationCallbacks = pEngine->allocationCallbacks;
                contextConfig.pLog = engineConfig.pLog;

                /* If the engine config does not specify a log, use the resource manager's if we have one. */
                #ifndef MA_NO_RESOURCE_MANAGER
                {

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN


    /* Uninitialize the resource manager last to ensure we don't have a thread still trying to access it. */
#ifndef MA_NO_RESOURCE_MANAGER
    if (pEngine->ownsResourceManager) {
        ma_resource_manager_uninit(pEngine->pResourceManager);
        ma_free(pEngine->pResourceManager, &pEngine->allocationCallbacks);
    }
#endif
}

MA_API ma_result ma_engine_read_pcm_frames(ma_engine* pEngine, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    return ma_node_graph_read_pcm_frames(&pEngine->nodeGraph, pFramesOut, frameCount, pFramesRead);
}

MA_API ma_node_graph* ma_engine_get_node_graph(ma_engine* pEngine)
{
    if (pEngine == NULL) {
        return NULL;
    }

    return &pEngine->nodeGraph;
}

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    }

    if (result != MA_SUCCESS) {
        ma_engine_node_uninit(&pSound->engineNode, &pEngine->allocationCallbacks);
        return result;
    }


    /* Apply initial range and looping state to the data source if applicable. */
    if (pConfig->rangeBegInPCMFrames != 0 || pConfig->rangeEndInPCMFrames != ~((ma_uint64)0)) {
        ma_data_source_set_range_in_pcm_frames(ma_sound_get_data_source(pSound), pConfig->rangeBegInPCMFrames, pConfig->rangeEndInPCMFrames);
    }

    if (pConfig->loopPointBegInPCMFrames != 0 || pConfig->loopPointEndInPCMFrames != ~((ma_uint64)0)) {
        ma_data_source_set_range_in_pcm_frames(ma_sound_get_data_source(pSound), pConfig->loopPointBegInPCMFrames, pConfig->loopPointEndInPCMFrames);
    }

    ma_sound_set_looping(pSound, pConfig->isLooping);

    return MA_SUCCESS;
}

#ifndef MA_NO_RESOURCE_MANAGER
MA_API ma_result ma_sound_init_from_file_internal(ma_engine* pEngine, const ma_sound_config* pConfig, ma_sound* pSound)
{

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        return MA_INVALID_ARGS;
    }

    /* If the sound is already playing, do nothing. */
    if (ma_sound_is_playing(pSound)) {
        return MA_SUCCESS;
    }

    /* If the sound is at the end it means we want to start from the start again. */
    if (ma_sound_at_end(pSound)) {
        ma_result result = ma_data_source_seek_to_pcm_frame(pSound->pDataSource, 0);
        if (result != MA_SUCCESS && result != MA_NOT_IMPLEMENTED) {
            return result;  /* Failed to seek back to the start. */
        }

        /* Make sure we clear the end indicator. */
        c89atomic_exchange_32(&pSound->atEnd, MA_FALSE);
    }

    /* Make sure the sound is started. If there's a start delay, the sound won't actually start until the start time is reached. */
    ma_node_set_state(pSound, ma_node_state_started);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

MA_API float ma_sound_get_directional_attenuation_factor(const ma_sound* pSound)
{
    if (pSound == NULL) {
        return 1;
    }

    return ma_spatializer_get_directional_attenuation_factor(&pSound->engineNode.spatializer);
}


MA_API void ma_sound_set_fade_in_pcm_frames(ma_sound* pSound, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInFrames)
{
    if (pSound == NULL) {
        return;
    }

    ma_fader_set_fade(&pSound->engineNode.fader, volumeBeg, volumeEnd, fadeLengthInFrames);
}

MA_API void ma_sound_set_fade_in_milliseconds(ma_sound* pSound, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInMilliseconds)
{
    if (pSound == NULL) {
        return;
    }

    ma_sound_set_fade_in_pcm_frames(pSound, volumeBeg, volumeEnd, (fadeLengthInMilliseconds * pSound->engineNode.fader.config.sampleRate) / 1000);
}

MA_API float ma_sound_get_current_fade_volume(ma_sound* pSound)
{
    if (pSound == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_fader_get_current_volume(&pSound->engineNode.fader);
}

MA_API void ma_sound_set_start_time_in_pcm_frames(ma_sound* pSound, ma_uint64 absoluteGlobalTimeInFrames)
{
    if (pSound == NULL) {
        return;
    }

    ma_node_set_state_time(pSound, ma_node_state_started, absoluteGlobalTimeInFrames);
}

MA_API void ma_sound_set_start_time_in_milliseconds(ma_sound* pSound, ma_uint64 absoluteGlobalTimeInMilliseconds)
{
    if (pSound == NULL) {
        return;
    }

    ma_sound_set_start_time_in_pcm_frames(pSound, absoluteGlobalTimeInMilliseconds * ma_engine_get_sample_rate(ma_sound_get_engine(pSound)) / 1000);
}

MA_API void ma_sound_set_stop_time_in_pcm_frames(ma_sound* pSound, ma_uint64 absoluteGlobalTimeInFrames)
{
    if (pSound == NULL) {
        return;
    }

    ma_node_set_state_time(pSound, ma_node_state_stopped, absoluteGlobalTimeInFrames);
}

MA_API void ma_sound_set_stop_time_in_milliseconds(ma_sound* pSound, ma_uint64 absoluteGlobalTimeInMilliseconds)
{
    if (pSound == NULL) {
        return;
    }

    ma_sound_set_stop_time_in_pcm_frames(pSound, absoluteGlobalTimeInMilliseconds * ma_engine_get_sample_rate(ma_sound_get_engine(pSound)) / 1000);
}

MA_API ma_bool32 ma_sound_is_playing(const ma_sound* pSound)
{
    if (pSound == NULL) {
        return MA_FALSE;
    }

    return ma_node_get_state_by_time(pSound, ma_engine_get_time(ma_sound_get_engine(pSound))) == ma_node_state_started;
}

MA_API ma_uint64 ma_sound_get_time_in_pcm_frames(const ma_sound* pSound)
{
    if (pSound == NULL) {
        return 0;
    }

    return ma_node_get_time(pSound);
}

MA_API void ma_sound_set_looping(ma_sound* pSound, ma_bool32 isLooping)
{

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    }

    /* There is no notion of an end of a sound if it's not backed by a data source. */
    if (pSound->pDataSource == NULL) {
        return MA_FALSE;
    }

    return c89atomic_load_32(&pSound->atEnd);
}

MA_API ma_result ma_sound_seek_to_pcm_frame(ma_sound* pSound, ma_uint64 frameIndex)
{
    if (pSound == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Seeking is only valid for sounds that are backed by a data source. */
    if (pSound->pDataSource == NULL) {
        return MA_INVALID_OPERATION;
    }

    /* We can't be seeking while reading at the same time. We just set the seek target and get the mixing thread to do the actual seek. */
    c89atomic_exchange_64(&pSound->seekTarget, frameIndex);

    return MA_SUCCESS;
}

MA_API ma_result ma_sound_get_data_format(ma_sound* pSound, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
    if (pSound == NULL) {
        return MA_INVALID_ARGS;
    }

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        if (pChannelMap != NULL) {
            ma_channel_map_init_standard(ma_standard_channel_map_default, pChannelMap, channelMapCap, channels);
        }

        return MA_SUCCESS;
    } else {
        return ma_data_source_get_data_format(pSound->pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
    }
}

MA_API ma_result ma_sound_get_cursor_in_pcm_frames(ma_sound* pSound, ma_uint64* pCursor)
{
    if (pSound == NULL) {
        return MA_INVALID_ARGS;
    }

    /* The notion of a cursor is only valid for sounds that are backed by a data source. */
    if (pSound->pDataSource == NULL) {
        return MA_INVALID_OPERATION;
    }

    return ma_data_source_get_cursor_in_pcm_frames(pSound->pDataSource, pCursor);
}

MA_API ma_result ma_sound_get_length_in_pcm_frames(ma_sound* pSound, ma_uint64* pLength)
{
    if (pSound == NULL) {
        return MA_INVALID_ARGS;
    }

    /* The notion of a sound length is only valid for sounds that are backed by a data source. */
    if (pSound->pDataSource == NULL) {
        return MA_INVALID_OPERATION;
    }

    return ma_data_source_get_length_in_pcm_frames(pSound->pDataSource, pLength);
}

MA_API ma_result ma_sound_get_cursor_in_seconds(ma_sound* pSound, float* pCursor)
{
    if (pSound == NULL) {
        return MA_INVALID_ARGS;
    }

    /* The notion of a cursor is only valid for sounds that are backed by a data source. */
    if (pSound->pDataSource == NULL) {

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

MA_API void ma_sound_group_set_directional_attenuation_factor(ma_sound_group* pGroup, float directionalAttenuationFactor)
{
    ma_sound_set_directional_attenuation_factor(pGroup, directionalAttenuationFactor);
}

MA_API float ma_sound_group_get_directional_attenuation_factor(const ma_sound_group* pGroup)
{
    return ma_sound_get_directional_attenuation_factor(pGroup);
}

MA_API void ma_sound_group_set_fade_in_pcm_frames(ma_sound_group* pGroup, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInFrames)
{
    ma_sound_set_fade_in_pcm_frames(pGroup, volumeBeg, volumeEnd, fadeLengthInFrames);
}

MA_API void ma_sound_group_set_fade_in_milliseconds(ma_sound_group* pGroup, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInMilliseconds)
{
    ma_sound_set_fade_in_milliseconds(pGroup, volumeBeg, volumeEnd, fadeLengthInMilliseconds);
}

MA_API float ma_sound_group_get_current_fade_volume(ma_sound_group* pGroup)
{
    return ma_sound_get_current_fade_volume(pGroup);
}

MA_API void ma_sound_group_set_start_time_in_pcm_frames(ma_sound_group* pGroup, ma_uint64 absoluteGlobalTimeInFrames)
{
    ma_sound_set_start_time_in_pcm_frames(pGroup, absoluteGlobalTimeInFrames);
}

MA_API void ma_sound_group_set_start_time_in_milliseconds(ma_sound_group* pGroup, ma_uint64 absoluteGlobalTimeInMilliseconds)
{
    ma_sound_set_start_time_in_milliseconds(pGroup, absoluteGlobalTimeInMilliseconds);
}

MA_API void ma_sound_group_set_stop_time_in_pcm_frames(ma_sound_group* pGroup, ma_uint64 absoluteGlobalTimeInFrames)
{
    ma_sound_set_stop_time_in_pcm_frames(pGroup, absoluteGlobalTimeInFrames);
}

MA_API void ma_sound_group_set_stop_time_in_milliseconds(ma_sound_group* pGroup, ma_uint64 absoluteGlobalTimeInMilliseconds)
{
    ma_sound_set_stop_time_in_milliseconds(pGroup, absoluteGlobalTimeInMilliseconds);
}

MA_API ma_bool32 ma_sound_group_is_playing(const ma_sound_group* pGroup)
{
    return ma_sound_is_playing(pGroup);
}

MA_API ma_uint64 ma_sound_group_get_time_in_pcm_frames(const ma_sound_group* pGroup)
{
    return ma_sound_get_time_in_pcm_frames(pGroup);
}
#endif  /* MA_NO_ENGINE */



/**************************************************************************************************************************************************************
***************************************************************************************************************************************************************

Auto Generated
==============

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        formatTag == DR_WAVE_FORMAT_DVI_ADPCM;
}
DRWAV_PRIVATE unsigned int drwav__chunk_padding_size_riff(drwav_uint64 chunkSize)
{
    return (unsigned int)(chunkSize % 2);
}
DRWAV_PRIVATE unsigned int drwav__chunk_padding_size_w64(drwav_uint64 chunkSize)
{
    return (unsigned int)(chunkSize % 8);
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut);
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut);
DRWAV_PRIVATE drwav_bool32 drwav_init_write__internal(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount);
DRWAV_PRIVATE drwav_result drwav__read_chunk_header(drwav_read_proc onRead, void* pUserData, drwav_container container, drwav_uint64* pRunningBytesReadOut, drwav_chunk_header* pHeaderOut)
{
    if (container == drwav_container_riff || container == drwav_container_rf64) {
        drwav_uint8 sizeInBytes[4];
        if (onRead(pUserData, pHeaderOut->id.fourcc, 4) != 4) {
            return DRWAV_AT_END;
        }
        if (onRead(pUserData, sizeInBytes, 4) != 4) {
            return DRWAV_INVALID_FILE;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

                    break;
                }
                bytesRead += 1;
            }
        }
    } else if ((allowedMetadataTypes & drwav_metadata_type_unknown) != 0) {
        bytesRead = drwav__metadata_process_unknown_chunk(pParser, pChunkID, pChunkHeader->sizeInBytes, drwav_metadata_location_top_level);
    }
    return bytesRead;
}
DRWAV_PRIVATE drwav_uint32 drwav_get_bytes_per_pcm_frame(drwav* pWav)
{
    drwav_uint32 bytesPerFrame;
    if ((pWav->bitsPerSample & 0x7) == 0) {
        bytesPerFrame = (pWav->bitsPerSample * pWav->fmt.channels) >> 3;
    } else {
        bytesPerFrame = pWav->fmt.blockAlign;
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW || pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
        if (bytesPerFrame != pWav->fmt.channels) {
            return 0;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    pWav->fmt                 = fmt;
    pWav->sampleRate          = fmt.sampleRate;
    pWav->channels            = fmt.channels;
    pWav->bitsPerSample       = fmt.bitsPerSample;
    pWav->bytesRemaining      = dataChunkSize;
    pWav->translatedFormatTag = translatedFormatTag;
    pWav->dataChunkDataSize   = dataChunkSize;
    if (sampleCountFromFactChunk != 0) {
        pWav->totalPCMFrameCount = sampleCountFromFactChunk;
    } else {
        drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
        if (bytesPerFrame == 0) {
            return DRWAV_FALSE;
        }
        pWav->totalPCMFrameCount = dataChunkSize / bytesPerFrame;
        if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
            drwav_uint64 totalBlockHeaderSizeInBytes;
            drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
            if ((blockCount * fmt.blockAlign) < dataChunkSize) {
                blockCount += 1;
            }

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            totalBlockHeaderSizeInBytes = blockCount * (4*fmt.channels);
            pWav->totalPCMFrameCount = ((dataChunkSize - totalBlockHeaderSizeInBytes) * 2) / fmt.channels;
            pWav->totalPCMFrameCount += blockCount;
        }
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM || pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
        if (pWav->channels > 2) {
            return DRWAV_FALSE;
        }
    }
    if (drwav_get_bytes_per_pcm_frame(pWav) == 0) {
        return DRWAV_FALSE;
    }
#ifdef DR_WAV_LIBSNDFILE_COMPAT
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
        drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
        pWav->totalPCMFrameCount = (((blockCount * (fmt.blockAlign - (6*pWav->channels))) * 2)) / fmt.channels;
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
        drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
        pWav->totalPCMFrameCount = (((blockCount * (fmt.blockAlign - (4*pWav->channels))) * 2) + (blockCount * pWav->channels)) / fmt.channels;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    }
    return drwav_init_write__internal(pWav, pFormat, 0);
}
DRWAV_API drwav_bool32 drwav_init_write_sequential(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    if (!drwav_preinit_write(pWav, pFormat, DRWAV_TRUE, onWrite, NULL, pUserData, pAllocationCallbacks)) {
        return DRWAV_FALSE;
    }
    return drwav_init_write__internal(pWav, pFormat, totalSampleCount);
}
DRWAV_API drwav_bool32 drwav_init_write_sequential_pcm_frames(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    if (pFormat == NULL) {
        return DRWAV_FALSE;
    }
    return drwav_init_write_sequential(pWav, pFormat, totalPCMFrameCount*pFormat->channels, onWrite, pUserData, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_write_with_metadata(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks, drwav_metadata* pMetadata,...
{
    if (!drwav_preinit_write(pWav, pFormat, DRWAV_FALSE, onWrite, onSeek, pUserData, pAllocationCallbacks)) {
        return DRWAV_FALSE;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    return drwav_init_file_write__internal_FILE(pWav, pFile, pFormat, totalSampleCount, isSequential, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    return drwav_init_file_write__internal(pWav, filename, pFormat, 0, DRWAV_FALSE, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_file_write_sequential(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    return drwav_init_file_write__internal(pWav, filename, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    if (pFormat == NULL) {
        return DRWAV_FALSE;
    }
    return drwav_init_file_write_sequential(pWav, filename, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_file_write_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    return drwav_init_file_write_w__internal(pWav, filename, pFormat, 0, DRWAV_FALSE, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    return drwav_init_file_write_w__internal(pWav, filename, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    if (pFormat == NULL) {
        return DRWAV_FALSE;
    }
    return drwav_init_file_write_sequential_w(pWav, filename, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
}
#endif
DRWAV_PRIVATE size_t drwav__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead)
{
    drwav* pWav = (drwav*)pUserData;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    return drwav_init_write__internal(pWav, pFormat, totalSampleCount);
}
DRWAV_API drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    return drwav_init_memory_write__internal(pWav, ppData, pDataSize, pFormat, 0, DRWAV_FALSE, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    return drwav_init_memory_write__internal(pWav, ppData, pDataSize, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
}
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential_pcm_frames(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    if (pFormat == NULL) {
        return DRWAV_FALSE;
    }
    return drwav_init_memory_write_sequential(pWav, ppData, pDataSize, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
}
DRWAV_API drwav_result drwav_uninit(drwav* pWav)
{
    drwav_result result = DRWAV_SUCCESS;
    if (pWav == NULL) {

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    drwav_uint32 bytesPerFrame;
    if (pWav == NULL || bytesToRead == 0) {
        return 0;
    }
    if (bytesToRead > pWav->bytesRemaining) {
        bytesToRead = (size_t)pWav->bytesRemaining;
    }
    if (bytesToRead == 0) {
        return 0;
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    if (pBufferOut != NULL) {
        bytesRead = pWav->onRead(pWav->pUserData, pBufferOut, bytesToRead);
    } else {
        bytesRead = 0;
        while (bytesRead < bytesToRead) {
            size_t bytesToSeek = (bytesToRead - bytesRead);
            if (bytesToSeek > 0x7FFFFFFF) {

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            bytesRead += bytesSeeked;
            if (bytesSeeked < bytesToSeek) {
                break;
            }
        }
    }
    pWav->readCursorInPCMFrames += bytesRead / bytesPerFrame;
    pWav->bytesRemaining -= bytesRead;
    return bytesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_le(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut)
{
    drwav_uint32 bytesPerFrame;
    drwav_uint64 bytesToRead;
    if (pWav == NULL || framesToRead == 0) {
        return 0;
    }
    if (drwav__is_compressed_format_tag(pWav->translatedFormatTag)) {
        return 0;
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    bytesToRead = framesToRead * bytesPerFrame;
    if (bytesToRead > DRWAV_SIZE_MAX) {
        bytesToRead = (DRWAV_SIZE_MAX / bytesPerFrame) * bytesPerFrame;
    }
    if (bytesToRead == 0) {
        return 0;
    }
    return drwav_read_raw(pWav, (size_t)bytesToRead, pBufferOut) / bytesPerFrame;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL) {
        drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
        if (bytesPerFrame == 0) {
            return 0;
        }
        drwav__bswap_samples(pBufferOut, framesRead*pWav->channels, bytesPerFrame/pWav->channels, pWav->translatedFormatTag);
    }
    return framesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut)
{
    if (drwav__is_little_endian()) {
        return drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut);
    } else {
        return drwav_read_pcm_frames_be(pWav, framesToRead, pBufferOut);
    }
}
DRWAV_PRIVATE drwav_bool32 drwav_seek_to_first_pcm_frame(drwav* pWav)
{
    if (pWav->onWrite != NULL) {
        return DRWAV_FALSE;
    }
    if (!pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos, drwav_seek_origin_start)) {
        return DRWAV_FALSE;
    }
    if (drwav__is_compressed_format_tag(pWav->translatedFormatTag)) {
        if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
            DRWAV_ZERO_OBJECT(&pWav->msadpcm);
        } else if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
            DRWAV_ZERO_OBJECT(&pWav->ima);
        } else {
            DRWAV_ASSERT(DRWAV_FALSE);
        }
    }
    pWav->readCursorInPCMFrames = 0;
    pWav->bytesRemaining = pWav->dataChunkDataSize;
    return DRWAV_TRUE;
}
DRWAV_API drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64 targetFrameIndex)
{
    if (pWav == NULL || pWav->onSeek == NULL) {
        return DRWAV_FALSE;
    }
    if (pWav->onWrite != NULL) {
        return DRWAV_FALSE;
    }
    if (pWav->totalPCMFrameCount == 0) {
        return DRWAV_TRUE;
    }
    if (targetFrameIndex > pWav->totalPCMFrameCount) {
        targetFrameIndex = pWav->totalPCMFrameCount;
    }
    if (drwav__is_compressed_format_tag(pWav->translatedFormatTag)) {
        if (targetFrameIndex < pWav->readCursorInPCMFrames) {
            if (!drwav_seek_to_first_pcm_frame(pWav)) {
                return DRWAV_FALSE;
            }
        }
        if (targetFrameIndex > pWav->readCursorInPCMFrames) {
            drwav_uint64 offsetInFrames = targetFrameIndex - pWav->readCursorInPCMFrames;
            drwav_int16 devnull[2048];
            while (offsetInFrames > 0) {
                drwav_uint64 framesRead = 0;
                drwav_uint64 framesToRead = offsetInFrames;
                if (framesToRead > drwav_countof(devnull)/pWav->channels) {
                    framesToRead = drwav_countof(devnull)/pWav->channels;
                }
                if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
                    framesRead = drwav_read_pcm_frames_s16__msadpcm(pWav, framesToRead, devnull);
                } else if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
                    framesRead = drwav_read_pcm_frames_s16__ima(pWav, framesToRead, devnull);
                } else {
                    DRWAV_ASSERT(DRWAV_FALSE);
                }
                if (framesRead != framesToRead) {
                    return DRWAV_FALSE;
                }
                offsetInFrames -= framesRead;
            }
        }
    } else {
        drwav_uint64 totalSizeInBytes;
        drwav_uint64 currentBytePos;
        drwav_uint64 targetBytePos;
        drwav_uint64 offset;
        drwav_uint32 bytesPerFrame;
        bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
        if (bytesPerFrame == 0) {
            return DRWAV_FALSE;
        }
        totalSizeInBytes = pWav->totalPCMFrameCount * bytesPerFrame;
        DRWAV_ASSERT(totalSizeInBytes >= pWav->bytesRemaining);
        currentBytePos = totalSizeInBytes - pWav->bytesRemaining;
        targetBytePos  = targetFrameIndex * bytesPerFrame;
        if (currentBytePos < targetBytePos) {
            offset = (targetBytePos - currentBytePos);
        } else {
            if (!drwav_seek_to_first_pcm_frame(pWav)) {
                return DRWAV_FALSE;
            }
            offset = targetBytePos;
        }
        while (offset > 0) {
            int offset32 = ((offset > INT_MAX) ? INT_MAX : (int)offset);
            if (!pWav->onSeek(pWav->pUserData, offset32, drwav_seek_origin_current)) {
                return DRWAV_FALSE;
            }
            pWav->readCursorInPCMFrames += offset32 / bytesPerFrame;
            pWav->bytesRemaining        -= offset32;
            offset                      -= offset32;
        }
    }
    return DRWAV_TRUE;
}
DRWAV_API drwav_result drwav_get_cursor_in_pcm_frames(drwav* pWav, drwav_uint64* pCursor)
{
    if (pCursor == NULL) {
        return DRWAV_INVALID_ARGS;
    }
    *pCursor = 0;
    if (pWav == NULL) {
        return DRWAV_INVALID_ARGS;
    }
    *pCursor = pWav->readCursorInPCMFrames;
    return DRWAV_SUCCESS;
}
DRWAV_API drwav_result drwav_get_length_in_pcm_frames(drwav* pWav, drwav_uint64* pLength)
{
    if (pLength == NULL) {
        return DRWAV_INVALID_ARGS;
    }
    *pLength = 0;
    if (pWav == NULL) {
        return DRWAV_INVALID_ARGS;
    }
    *pLength = pWav->totalPCMFrameCount;
    return DRWAV_SUCCESS;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

DRWAV_API size_t drwav_write_raw(drwav* pWav, size_t bytesToWrite, const void* pData)
{
    size_t bytesWritten;
    if (pWav == NULL || bytesToWrite == 0 || pData == NULL) {
        return 0;
    }
    bytesWritten = pWav->onWrite(pWav->pUserData, pData, bytesToWrite);
    pWav->dataChunkDataSize += bytesWritten;
    return bytesWritten;
}
DRWAV_API drwav_uint64 drwav_write_pcm_frames_le(drwav* pWav, drwav_uint64 framesToWrite, const void* pData)
{
    drwav_uint64 bytesToWrite;
    drwav_uint64 bytesWritten;
    const drwav_uint8* pRunningData;
    if (pWav == NULL || framesToWrite == 0 || pData == NULL) {
        return 0;
    }
    bytesToWrite = ((framesToWrite * pWav->channels * pWav->bitsPerSample) / 8);
    if (bytesToWrite > DRWAV_SIZE_MAX) {
        return 0;
    }
    bytesWritten = 0;
    pRunningData = (const drwav_uint8*)pData;
    while (bytesToWrite > 0) {
        size_t bytesJustWritten;
        drwav_uint64 bytesToWriteThisIteration;
        bytesToWriteThisIteration = bytesToWrite;
        DRWAV_ASSERT(bytesToWriteThisIteration <= DRWAV_SIZE_MAX);
        bytesJustWritten = drwav_write_raw(pWav, (size_t)bytesToWriteThisIteration, pRunningData);
        if (bytesJustWritten == 0) {
            break;
        }
        bytesToWrite -= bytesJustWritten;
        bytesWritten += bytesJustWritten;
        pRunningData += bytesJustWritten;
    }
    return (bytesWritten * 8) / pWav->bitsPerSample / pWav->channels;
}
DRWAV_API drwav_uint64 drwav_write_pcm_frames_be(drwav* pWav, drwav_uint64 framesToWrite, const void* pData)
{
    drwav_uint64 bytesToWrite;
    drwav_uint64 bytesWritten;
    drwav_uint32 bytesPerSample;
    const drwav_uint8* pRunningData;
    if (pWav == NULL || framesToWrite == 0 || pData == NULL) {
        return 0;
    }
    bytesToWrite = ((framesToWrite * pWav->channels * pWav->bitsPerSample) / 8);
    if (bytesToWrite > DRWAV_SIZE_MAX) {
        return 0;
    }
    bytesWritten = 0;
    pRunningData = (const drwav_uint8*)pData;
    bytesPerSample = drwav_get_bytes_per_pcm_frame(pWav) / pWav->channels;
    if (bytesPerSample == 0) {
        return 0;
    }
    while (bytesToWrite > 0) {
        drwav_uint8 temp[4096];
        drwav_uint32 sampleCount;
        size_t bytesJustWritten;
        drwav_uint64 bytesToWriteThisIteration;
        bytesToWriteThisIteration = bytesToWrite;
        DRWAV_ASSERT(bytesToWriteThisIteration <= DRWAV_SIZE_MAX);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        bytesJustWritten = drwav_write_raw(pWav, (size_t)bytesToWriteThisIteration, temp);
        if (bytesJustWritten == 0) {
            break;
        }
        bytesToWrite -= bytesJustWritten;
        bytesWritten += bytesJustWritten;
        pRunningData += bytesJustWritten;
    }
    return (bytesWritten * 8) / pWav->bitsPerSample / pWav->channels;
}
DRWAV_API drwav_uint64 drwav_write_pcm_frames(drwav* pWav, drwav_uint64 framesToWrite, const void* pData)
{
    if (drwav__is_little_endian()) {
        return drwav_write_pcm_frames_le(pWav, framesToWrite, pData);
    } else {
        return drwav_write_pcm_frames_be(pWav, framesToWrite, pData);
    }
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 totalFramesRead = 0;
    DRWAV_ASSERT(pWav != NULL);
    DRWAV_ASSERT(framesToRead > 0);
    while (pWav->readCursorInPCMFrames < pWav->totalPCMFrameCount) {
        DRWAV_ASSERT(framesToRead > 0);
        if (pWav->msadpcm.cachedFrameCount == 0 && pWav->msadpcm.bytesRemainingInBlock == 0) {
            if (pWav->channels == 1) {
                drwav_uint8 header[7];
                if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
                    return totalFramesRead;
                }
                pWav->msadpcm.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
                pWav->msadpcm.predictor[0]     = header[0];
                pWav->msadpcm.delta[0]         = drwav_bytes_to_s16(header + 1);
                pWav->msadpcm.prevFrames[0][1] = (drwav_int32)drwav_bytes_to_s16(header + 3);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

                pWav->msadpcm.prevFrames[1][1] = (drwav_int32)drwav_bytes_to_s16(header + 8);
                pWav->msadpcm.prevFrames[0][0] = (drwav_int32)drwav_bytes_to_s16(header + 10);
                pWav->msadpcm.prevFrames[1][0] = (drwav_int32)drwav_bytes_to_s16(header + 12);
                pWav->msadpcm.cachedFrames[0] = pWav->msadpcm.prevFrames[0][0];
                pWav->msadpcm.cachedFrames[1] = pWav->msadpcm.prevFrames[1][0];
                pWav->msadpcm.cachedFrames[2] = pWav->msadpcm.prevFrames[0][1];
                pWav->msadpcm.cachedFrames[3] = pWav->msadpcm.prevFrames[1][1];
                pWav->msadpcm.cachedFrameCount = 2;
            }
        }
        while (framesToRead > 0 && pWav->msadpcm.cachedFrameCount > 0 && pWav->readCursorInPCMFrames < pWav->totalPCMFrameCount) {
            if (pBufferOut != NULL) {
                drwav_uint32 iSample = 0;
                for (iSample = 0; iSample < pWav->channels; iSample += 1) {
                    pBufferOut[iSample] = (drwav_int16)pWav->msadpcm.cachedFrames[(drwav_countof(pWav->msadpcm.cachedFrames) - (pWav->msadpcm.cachedFrameCount*pWav->channels)) + iSample];
                }
                pBufferOut += pWav->channels;
            }
            framesToRead    -= 1;
            totalFramesRead += 1;
            pWav->readCursorInPCMFrames += 1;
            pWav->msadpcm.cachedFrameCount -= 1;
        }
        if (framesToRead == 0) {
            break;
        }
        if (pWav->msadpcm.cachedFrameCount == 0) {
            if (pWav->msadpcm.bytesRemainingInBlock == 0) {
                continue;
            } else {
                static drwav_int32 adaptationTable[] = {
                    230, 230, 230, 230, 307, 409, 512, 614,
                    768, 614, 512, 409, 307, 230, 230, 230
                };

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

                    pWav->msadpcm.prevFrames[1][1] = newSample1;
                    pWav->msadpcm.cachedFrames[2] = newSample0;
                    pWav->msadpcm.cachedFrames[3] = newSample1;
                    pWav->msadpcm.cachedFrameCount = 1;
                }
            }
        }
    }
    return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 totalFramesRead = 0;
    drwav_uint32 iChannel;
    static drwav_int32 indexTable[16] = {
        -1, -1, -1, -1, 2, 4, 6, 8,
        -1, -1, -1, -1, 2, 4, 6, 8
    };
    static drwav_int32 stepTable[89] = {
        7,     8,     9,     10,    11,    12,    13,    14,    16,    17,
        19,    21,    23,    25,    28,    31,    34,    37,    41,    45,
        50,    55,    60,    66,    73,    80,    88,    97,    107,   118,
        130,   143,   157,   173,   190,   209,   230,   253,   279,   307,
        337,   371,   408,   449,   494,   544,   598,   658,   724,   796,
        876,   963,   1060,  1166,  1282,  1411,  1552,  1707,  1878,  2066,
        2272,  2499,  2749,  3024,  3327,  3660,  4026,  4428,  4871,  5358,
        5894,  6484,  7132,  7845,  8630,  9493,  10442, 11487, 12635, 13899,
        15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
    };
    DRWAV_ASSERT(pWav != NULL);
    DRWAV_ASSERT(framesToRead > 0);
    while (pWav->readCursorInPCMFrames < pWav->totalPCMFrameCount) {
        DRWAV_ASSERT(framesToRead > 0);
        if (pWav->ima.cachedFrameCount == 0 && pWav->ima.bytesRemainingInBlock == 0) {
            if (pWav->channels == 1) {
                drwav_uint8 header[4];
                if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
                    return totalFramesRead;
                }
                pWav->ima.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
                if (header[2] >= drwav_countof(stepTable)) {
                    pWav->onSeek(pWav->pUserData, pWav->ima.bytesRemainingInBlock, drwav_seek_origin_current);
                    pWav->ima.bytesRemainingInBlock = 0;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

                }
                pWav->ima.predictor[0] = drwav_bytes_to_s16(header + 0);
                pWav->ima.stepIndex[0] = drwav_clamp(header[2], 0, (drwav_int32)drwav_countof(stepTable)-1);
                pWav->ima.predictor[1] = drwav_bytes_to_s16(header + 4);
                pWav->ima.stepIndex[1] = drwav_clamp(header[6], 0, (drwav_int32)drwav_countof(stepTable)-1);
                pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 2] = pWav->ima.predictor[0];
                pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[1];
                pWav->ima.cachedFrameCount = 1;
            }
        }
        while (framesToRead > 0 && pWav->ima.cachedFrameCount > 0 && pWav->readCursorInPCMFrames < pWav->totalPCMFrameCount) {
            if (pBufferOut != NULL) {
                drwav_uint32 iSample;
                for (iSample = 0; iSample < pWav->channels; iSample += 1) {
                    pBufferOut[iSample] = (drwav_int16)pWav->ima.cachedFrames[(drwav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + iSample];
                }
                pBufferOut += pWav->channels;
            }
            framesToRead    -= 1;
            totalFramesRead += 1;
            pWav->readCursorInPCMFrames += 1;
            pWav->ima.cachedFrameCount -= 1;
        }
        if (framesToRead == 0) {
            break;
        }
        if (pWav->ima.cachedFrameCount == 0) {
            if (pWav->ima.bytesRemainingInBlock == 0) {
                continue;
            } else {
                pWav->ima.cachedFrameCount = 8;
                for (iChannel = 0; iChannel < pWav->channels; ++iChannel) {
                    drwav_uint32 iByte;
                    drwav_uint8 nibbles[4];

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        drwav_f32_to_s16(pOut, (const float*)pIn, totalSampleCount);
        return;
    } else if (bytesPerSample == 8) {
        drwav_f64_to_s16(pOut, (const double*)pIn, totalSampleCount);
        return;
    } else {
        DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
        return;
    }
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__pcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096] = {0};
    drwav_uint32 bytesPerFrame;
    drwav_uint32 bytesPerSample;
    drwav_uint64 samplesRead;
    if ((pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 16) || pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    bytesPerSample = bytesPerFrame / pWav->channels;
    if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        samplesRead = framesRead * pWav->channels;
        if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
            DRWAV_ASSERT(DRWAV_FALSE);
            break;
        }
        drwav__pcm_to_s16(pBufferOut, sampleData, (size_t)samplesRead, bytesPerSample);
        pBufferOut      += samplesRead;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ieee(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096] = {0};
    drwav_uint32 bytesPerFrame;
    drwav_uint32 bytesPerSample;
    drwav_uint64 samplesRead;
    if (pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, NULL);
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    bytesPerSample = bytesPerFrame / pWav->channels;
    if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        samplesRead = framesRead * pWav->channels;
        if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
            DRWAV_ASSERT(DRWAV_FALSE);
            break;
        }
        drwav__ieee_to_s16(pBufferOut, sampleData, (size_t)samplesRead, bytesPerSample);
        pBufferOut      += samplesRead;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__alaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096] = {0};
    drwav_uint32 bytesPerFrame;
    drwav_uint32 bytesPerSample;
    drwav_uint64 samplesRead;
    if (pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, NULL);
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    bytesPerSample = bytesPerFrame / pWav->channels;
    if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        samplesRead = framesRead * pWav->channels;
        if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
            DRWAV_ASSERT(DRWAV_FALSE);
            break;
        }
        drwav_alaw_to_s16(pBufferOut, sampleData, (size_t)samplesRead);
        pBufferOut      += samplesRead;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__mulaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096] = {0};
    drwav_uint32 bytesPerFrame;
    drwav_uint32 bytesPerSample;
    drwav_uint64 samplesRead;
    if (pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, NULL);
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    bytesPerSample = bytesPerFrame / pWav->channels;
    if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        samplesRead = framesRead * pWav->channels;
        if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
            DRWAV_ASSERT(DRWAV_FALSE);
            break;
        }
        drwav_mulaw_to_s16(pBufferOut, sampleData, (size_t)samplesRead);
        pBufferOut      += samplesRead;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    if (pWav == NULL || framesToRead == 0) {
        return 0;
    }
    if (pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, NULL);
    }
    if (framesToRead * pWav->channels * sizeof(drwav_int16) > DRWAV_SIZE_MAX) {
        framesToRead = DRWAV_SIZE_MAX / sizeof(drwav_int16) / pWav->channels;
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
        return drwav_read_pcm_frames_s16__pcm(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
        return drwav_read_pcm_frames_s16__ieee(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
        return drwav_read_pcm_frames_s16__alaw(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
        return drwav_read_pcm_frames_s16__mulaw(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
        return drwav_read_pcm_frames_s16__msadpcm(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
        return drwav_read_pcm_frames_s16__ima(pWav, framesToRead, pBufferOut);
    }
    return 0;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16le(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_FALSE) {
        drwav__bswap_samples_s16(pBufferOut, framesRead*pWav->channels);
    }
    return framesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16be(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_TRUE) {
        drwav__bswap_samples_s16(pBufferOut, framesRead*pWav->channels);
    }
    return framesRead;
}
DRWAV_API void drwav_u8_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
{
    int r;
    size_t i;
    for (i = 0; i < sampleCount; ++i) {
        int x = pIn[i];
        r = x << 8;
        r = r - 32768;
        pOut[i] = (short)r;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        }
        return;
    } else if (bytesPerSample == 8) {
        drwav_f64_to_f32(pOut, (const double*)pIn, sampleCount);
        return;
    } else {
        DRWAV_ZERO_MEMORY(pOut, sampleCount * sizeof(*pOut));
        return;
    }
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__pcm(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096] = {0};
    drwav_uint32 bytesPerFrame;
    drwav_uint32 bytesPerSample;
    drwav_uint64 samplesRead;
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    bytesPerSample = bytesPerFrame / pWav->channels;
    if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        samplesRead = framesRead * pWav->channels;
        if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
            DRWAV_ASSERT(DRWAV_FALSE);
            break;
        }
        drwav__pcm_to_f32(pBufferOut, sampleData, (size_t)samplesRead, bytesPerSample);
        pBufferOut      += samplesRead;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__msadpcm_ima(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_int16 samples16[2048];
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels);
        drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToReadThisIteration, samples16);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        drwav_s16_to_f32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ieee(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096] = {0};
    drwav_uint32 bytesPerFrame;
    drwav_uint32 bytesPerSample;
    drwav_uint64 samplesRead;
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT && pWav->bitsPerSample == 32) {
        return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    bytesPerSample = bytesPerFrame / pWav->channels;
    if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        samplesRead = framesRead * pWav->channels;
        if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
            DRWAV_ASSERT(DRWAV_FALSE);
            break;
        }
        drwav__ieee_to_f32(pBufferOut, sampleData, (size_t)samplesRead, bytesPerSample);
        pBufferOut      += samplesRead;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__alaw(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096] = {0};
    drwav_uint32 bytesPerFrame;
    drwav_uint32 bytesPerSample;
    drwav_uint64 samplesRead;
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    bytesPerSample = bytesPerFrame / pWav->channels;
    if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        samplesRead = framesRead * pWav->channels;
        if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
            DRWAV_ASSERT(DRWAV_FALSE);
            break;
        }
        drwav_alaw_to_f32(pBufferOut, sampleData, (size_t)samplesRead);
        pBufferOut      += samplesRead;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__mulaw(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096] = {0};
    drwav_uint32 bytesPerFrame;
    drwav_uint32 bytesPerSample;
    drwav_uint64 samplesRead;
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    bytesPerSample = bytesPerFrame / pWav->channels;
    if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        samplesRead = framesRead * pWav->channels;
        if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
            DRWAV_ASSERT(DRWAV_FALSE);
            break;
        }
        drwav_mulaw_to_f32(pBufferOut, sampleData, (size_t)samplesRead);
        pBufferOut      += samplesRead;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    if (pWav == NULL || framesToRead == 0) {
        return 0;
    }
    if (pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, NULL);
    }
    if (framesToRead * pWav->channels * sizeof(float) > DRWAV_SIZE_MAX) {
        framesToRead = DRWAV_SIZE_MAX / sizeof(float) / pWav->channels;
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
        return drwav_read_pcm_frames_f32__pcm(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM || pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
        return drwav_read_pcm_frames_f32__msadpcm_ima(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
        return drwav_read_pcm_frames_f32__ieee(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
        return drwav_read_pcm_frames_f32__alaw(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
        return drwav_read_pcm_frames_f32__mulaw(pWav, framesToRead, pBufferOut);
    }
    return 0;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32le(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_f32(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_FALSE) {
        drwav__bswap_samples_f32(pBufferOut, framesRead*pWav->channels);
    }
    return framesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32be(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_f32(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_TRUE) {
        drwav__bswap_samples_f32(pBufferOut, framesRead*pWav->channels);
    }
    return framesRead;
}
DRWAV_API void drwav_u8_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
{
    size_t i;
    if (pOut == NULL || pIn == NULL) {
        return;
    }
#ifdef DR_WAV_LIBSNDFILE_COMPAT
    for (i = 0; i < sampleCount; ++i) {
        *pOut++ = (pIn[i] / 256.0f) * 2 - 1;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        drwav_f32_to_s32(pOut, (const float*)pIn, totalSampleCount);
        return;
    } else if (bytesPerSample == 8) {
        drwav_f64_to_s32(pOut, (const double*)pIn, totalSampleCount);
        return;
    } else {
        DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
        return;
    }
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__pcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096] = {0};
    drwav_uint32 bytesPerFrame;
    drwav_uint32 bytesPerSample;
    drwav_uint64 samplesRead;
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 32) {
        return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
    }
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    bytesPerSample = bytesPerFrame / pWav->channels;
    if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        samplesRead = framesRead * pWav->channels;
        if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
            DRWAV_ASSERT(DRWAV_FALSE);
            break;
        }
        drwav__pcm_to_s32(pBufferOut, sampleData, (size_t)samplesRead, bytesPerSample);
        pBufferOut      += samplesRead;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__msadpcm_ima(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 totalFramesRead = 0;
    drwav_int16 samples16[2048];
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels);
        drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToReadThisIteration, samples16);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        drwav_s16_to_s32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));
        pBufferOut      += framesRead*pWav->channels;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__ieee(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096] = {0};
    drwav_uint32 bytesPerFrame;
    drwav_uint32 bytesPerSample;
    drwav_uint64 samplesRead;
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    bytesPerSample = bytesPerFrame / pWav->channels;
    if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        samplesRead = framesRead * pWav->channels;
        if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
            DRWAV_ASSERT(DRWAV_FALSE);
            break;
        }
        drwav__ieee_to_s32(pBufferOut, sampleData, (size_t)samplesRead, bytesPerSample);
        pBufferOut      += samplesRead;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__alaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096] = {0};
    drwav_uint32 bytesPerFrame;
    drwav_uint32 bytesPerSample;
    drwav_uint64 samplesRead;
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    bytesPerSample = bytesPerFrame / pWav->channels;
    if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        samplesRead = framesRead * pWav->channels;
        if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
            DRWAV_ASSERT(DRWAV_FALSE);
            break;
        }
        drwav_alaw_to_s32(pBufferOut, sampleData, (size_t)samplesRead);
        pBufferOut      += samplesRead;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__mulaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 totalFramesRead;
    drwav_uint8 sampleData[4096] = {0};
    drwav_uint32 bytesPerFrame;
    drwav_uint32 bytesPerSample;
    drwav_uint64 samplesRead;
    bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
    if (bytesPerFrame == 0) {
        return 0;
    }
    bytesPerSample = bytesPerFrame / pWav->channels;
    if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
        return 0;
    }
    totalFramesRead = 0;
    while (framesToRead > 0) {
        drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
        drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
        if (framesRead == 0) {
            break;
        }
        DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
        samplesRead = framesRead * pWav->channels;
        if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
            DRWAV_ASSERT(DRWAV_FALSE);
            break;
        }
        drwav_mulaw_to_s32(pBufferOut, sampleData, (size_t)samplesRead);
        pBufferOut      += samplesRead;
        framesToRead    -= framesRead;
        totalFramesRead += framesRead;
    }
    return totalFramesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    if (pWav == NULL || framesToRead == 0) {
        return 0;
    }
    if (pBufferOut == NULL) {
        return drwav_read_pcm_frames(pWav, framesToRead, NULL);
    }
    if (framesToRead * pWav->channels * sizeof(drwav_int32) > DRWAV_SIZE_MAX) {
        framesToRead = DRWAV_SIZE_MAX / sizeof(drwav_int32) / pWav->channels;
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
        return drwav_read_pcm_frames_s32__pcm(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM || pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
        return drwav_read_pcm_frames_s32__msadpcm_ima(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
        return drwav_read_pcm_frames_s32__ieee(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
        return drwav_read_pcm_frames_s32__alaw(pWav, framesToRead, pBufferOut);
    }
    if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
        return drwav_read_pcm_frames_s32__mulaw(pWav, framesToRead, pBufferOut);
    }
    return 0;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32le(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_s32(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_FALSE) {
        drwav__bswap_samples_s32(pBufferOut, framesRead*pWav->channels);
    }
    return framesRead;
}
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32be(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
    drwav_uint64 framesRead = drwav_read_pcm_frames_s32(pWav, framesToRead, pBufferOut);
    if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_TRUE) {
        drwav__bswap_samples_s32(pBufferOut, framesRead*pWav->channels);
    }
    return framesRead;
}
DRWAV_API void drwav_u8_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
{
    size_t i;
    if (pOut == NULL || pIn == NULL) {
        return;
    }
    for (i = 0; i < sampleCount; ++i) {
        *pOut++ = ((int)pIn[i] - 128) << 24;
    }

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

DRWAV_API void drwav_mulaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
{
    size_t i;
    if (pOut == NULL || pIn == NULL) {
        return;
    }
    for (i= 0; i < sampleCount; ++i) {
        *pOut++ = ((drwav_int32)drwav__mulaw_to_s16(pIn[i])) << 16;
    }
}
DRWAV_PRIVATE drwav_int16* drwav__read_pcm_frames_and_close_s16(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
{
    drwav_uint64 sampleDataSize;
    drwav_int16* pSampleData;
    drwav_uint64 framesRead;
    DRWAV_ASSERT(pWav != NULL);
    sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(drwav_int16);
    if (sampleDataSize > DRWAV_SIZE_MAX) {
        drwav_uninit(pWav);
        return NULL;
    }
    pSampleData = (drwav_int16*)drwav__malloc_from_callbacks((size_t)sampleDataSize, &pWav->allocationCallbacks);
    if (pSampleData == NULL) {
        drwav_uninit(pWav);
        return NULL;
    }
    framesRead = drwav_read_pcm_frames_s16(pWav, (size_t)pWav->totalPCMFrameCount, pSampleData);
    if (framesRead != pWav->totalPCMFrameCount) {
        drwav__free_from_callbacks(pSampleData, &pWav->allocationCallbacks);
        drwav_uninit(pWav);
        return NULL;
    }
    drwav_uninit(pWav);
    if (sampleRate) {
        *sampleRate = pWav->sampleRate;
    }
    if (channels) {
        *channels = pWav->channels;
    }
    if (totalFrameCount) {
        *totalFrameCount = pWav->totalPCMFrameCount;
    }
    return pSampleData;
}
DRWAV_PRIVATE float* drwav__read_pcm_frames_and_close_f32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
{
    drwav_uint64 sampleDataSize;
    float* pSampleData;
    drwav_uint64 framesRead;
    DRWAV_ASSERT(pWav != NULL);
    sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(float);
    if (sampleDataSize > DRWAV_SIZE_MAX) {
        drwav_uninit(pWav);
        return NULL;
    }
    pSampleData = (float*)drwav__malloc_from_callbacks((size_t)sampleDataSize, &pWav->allocationCallbacks);
    if (pSampleData == NULL) {
        drwav_uninit(pWav);
        return NULL;
    }
    framesRead = drwav_read_pcm_frames_f32(pWav, (size_t)pWav->totalPCMFrameCount, pSampleData);
    if (framesRead != pWav->totalPCMFrameCount) {
        drwav__free_from_callbacks(pSampleData, &pWav->allocationCallbacks);
        drwav_uninit(pWav);
        return NULL;
    }
    drwav_uninit(pWav);
    if (sampleRate) {
        *sampleRate = pWav->sampleRate;
    }
    if (channels) {
        *channels = pWav->channels;
    }
    if (totalFrameCount) {
        *totalFrameCount = pWav->totalPCMFrameCount;
    }
    return pSampleData;
}
DRWAV_PRIVATE drwav_int32* drwav__read_pcm_frames_and_close_s32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
{
    drwav_uint64 sampleDataSize;
    drwav_int32* pSampleData;
    drwav_uint64 framesRead;
    DRWAV_ASSERT(pWav != NULL);
    sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(drwav_int32);
    if (sampleDataSize > DRWAV_SIZE_MAX) {
        drwav_uninit(pWav);
        return NULL;
    }
    pSampleData = (drwav_int32*)drwav__malloc_from_callbacks((size_t)sampleDataSize, &pWav->allocationCallbacks);
    if (pSampleData == NULL) {
        drwav_uninit(pWav);
        return NULL;
    }
    framesRead = drwav_read_pcm_frames_s32(pWav, (size_t)pWav->totalPCMFrameCount, pSampleData);
    if (framesRead != pWav->totalPCMFrameCount) {
        drwav__free_from_callbacks(pSampleData, &pWav->allocationCallbacks);
        drwav_uninit(pWav);
        return NULL;
    }
    drwav_uninit(pWav);
    if (sampleRate) {
        *sampleRate = pWav->sampleRate;
    }
    if (channels) {
        *channels = pWav->channels;
    }
    if (totalFrameCount) {
        *totalFrameCount = pWav->totalPCMFrameCount;
    }
    return pSampleData;
}
DRWAV_API drwav_int16* drwav_open_and_read_pcm_frames_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAl...
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API float* drwav_open_and_read_pcm_frames_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocati...
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API drwav_int32* drwav_open_and_read_pcm_frames_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAl...
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
#ifndef DR_WAV_NO_STDIO
DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_file(&wav, filename, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_file(&wav, filename, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_file(&wav, filename, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_file_w(&wav, filename, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_file_w(&wav, filename, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_file_w(&wav, filename, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
#endif
DRWAV_API drwav_int16* drwav_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_memory(&wav, data, dataSize, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API float* drwav_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_memory(&wav, data, dataSize, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
DRWAV_API drwav_int32* drwav_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    drwav wav;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalFrameCountOut) {
        *totalFrameCountOut = 0;
    }
    if (!drwav_init_memory(&wav, data, dataSize, pAllocationCallbacks)) {
        return NULL;
    }
    return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
#endif
DRWAV_API void drwav_free(void* p, const drwav_allocation_callbacks* pAllocationCallbacks)
{
    if (pAllocationCallbacks != NULL) {
        drwav__free_from_callbacks(p, pAllocationCallbacks);
    } else {
        drwav__free_default(p, NULL);
    }
}

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            }
        }
        if (partitionsRemaining == 1) {
            break;
        }
        partitionsRemaining -= 1;
        samplesInPartition = blockSize / (1 << partitionOrder);
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__decode_samples__constant(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
{
    drflac_uint32 i;
    drflac_int32 sample;
    if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
        return DRFLAC_FALSE;
    }
    for (i = 0; i < blockSize; ++i) {
        pDecodedSamples[i] = sample;
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
{
    drflac_uint32 i;
    for (i = 0; i < blockSize; ++i) {
        drflac_int32 sample;
        if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
            return DRFLAC_FALSE;
        }
        pDecodedSamples[i] = sample;
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__decode_samples__fixed(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
{
    drflac_uint32 i;
    static drflac_int32 lpcCoefficientsTable[5][4] = {
        {0,  0, 0,  0},
        {1,  0, 0,  0},
        {2, -1, 0,  0},
        {3, -3, 1,  0},
        {4, -6, 4, -1}
    };
    for (i = 0; i < lpcOrder; ++i) {
        drflac_int32 sample;
        if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
            return DRFLAC_FALSE;
        }
        pDecodedSamples[i] = sample;
    }
    if (!drflac__decode_samples_with_residual(bs, subframeBitsPerSample, blockSize, lpcOrder, 0, 4, lpcCoefficientsTable[lpcOrder], pDecodedSamples)) {
        return DRFLAC_FALSE;
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__decode_samples__lpc(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
{
    drflac_uint8 i;
    drflac_uint8 lpcPrecision;
    drflac_int8 lpcShift;
    drflac_int32 coefficients[32];

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    for (i = 0; i < lpcOrder; ++i) {
        if (!drflac__read_int32(bs, lpcPrecision, coefficients + i)) {
            return DRFLAC_FALSE;
        }
    }
    if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
        return DRFLAC_FALSE;
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__read_next_flac_frame_header(drflac_bs* bs, drflac_uint8 streaminfoBitsPerSample, drflac_frame_header* header)
{
    const drflac_uint32 sampleRateTable[12]  = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
    const drflac_uint8 bitsPerSampleTable[8] = {0, 8, 12, (drflac_uint8)-1, 16, 20, 24, (drflac_uint8)-1};
    DRFLAC_ASSERT(bs != NULL);
    DRFLAC_ASSERT(header != NULL);
    for (;;) {
        drflac_uint8 crc8 = 0xCE;
        drflac_uint8 reserved = 0;
        drflac_uint8 blockingStrategy = 0;
        drflac_uint8 blockSize = 0;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            return DRFLAC_FALSE;
        }
#ifndef DR_FLAC_NO_CRC
        if (header->crc8 != crc8) {
            continue;
        }
#endif
        return DRFLAC_TRUE;
    }
}
static drflac_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe)
{
    drflac_uint8 header;
    int type;
    if (!drflac__read_uint8(bs, 8, &header)) {
        return DRFLAC_FALSE;
    }
    if ((header & 0x80) != 0) {
        return DRFLAC_FALSE;
    }
    type = (header & 0x7E) >> 1;
    if (type == 0) {
        pSubframe->subframeType = DRFLAC_SUBFRAME_CONSTANT;
    } else if (type == 1) {
        pSubframe->subframeType = DRFLAC_SUBFRAME_VERBATIM;
    } else {
        if ((type & 0x20) != 0) {
            pSubframe->subframeType = DRFLAC_SUBFRAME_LPC;
            pSubframe->lpcOrder = (drflac_uint8)(type & 0x1F) + 1;
        } else if ((type & 0x08) != 0) {
            pSubframe->subframeType = DRFLAC_SUBFRAME_FIXED;
            pSubframe->lpcOrder = (drflac_uint8)(type & 0x07);
            if (pSubframe->lpcOrder > 4) {
                pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED;
                pSubframe->lpcOrder = 0;
            }
        } else {
            pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED;
        }
    }
    if (pSubframe->subframeType == DRFLAC_SUBFRAME_RESERVED) {
        return DRFLAC_FALSE;
    }
    pSubframe->wastedBitsPerSample = 0;
    if ((header & 0x01) == 1) {
        unsigned int wastedBitsPerSample;
        if (!drflac__seek_past_next_set_bit(bs, &wastedBitsPerSample)) {
            return DRFLAC_FALSE;
        }
        pSubframe->wastedBitsPerSample = (drflac_uint8)wastedBitsPerSample + 1;
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, drflac_int32* pDecodedSamplesOut)
{
    drflac_subframe* pSubframe;
    drflac_uint32 subframeBitsPerSample;
    DRFLAC_ASSERT(bs != NULL);
    DRFLAC_ASSERT(frame != NULL);
    pSubframe = frame->subframes + subframeIndex;
    if (!drflac__read_subframe_header(bs, pSubframe)) {
        return DRFLAC_FALSE;
    }
    subframeBitsPerSample = frame->header.bitsPerSample;
    if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
        subframeBitsPerSample += 1;
    } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
        subframeBitsPerSample += 1;
    }
    if (subframeBitsPerSample > 32) {
        return DRFLAC_FALSE;
    }
    if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
        return DRFLAC_FALSE;
    }
    subframeBitsPerSample -= pSubframe->wastedBitsPerSample;
    pSubframe->pSamplesS32 = pDecodedSamplesOut;
    switch (pSubframe->subframeType)
    {
        case DRFLAC_SUBFRAME_CONSTANT:
        {
            drflac__decode_samples__constant(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
        } break;
        case DRFLAC_SUBFRAME_VERBATIM:
        {
            drflac__decode_samples__verbatim(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
        } break;
        case DRFLAC_SUBFRAME_FIXED:
        {
            drflac__decode_samples__fixed(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
        } break;
        case DRFLAC_SUBFRAME_LPC:
        {
            drflac__decode_samples__lpc(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
        } break;
        default: return DRFLAC_FALSE;
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex)
{
    drflac_subframe* pSubframe;
    drflac_uint32 subframeBitsPerSample;
    DRFLAC_ASSERT(bs != NULL);
    DRFLAC_ASSERT(frame != NULL);
    pSubframe = frame->subframes + subframeIndex;
    if (!drflac__read_subframe_header(bs, pSubframe)) {
        return DRFLAC_FALSE;
    }
    subframeBitsPerSample = frame->header.bitsPerSample;
    if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
        subframeBitsPerSample += 1;
    } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
        subframeBitsPerSample += 1;
    }
    if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
        return DRFLAC_FALSE;
    }
    subframeBitsPerSample -= pSubframe->wastedBitsPerSample;
    pSubframe->pSamplesS32 = NULL;
    switch (pSubframe->subframeType)
    {
        case DRFLAC_SUBFRAME_CONSTANT:
        {
            if (!drflac__seek_bits(bs, subframeBitsPerSample)) {
                return DRFLAC_FALSE;
            }
        } break;
        case DRFLAC_SUBFRAME_VERBATIM:
        {
            unsigned int bitsToSeek = frame->header.blockSizeInPCMFrames * subframeBitsPerSample;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }
        } break;
        case DRFLAC_SUBFRAME_FIXED:
        {
            unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }
            if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
                return DRFLAC_FALSE;
            }
        } break;
        case DRFLAC_SUBFRAME_LPC:
        {
            drflac_uint8 lpcPrecision;
            unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }
            if (!drflac__read_uint8(bs, 4, &lpcPrecision)) {
                return DRFLAC_FALSE;
            }
            if (lpcPrecision == 15) {
                return DRFLAC_FALSE;
            }
            lpcPrecision += 1;
            bitsToSeek = (pSubframe->lpcOrder * lpcPrecision) + 5;
            if (!drflac__seek_bits(bs, bitsToSeek)) {
                return DRFLAC_FALSE;
            }
            if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
                return DRFLAC_FALSE;
            }
        } break;
        default: return DRFLAC_FALSE;
    }
    return DRFLAC_TRUE;
}
static DRFLAC_INLINE drflac_uint8 drflac__get_channel_count_from_channel_assignment(drflac_int8 channelAssignment)
{
    drflac_uint8 lookup[] = {1, 2, 3, 4, 5, 6, 7, 8, 2, 2, 2};
    DRFLAC_ASSERT(channelAssignment <= 10);
    return lookup[channelAssignment];
}
static drflac_result drflac__decode_flac_frame(drflac* pFlac)
{
    int channelCount;
    int i;
    drflac_uint8 paddingSizeInBits;
    drflac_uint16 desiredCRC16;
#ifndef DR_FLAC_NO_CRC
    drflac_uint16 actualCRC16;
#endif
    DRFLAC_ZERO_MEMORY(pFlac->currentFLACFrame.subframes, sizeof(pFlac->currentFLACFrame.subframes));
    if (pFlac->currentFLACFrame.header.blockSizeInPCMFrames > pFlac->maxBlockSizeInPCMFrames) {
        return DRFLAC_ERROR;
    }
    channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
    if (channelCount != (int)pFlac->channels) {
        return DRFLAC_ERROR;
    }
    for (i = 0; i < channelCount; ++i) {
        if (!drflac__decode_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i, pFlac->pDecodedSamples + (pFlac->currentFLACFrame.header.blockSizeInPCMFrames * i))) {
            return DRFLAC_ERROR;
        }
    }
    paddingSizeInBits = (drflac_uint8)(DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7);
    if (paddingSizeInBits > 0) {
        drflac_uint8 padding = 0;
        if (!drflac__read_uint8(&pFlac->bs, paddingSizeInBits, &padding)) {
            return DRFLAC_AT_END;
        }
    }

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        return DRFLAC_AT_END;
    }
#ifndef DR_FLAC_NO_CRC
    if (actualCRC16 != desiredCRC16) {
        return DRFLAC_CRC_MISMATCH;
    }
#endif
    pFlac->currentFLACFrame.pcmFramesRemaining = pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
    return DRFLAC_SUCCESS;
}
static drflac_result drflac__seek_flac_frame(drflac* pFlac)
{
    int channelCount;
    int i;
    drflac_uint16 desiredCRC16;
#ifndef DR_FLAC_NO_CRC
    drflac_uint16 actualCRC16;
#endif
    channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
    for (i = 0; i < channelCount; ++i) {
        if (!drflac__seek_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i)) {
            return DRFLAC_ERROR;
        }
    }
    if (!drflac__seek_bits(&pFlac->bs, DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7)) {
        return DRFLAC_ERROR;
    }
#ifndef DR_FLAC_NO_CRC
    actualCRC16 = drflac__flush_crc16(&pFlac->bs);
#endif
    if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) {
        return DRFLAC_AT_END;
    }
#ifndef DR_FLAC_NO_CRC
    if (actualCRC16 != desiredCRC16) {
        return DRFLAC_CRC_MISMATCH;
    }
#endif
    return DRFLAC_SUCCESS;
}
static drflac_bool32 drflac__read_and_decode_next_flac_frame(drflac* pFlac)
{
    DRFLAC_ASSERT(pFlac != NULL);
    for (;;) {
        drflac_result result;
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
        result = drflac__decode_flac_frame(pFlac);
        if (result != DRFLAC_SUCCESS) {
            if (result == DRFLAC_CRC_MISMATCH) {
                continue;
            } else {
                return DRFLAC_FALSE;
            }
        }
        return DRFLAC_TRUE;
    }
}
static void drflac__get_pcm_frame_range_of_current_flac_frame(drflac* pFlac, drflac_uint64* pFirstPCMFrame, drflac_uint64* pLastPCMFrame)
{
    drflac_uint64 firstPCMFrame;
    drflac_uint64 lastPCMFrame;
    DRFLAC_ASSERT(pFlac != NULL);
    firstPCMFrame = pFlac->currentFLACFrame.header.pcmFrameNumber;
    if (firstPCMFrame == 0) {
        firstPCMFrame = ((drflac_uint64)pFlac->currentFLACFrame.header.flacFrameNumber) * pFlac->maxBlockSizeInPCMFrames;
    }
    lastPCMFrame = firstPCMFrame + pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
    if (lastPCMFrame > 0) {
        lastPCMFrame -= 1;
    }
    if (pFirstPCMFrame) {
        *pFirstPCMFrame = firstPCMFrame;
    }
    if (pLastPCMFrame) {
        *pLastPCMFrame = lastPCMFrame;
    }
}
static drflac_bool32 drflac__seek_to_first_frame(drflac* pFlac)
{
    drflac_bool32 result;
    DRFLAC_ASSERT(pFlac != NULL);
    result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes);
    DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
    pFlac->currentPCMFrame = 0;
    return result;
}
static DRFLAC_INLINE drflac_result drflac__seek_to_next_flac_frame(drflac* pFlac)
{
    DRFLAC_ASSERT(pFlac != NULL);
    return drflac__seek_flac_frame(pFlac);
}
static drflac_uint64 drflac__seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 pcmFramesToSeek)
{
    drflac_uint64 pcmFramesRead = 0;
    while (pcmFramesToSeek > 0) {
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;
            }
        } else {
            if (pFlac->currentFLACFrame.pcmFramesRemaining > pcmFramesToSeek) {
                pcmFramesRead   += pcmFramesToSeek;
                pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)pcmFramesToSeek;
                pcmFramesToSeek  = 0;
            } else {
                pcmFramesRead   += pFlac->currentFLACFrame.pcmFramesRemaining;
                pcmFramesToSeek -= pFlac->currentFLACFrame.pcmFramesRemaining;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
            }
        }
    }
    pFlac->currentPCMFrame += pcmFramesRead;
    return pcmFramesRead;
}
static drflac_bool32 drflac__seek_to_pcm_frame__brute_force(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_bool32 isMidFrame = DRFLAC_FALSE;
    drflac_uint64 runningPCMFrameCount;
    DRFLAC_ASSERT(pFlac != NULL);
    if (pcmFrameIndex >= pFlac->currentPCMFrame) {
        runningPCMFrameCount = pFlac->currentPCMFrame;
        if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                return DRFLAC_FALSE;
            }
        } else {
            isMidFrame = DRFLAC_TRUE;
        }
    } else {
        runningPCMFrameCount = 0;
        if (!drflac__seek_to_first_frame(pFlac)) {
            return DRFLAC_FALSE;
        }
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }
    for (;;) {
        drflac_uint64 pcmFrameCountInThisFLACFrame;
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
        drflac_uint64 lastPCMFrameInFLACFrame = 0;
        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
        pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
            drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;
            if (!isMidFrame) {
                drflac_result result = drflac__decode_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
            }
        } else {
            if (!isMidFrame) {
                drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
                isMidFrame = DRFLAC_FALSE;
            }
            if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
                return DRFLAC_TRUE;
            }
        }
    next_iteration:
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }
}
#if !defined(DR_FLAC_NO_CRC)
#define DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO 0.6f
static drflac_bool32 drflac__seek_to_approximate_flac_frame_to_byte(drflac* pFlac, drflac_uint64 targetByte, drflac_uint64 rangeLo, drflac_uint64 rangeHi, drflac_uint64* pLastSuccessfulSeekOffset)
{
    DRFLAC_ASSERT(pFlac != NULL);
    DRFLAC_ASSERT(pLastSuccessfulSeekOffset != NULL);
    DRFLAC_ASSERT(targetByte >= rangeLo);
    DRFLAC_ASSERT(targetByte <= rangeHi);
    *pLastSuccessfulSeekOffset = pFlac->firstFLACFramePosInBytes;
    for (;;) {
        drflac_uint64 lastTargetByte = targetByte;
        if (!drflac__seek_to_byte(&pFlac->bs, targetByte)) {
            if (targetByte == 0) {
                drflac__seek_to_first_frame(pFlac);
                return DRFLAC_FALSE;
            }
            targetByte = rangeLo + ((rangeHi - rangeLo)/2);
            rangeHi = targetByte;
        } else {
            DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
#if 1
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                targetByte = rangeLo + ((rangeHi - rangeLo)/2);
                rangeHi = targetByte;
            } else {
                break;
            }
#else
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                targetByte = rangeLo + ((rangeHi - rangeLo)/2);
                rangeHi = targetByte;
            } else {
                break;
            }
#endif
        }
        if(targetByte == lastTargetByte) {
            return DRFLAC_FALSE;
        }
    }
    drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);
    DRFLAC_ASSERT(targetByte <= rangeHi);
    *pLastSuccessfulSeekOffset = targetByte;
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 offset)
{
#if 0
    if (drflac__decode_flac_frame(pFlac) != DRFLAC_SUCCESS) {
        if (drflac__read_and_decode_next_flac_frame(pFlac) == DRFLAC_FALSE) {
            return DRFLAC_FALSE;
        }
    }
#endif
    return drflac__seek_forward_by_pcm_frames(pFlac, offset) == offset;
}
static drflac_bool32 drflac__seek_to_pcm_frame__binary_search_internal(drflac* pFlac, drflac_uint64 pcmFrameIndex, drflac_uint64 byteRangeLo, drflac_uint64 byteRangeHi)
{
    drflac_uint64 targetByte;
    drflac_uint64 pcmRangeLo = pFlac->totalPCMFrameCount;
    drflac_uint64 pcmRangeHi = 0;
    drflac_uint64 lastSuccessfulSeekOffset = (drflac_uint64)-1;
    drflac_uint64 closestSeekOffsetBeforeTargetPCMFrame = byteRangeLo;
    drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
    targetByte = byteRangeLo + (drflac_uint64)(((drflac_int64)((pcmFrameIndex - pFlac->currentPCMFrame) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO);
    if (targetByte > byteRangeHi) {
        targetByte = byteRangeHi;
    }
    for (;;) {
        if (drflac__seek_to_approximate_flac_frame_to_byte(pFlac, targetByte, byteRangeLo, byteRangeHi, &lastSuccessfulSeekOffset)) {
            drflac_uint64 newPCMRangeLo;
            drflac_uint64 newPCMRangeHi;
            drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &newPCMRangeLo, &newPCMRangeHi);
            if (pcmRangeLo == newPCMRangeLo) {
                if (!drflac__seek_to_approximate_flac_frame_to_byte(pFlac, closestSeekOffsetBeforeTargetPCMFrame, closestSeekOffsetBeforeTargetPCMFrame, byteRangeHi, &lastSuccessfulSeekOffset)) {
                    break;
                }
                if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
                    return DRFLAC_TRUE;
                } else {
                    break;
                }
            }
            pcmRangeLo = newPCMRangeLo;
            pcmRangeHi = newPCMRangeHi;
            if (pcmRangeLo <= pcmFrameIndex && pcmRangeHi >= pcmFrameIndex) {
                if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame) ) {
                    return DRFLAC_TRUE;
                } else {
                    break;
                }
            } else {
                const float approxCompressionRatio = (drflac_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / ((drflac_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0f);
                if (pcmRangeLo > pcmFrameIndex) {
                    byteRangeHi = lastSuccessfulSeekOffset;
                    if (byteRangeLo > byteRangeHi) {
                        byteRangeLo = byteRangeHi;
                    }
                    targetByte = byteRangeLo + ((byteRangeHi - byteRangeLo) / 2);
                    if (targetByte < byteRangeLo) {
                        targetByte = byteRangeLo;
                    }
                } else  {
                    if ((pcmFrameIndex - pcmRangeLo) < seekForwardThreshold) {
                        if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
                            return DRFLAC_TRUE;
                        } else {
                            break;
                        }
                    } else {
                        byteRangeLo = lastSuccessfulSeekOffset;
                        if (byteRangeHi < byteRangeLo) {
                            byteRangeHi = byteRangeLo;
                        }
                        targetByte = lastSuccessfulSeekOffset + (drflac_uint64)(((drflac_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * approxCompressionRatio);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

                        if (closestSeekOffsetBeforeTargetPCMFrame < lastSuccessfulSeekOffset) {
                            closestSeekOffsetBeforeTargetPCMFrame = lastSuccessfulSeekOffset;
                        }
                    }
                }
            }
        } else {
            break;
        }
    }
    drflac__seek_to_first_frame(pFlac);
    return DRFLAC_FALSE;
}
static drflac_bool32 drflac__seek_to_pcm_frame__binary_search(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_uint64 byteRangeLo;
    drflac_uint64 byteRangeHi;
    drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
    if (drflac__seek_to_first_frame(pFlac) == DRFLAC_FALSE) {
        return DRFLAC_FALSE;
    }
    if (pcmFrameIndex < seekForwardThreshold) {
        return drflac__seek_forward_by_pcm_frames(pFlac, pcmFrameIndex) == pcmFrameIndex;
    }
    byteRangeLo = pFlac->firstFLACFramePosInBytes;
    byteRangeHi = pFlac->firstFLACFramePosInBytes + (drflac_uint64)((drflac_int64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample)/8.0f);
    return drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi);
}
#endif
static drflac_bool32 drflac__seek_to_pcm_frame__seek_table(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_uint32 iClosestSeekpoint = 0;
    drflac_bool32 isMidFrame = DRFLAC_FALSE;
    drflac_uint64 runningPCMFrameCount;
    drflac_uint32 iSeekpoint;
    DRFLAC_ASSERT(pFlac != NULL);
    if (pFlac->pSeekpoints == NULL || pFlac->seekpointCount == 0) {
        return DRFLAC_FALSE;
    }
    if (pFlac->pSeekpoints[0].firstPCMFrame > pcmFrameIndex) {

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        if (iClosestSeekpoint < pFlac->seekpointCount-1) {
            drflac_uint32 iNextSeekpoint = iClosestSeekpoint + 1;
            if (pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset >= pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset || pFlac->pSeekpoints[iNextSeekpoint].pcmFrameCount == 0) {
                return DRFLAC_FALSE;
            }
            if (pFlac->pSeekpoints[iNextSeekpoint].firstPCMFrame != (((drflac_uint64)0xFFFFFFFF << 32) | 0xFFFFFFFF)) {
                byteRangeHi = pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset - 1;
            }
        }
        if (drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
            if (drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);
                if (drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi)) {
                    return DRFLAC_TRUE;
                }
            }
        }
    }
#endif
    if (pcmFrameIndex >= pFlac->currentPCMFrame && pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame <= pFlac->currentPCMFrame) {
        runningPCMFrameCount = pFlac->currentPCMFrame;
        if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                return DRFLAC_FALSE;
            }
        } else {
            isMidFrame = DRFLAC_TRUE;
        }
    } else {
        runningPCMFrameCount = pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame;
        if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
            return DRFLAC_FALSE;
        }
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }
    for (;;) {
        drflac_uint64 pcmFrameCountInThisFLACFrame;
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
        drflac_uint64 lastPCMFrameInFLACFrame = 0;
        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
        pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
            drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;
            if (!isMidFrame) {
                drflac_result result = drflac__decode_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
            }
        } else {
            if (!isMidFrame) {
                drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
                if (result == DRFLAC_SUCCESS) {
                    runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
                } else {
                    if (result == DRFLAC_CRC_MISMATCH) {
                        goto next_iteration;
                    } else {
                        return DRFLAC_FALSE;
                    }
                }
            } else {
                runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
                isMidFrame = DRFLAC_FALSE;
            }
            if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
                return DRFLAC_TRUE;
            }
        }
    next_iteration:
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
    }
}
#ifndef DR_FLAC_NO_OGG
typedef struct
{
    drflac_uint8 capturePattern[4];
    drflac_uint8 structureVersion;
    drflac_uint8 headerType;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    void* pUserDataMD;
    drflac_uint32 sampleRate;
    drflac_uint8  channels;
    drflac_uint8  bitsPerSample;
    drflac_uint64 totalPCMFrameCount;
    drflac_uint16 maxBlockSizeInPCMFrames;
    drflac_uint64 runningFilePos;
    drflac_bool32 hasStreamInfoBlock;
    drflac_bool32 hasMetadataBlocks;
    drflac_bs bs;
    drflac_frame_header firstFrameHeader;
#ifndef DR_FLAC_NO_OGG
    drflac_uint32 oggSerial;
    drflac_uint64 oggFirstBytePos;
    drflac_ogg_page_header oggBosHeader;
#endif
} drflac_init_info;
static DRFLAC_INLINE void drflac__decode_block_header(drflac_uint32 blockHeader, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize)
{
    blockHeader = drflac__be2host_32(blockHeader);
    *isLastBlock = (drflac_uint8)((blockHeader & 0x80000000UL) >> 31);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    *blockSize = 0;
    if (onRead(pUserData, &blockHeader, 4) != 4) {
        return DRFLAC_FALSE;
    }
    drflac__decode_block_header(blockHeader, isLastBlock, blockType, blockSize);
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo)
{
    drflac_uint32 blockSizes;
    drflac_uint64 frameSizes = 0;
    drflac_uint64 importantProps;
    drflac_uint8 md5[16];
    if (onRead(pUserData, &blockSizes, 4) != 4) {
        return DRFLAC_FALSE;
    }
    if (onRead(pUserData, &frameSizes, 6) != 6) {
        return DRFLAC_FALSE;
    }
    if (onRead(pUserData, &importantProps, 8) != 8) {
        return DRFLAC_FALSE;
    }
    if (onRead(pUserData, md5, sizeof(md5)) != sizeof(md5)) {
        return DRFLAC_FALSE;
    }
    blockSizes     = drflac__be2host_32(blockSizes);
    frameSizes     = drflac__be2host_64(frameSizes);
    importantProps = drflac__be2host_64(importantProps);
    pStreamInfo->minBlockSizeInPCMFrames = (drflac_uint16)((blockSizes & 0xFFFF0000) >> 16);
    pStreamInfo->maxBlockSizeInPCMFrames = (drflac_uint16) (blockSizes & 0x0000FFFF);
    pStreamInfo->minFrameSizeInPCMFrames = (drflac_uint32)((frameSizes     &  (((drflac_uint64)0x00FFFFFF << 16) << 24)) >> 40);
    pStreamInfo->maxFrameSizeInPCMFrames = (drflac_uint32)((frameSizes     &  (((drflac_uint64)0x00FFFFFF << 16) <<  0)) >> 16);
    pStreamInfo->sampleRate              = (drflac_uint32)((importantProps &  (((drflac_uint64)0x000FFFFF << 16) << 28)) >> 44);
    pStreamInfo->channels                = (drflac_uint8 )((importantProps &  (((drflac_uint64)0x0000000E << 16) << 24)) >> 41) + 1;
    pStreamInfo->bitsPerSample           = (drflac_uint8 )((importantProps &  (((drflac_uint64)0x0000001F << 16) << 20)) >> 36) + 1;
    pStreamInfo->totalPCMFrameCount      =                ((importantProps & ((((drflac_uint64)0x0000000F << 16) << 16) | 0xFFFFFFFF)));
    DRFLAC_COPY_MEMORY(pStreamInfo->md5, md5, sizeof(md5));
    return DRFLAC_TRUE;
}
static void* drflac__malloc_default(size_t sz, void* pUserData)
{
    (void)pUserData;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    pInit->container = drflac_container_native;
    if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
        return DRFLAC_FALSE;
    }
    if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) {
        if (!relaxed) {
            return DRFLAC_FALSE;
        } else {
            pInit->hasStreamInfoBlock = DRFLAC_FALSE;
            pInit->hasMetadataBlocks  = DRFLAC_FALSE;
            if (!drflac__read_next_flac_frame_header(&pInit->bs, 0, &pInit->firstFrameHeader)) {
                return DRFLAC_FALSE;
            }
            if (pInit->firstFrameHeader.bitsPerSample == 0) {
                return DRFLAC_FALSE;
            }
            pInit->sampleRate              = pInit->firstFrameHeader.sampleRate;
            pInit->channels                = drflac__get_channel_count_from_channel_assignment(pInit->firstFrameHeader.channelAssignment);
            pInit->bitsPerSample           = pInit->firstFrameHeader.bitsPerSample;
            pInit->maxBlockSizeInPCMFrames = 65535;
            return DRFLAC_TRUE;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

                return DRFLAC_FALSE;
            }
            if ((oggbs->currentPageHeader.headerType & 0x01) == 0) {
                return DRFLAC_TRUE;
            }
        } else {
            return DRFLAC_TRUE;
        }
    }
}
static drflac_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs)
{
    return drflac_oggbs__seek_to_next_packet(oggbs);
}
#endif
static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytesToRead)
{
    drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
    drflac_uint8* pRunningBufferOut = (drflac_uint8*)bufferOut;
    size_t bytesRead = 0;
    DRFLAC_ASSERT(oggbs != NULL);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            bytesSeeked += (int)oggbs->bytesRemainingInPage;
            oggbs->bytesRemainingInPage = 0;
        }
        DRFLAC_ASSERT(bytesRemainingToSeek > 0);
        if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
            return DRFLAC_FALSE;
        }
    }
    return DRFLAC_TRUE;
}
static drflac_bool32 drflac_ogg__seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
    drflac_uint64 originalBytePos;
    drflac_uint64 runningGranulePosition;
    drflac_uint64 runningFrameBytePos;
    drflac_uint64 runningPCMFrameCount;
    DRFLAC_ASSERT(oggbs != NULL);
    originalBytePos = oggbs->currentBytePos;
    if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes)) {
        return DRFLAC_FALSE;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        return DRFLAC_FALSE;
    }
    if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
        return DRFLAC_FALSE;
    }
    runningPCMFrameCount = runningGranulePosition;
    for (;;) {
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
        drflac_uint64 lastPCMFrameInFLACFrame = 0;
        drflac_uint64 pcmFrameCountInThisFrame;
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
            return DRFLAC_FALSE;
        }
        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
        pcmFrameCountInThisFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
        if (pcmFrameIndex == pFlac->totalPCMFrameCount && (runningPCMFrameCount + pcmFrameCountInThisFrame) == pFlac->totalPCMFrameCount) {
            drflac_result result = drflac__decode_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                pFlac->currentPCMFrame = pcmFrameIndex;
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
                return DRFLAC_TRUE;
            } else {
                return DRFLAC_FALSE;
            }
        }
        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFrame)) {
            drflac_result result = drflac__decode_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                drflac_uint64 pcmFramesToDecode = (size_t)(pcmFrameIndex - runningPCMFrameCount);
                if (pcmFramesToDecode == 0) {
                    return DRFLAC_TRUE;
                }
                pFlac->currentPCMFrame = runningPCMFrameCount;
                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
            } else {
                if (result == DRFLAC_CRC_MISMATCH) {
                    continue;
                } else {
                    return DRFLAC_FALSE;
                }
            }
        } else {
            drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                runningPCMFrameCount += pcmFrameCountInThisFrame;
            } else {
                if (result == DRFLAC_CRC_MISMATCH) {
                    continue;
                } else {
                    return DRFLAC_FALSE;
                }
            }
        }

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

                }
            } else {
                pFlac->pSeekpoints = NULL;
                pFlac->seekpointCount = 0;
            }
        }
    }
    if (!init.hasStreamInfoBlock) {
        pFlac->currentFLACFrame.header = init.firstFrameHeader;
        for (;;) {
            drflac_result result = drflac__decode_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                break;
            } else {
                if (result == DRFLAC_CRC_MISMATCH) {
                    if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                        drflac__free_from_callbacks(pFlac, &allocationCallbacks);
                        return NULL;
                    }
                    continue;
                } else {
                    drflac__free_from_callbacks(pFlac, &allocationCallbacks);
                    return NULL;
                }
            }
        }

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        DRFLAC_ASSERT(pFlac->bs.onRead == drflac__on_read_ogg);
        if (oggbs->onRead == drflac__on_read_stdio) {
            fclose((FILE*)oggbs->pUserData);
        }
    }
#endif
#endif
    drflac__free_from_callbacks(pFlac, &pFlac->allocationCallbacks);
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutpu...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
        drflac_uint32 right0 = left0 - side0;
        drflac_uint32 right1 = left1 - side1;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        drflac_uint32 right3 = left3 - side3;
        pOutputSamples[i*8+0] = (drflac_int32)left0;
        pOutputSamples[i*8+1] = (drflac_int32)right0;
        pOutputSamples[i*8+2] = (drflac_int32)left1;
        pOutputSamples[i*8+3] = (drflac_int32)right1;
        pOutputSamples[i*8+4] = (drflac_int32)left2;
        pOutputSamples[i*8+5] = (drflac_int32)right2;
        pOutputSamples[i*8+6] = (drflac_int32)left3;
        pOutputSamples[i*8+7] = (drflac_int32)right3;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i right = _mm_sub_epi32(left, side);
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t left;
        uint32x4_t side;
        uint32x4_t right;
        left  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        right = vsubq_u32(left, side);
        drflac__vst2q_u32((drflac_uint32*)pOutputSamples + i*8, vzipq_u32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutp...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputS...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
        drflac_uint32 left0 = right0 + side0;
        drflac_uint32 left1 = right1 + side1;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        drflac_uint32 left3 = right3 + side3;
        pOutputSamples[i*8+0] = (drflac_int32)left0;
        pOutputSamples[i*8+1] = (drflac_int32)right0;
        pOutputSamples[i*8+2] = (drflac_int32)left1;
        pOutputSamples[i*8+3] = (drflac_int32)right1;
        pOutputSamples[i*8+4] = (drflac_int32)left2;
        pOutputSamples[i*8+5] = (drflac_int32)right2;
        pOutputSamples[i*8+6] = (drflac_int32)left3;
        pOutputSamples[i*8+7] = (drflac_int32)right3;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    for (i = 0; i < frameCount4; ++i) {
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i left  = _mm_add_epi32(right, side);
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t side;
        uint32x4_t right;
        uint32x4_t left;
        side  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        right = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        left  = vaddq_u32(right, side);
        drflac__vst2q_u32((drflac_uint32*)pOutputSamples + i*8, vzipq_u32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left;
        pOutputSamples[i*2+1] = (drflac_int32)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutput...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
        mid = (mid << 1) | (side & 0x01);
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_int32 shift = unusedBitsPerSample;
    if (shift > 0) {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);
            temp0L = (mid0 + side0) << shift;
            temp1L = (mid1 + side1) << shift;
            temp2L = (mid2 + side2) << shift;
            temp3L = (mid3 + side3) << shift;
            temp0R = (mid0 - side0) << shift;
            temp1R = (mid1 - side1) << shift;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            pOutputSamples[i*8+0] = (drflac_int32)temp0L;
            pOutputSamples[i*8+1] = (drflac_int32)temp0R;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R;
        }
    } else {
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);
            temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
            temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
            temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
            temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);
            temp0R = (drflac_uint32)((drflac_int32)(mid0 - side0) >> 1);
            temp1R = (drflac_uint32)((drflac_int32)(mid1 - side1) >> 1);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            pOutputSamples[i*8+0] = (drflac_int32)temp0L;
            pOutputSamples[i*8+1] = (drflac_int32)temp0R;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R;
        }
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
        mid = (mid << 1) | (side & 0x01);
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_int32 shift = unusedBitsPerSample;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;
            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
            left  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
            right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int32)(mid + side) >> 1;
            pOutputSamples[i*2+1] = (drflac_int32)(mid - side) >> 1;
        }
    } else {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;
            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
            left  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
            right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
        }
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_int32 shift = unusedBitsPerSample;
    int32x4_t  wbpsShift0_4;
    int32x4_t  wbpsShift1_4;
    uint32x4_t one4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
    wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
    one4         = vdupq_n_u32(1);
    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;
            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, one4));
            left  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
            right = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);
            drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int32)(mid + side) >> 1;
            pOutputSamples[i*2+1] = (drflac_int32)(mid - side) >> 1;
        }
    } else {
        int32x4_t shift4;
        shift -= 1;
        shift4 = vdupq_n_s32(shift);
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;
            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, one4));
            left  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
            right = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));
            drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
        }
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int3...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample));
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample));
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* ...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
        pOutputSamples[i*8+0] = (drflac_int32)tempL0;
        pOutputSamples[i*8+1] = (drflac_int32)tempR0;
        pOutputSamples[i*8+2] = (drflac_int32)tempL1;
        pOutputSamples[i*8+3] = (drflac_int32)tempR1;
        pOutputSamples[i*8+4] = (drflac_int32)tempL2;
        pOutputSamples[i*8+5] = (drflac_int32)tempR2;
        pOutputSamples[i*8+6] = (drflac_int32)tempL3;
        pOutputSamples[i*8+7] = (drflac_int32)tempR3;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift4_0 = vdupq_n_s32(shift0);
    int32x4_t shift4_1 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        int32x4_t left;
        int32x4_t right;
        left  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift4_0));
        right = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift4_1));
        drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputS...
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut)
{
    drflac_uint64 framesRead;
    drflac_uint32 unusedBitsPerSample;
    if (pFlac == NULL || framesToRead == 0) {
        return 0;
    }
    if (pBufferOut == NULL) {
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
    }
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;
    framesRead = 0;
    while (framesToRead > 0) {
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;
            }
        } else {
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
            drflac_uint64 frameCountThisIteration = framesToRead;
            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
            }
            if (channelCount == 2) {
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
                switch (pFlac->currentFLACFrame.header.channelAssignment)
                {
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
                    {
                        drflac_read_pcm_frames_s32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
                    {
                        drflac_read_pcm_frames_s32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
                    {
                        drflac_read_pcm_frames_s32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
                    default:
                    {
                        drflac_read_pcm_frames_s32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                }
            } else {
                drflac_uint64 i;
                for (i = 0; i < frameCountThisIteration; ++i) {
                    unsigned int j;
                    for (j = 0; j < channelCount; ++j) {
                        pBufferOut[(i*channelCount)+j] = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
                    }
                }
            }
            framesRead                += frameCountThisIteration;
            pBufferOut                += frameCountThisIteration * channelCount;
            framesToRead              -= frameCountThisIteration;
            pFlac->currentPCMFrame    += frameCountThisIteration;
            pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
        }
    }
    return framesRead;
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutpu...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 right = left - side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
        drflac_uint32 right0 = left0 - side0;
        drflac_uint32 right1 = left1 - side1;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        right3 >>= 16;
        pOutputSamples[i*8+0] = (drflac_int16)left0;
        pOutputSamples[i*8+1] = (drflac_int16)right0;
        pOutputSamples[i*8+2] = (drflac_int16)left1;
        pOutputSamples[i*8+3] = (drflac_int16)right1;
        pOutputSamples[i*8+4] = (drflac_int16)left2;
        pOutputSamples[i*8+5] = (drflac_int16)right2;
        pOutputSamples[i*8+6] = (drflac_int16)left3;
        pOutputSamples[i*8+7] = (drflac_int16)right3;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i right = _mm_sub_epi32(left, side);
        left  = _mm_srai_epi32(left,  16);
        right = _mm_srai_epi32(right, 16);
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamp...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t left;
        uint32x4_t side;
        uint32x4_t right;
        left  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        right = vsubq_u32(left, side);
        left  = vshrq_n_u32(left,  16);
        right = vshrq_n_u32(right, 16);
        drflac__vst2q_u16((drflac_uint16*)pOutputSamples + i*8, vzip_u16(vmovn_u32(left), vmovn_u32(right)));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s16__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutp...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 left  = right + side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputS...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
        drflac_uint32 left0 = right0 + side0;
        drflac_uint32 left1 = right1 + side1;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        right3 >>= 16;
        pOutputSamples[i*8+0] = (drflac_int16)left0;
        pOutputSamples[i*8+1] = (drflac_int16)right0;
        pOutputSamples[i*8+2] = (drflac_int16)left1;
        pOutputSamples[i*8+3] = (drflac_int16)right1;
        pOutputSamples[i*8+4] = (drflac_int16)left2;
        pOutputSamples[i*8+5] = (drflac_int16)right2;
        pOutputSamples[i*8+6] = (drflac_int16)left3;
        pOutputSamples[i*8+7] = (drflac_int16)right3;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    for (i = 0; i < frameCount4; ++i) {
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i left  = _mm_add_epi32(right, side);
        left  = _mm_srai_epi32(left,  16);
        right = _mm_srai_epi32(right, 16);
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4;
    int32x4_t shift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t side;
        uint32x4_t right;
        uint32x4_t left;
        side  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        right = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        left  = vaddq_u32(right, side);
        left  = vshrq_n_u32(left,  16);
        right = vshrq_n_u32(right, 16);
        drflac__vst2q_u16((drflac_uint16*)pOutputSamples + i*8, vzip_u16(vmovn_u32(left), vmovn_u32(right)));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        left  >>= 16;
        right >>= 16;
        pOutputSamples[i*2+0] = (drflac_int16)left;
        pOutputSamples[i*2+1] = (drflac_int16)right;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s16__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutput...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        drflac_uint32 mid  = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
        mid = (mid << 1) | (side & 0x01);
        pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSam...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;
    if (shift > 0) {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);
            temp0L = (mid0 + side0) << shift;
            temp1L = (mid1 + side1) << shift;
            temp2L = (mid2 + side2) << shift;
            temp3L = (mid3 + side3) << shift;
            temp0R = (mid0 - side0) << shift;
            temp1R = (mid1 - side1) << shift;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            pOutputSamples[i*8+0] = (drflac_int16)temp0L;
            pOutputSamples[i*8+1] = (drflac_int16)temp0R;
            pOutputSamples[i*8+2] = (drflac_int16)temp1L;
            pOutputSamples[i*8+3] = (drflac_int16)temp1R;
            pOutputSamples[i*8+4] = (drflac_int16)temp2L;
            pOutputSamples[i*8+5] = (drflac_int16)temp2R;
            pOutputSamples[i*8+6] = (drflac_int16)temp3L;
            pOutputSamples[i*8+7] = (drflac_int16)temp3R;
        }
    } else {
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);
            temp0L = ((drflac_int32)(mid0 + side0) >> 1);
            temp1L = ((drflac_int32)(mid1 + side1) >> 1);
            temp2L = ((drflac_int32)(mid2 + side2) >> 1);
            temp3L = ((drflac_int32)(mid3 + side3) >> 1);
            temp0R = ((drflac_int32)(mid0 - side0) >> 1);
            temp1R = ((drflac_int32)(mid1 - side1) >> 1);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            pOutputSamples[i*8+0] = (drflac_int16)temp0L;
            pOutputSamples[i*8+1] = (drflac_int16)temp0R;
            pOutputSamples[i*8+2] = (drflac_int16)temp1L;
            pOutputSamples[i*8+3] = (drflac_int16)temp1R;
            pOutputSamples[i*8+4] = (drflac_int16)temp2L;
            pOutputSamples[i*8+5] = (drflac_int16)temp2R;
            pOutputSamples[i*8+6] = (drflac_int16)temp3L;
            pOutputSamples[i*8+7] = (drflac_int16)temp3R;
        }
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
        mid = (mid << 1) | (side & 0x01);
        pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;
            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
            left  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
            right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
            left  = _mm_srai_epi32(left,  16);
            right = _mm_srai_epi32(right, 16);
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
        }
    } else {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i left;
            __m128i right;
            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
            left  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
            right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
            left  = _mm_srai_epi32(left,  16);
            right = _mm_srai_epi32(right, 16);
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
        }
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSampl...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;
    int32x4_t wbpsShift0_4;
    int32x4_t wbpsShift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
    wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;
            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
            left  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
            right = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);
            left  = vshrq_n_s32(left,  16);
            right = vshrq_n_s32(right, 16);
            drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
        }
    } else {
        int32x4_t shift4;
        shift -= 1;
        shift4 = vdupq_n_s32(shift);
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t left;
            int32x4_t right;
            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
            left  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
            right = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));
            left  = vshrq_n_s32(left,  16);
            right = vshrq_n_s32(right, 16);
            drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
            pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
        }
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s16__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int1...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) >> 16);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* ...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
        tempL0 >>= 16;
        tempL1 >>= 16;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        tempR3 >>= 16;
        pOutputSamples[i*8+0] = (drflac_int16)tempL0;
        pOutputSamples[i*8+1] = (drflac_int16)tempR0;
        pOutputSamples[i*8+2] = (drflac_int16)tempL1;
        pOutputSamples[i*8+3] = (drflac_int16)tempR1;
        pOutputSamples[i*8+4] = (drflac_int16)tempL2;
        pOutputSamples[i*8+5] = (drflac_int16)tempR2;
        pOutputSamples[i*8+6] = (drflac_int16)tempL3;
        pOutputSamples[i*8+7] = (drflac_int16)tempR3;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        left  = _mm_srai_epi32(left,  16);
        right = _mm_srai_epi32(right, 16);
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pO...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    int32x4_t shift0_4 = vdupq_n_s32(shift0);
    int32x4_t shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        int32x4_t left;
        int32x4_t right;
        left  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4));
        right = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4));
        left  = vshrq_n_s32(left,  16);
        right = vshrq_n_s32(right, 16);
        drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputS...
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_s16__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_s16__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut)
{
    drflac_uint64 framesRead;
    drflac_uint32 unusedBitsPerSample;
    if (pFlac == NULL || framesToRead == 0) {
        return 0;
    }
    if (pBufferOut == NULL) {
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
    }
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;
    framesRead = 0;
    while (framesToRead > 0) {
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;
            }
        } else {
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
            drflac_uint64 frameCountThisIteration = framesToRead;
            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
            }
            if (channelCount == 2) {
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
                switch (pFlac->currentFLACFrame.header.channelAssignment)
                {
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
                    {
                        drflac_read_pcm_frames_s16__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
                    {
                        drflac_read_pcm_frames_s16__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
                    {
                        drflac_read_pcm_frames_s16__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
                    default:
                    {
                        drflac_read_pcm_frames_s16__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                }
            } else {
                drflac_uint64 i;
                for (i = 0; i < frameCountThisIteration; ++i) {
                    unsigned int j;
                    for (j = 0; j < channelCount; ++j) {
                        drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
                        pBufferOut[(i*channelCount)+j] = (drflac_int16)(sampleS32 >> 16);
                    }
                }
            }
            framesRead                += frameCountThisIteration;
            pBufferOut                += frameCountThisIteration * channelCount;
            framesToRead              -= frameCountThisIteration;
            pFlac->currentPCMFrame    += frameCountThisIteration;
            pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
        }
    }
    return framesRead;
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSample...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (float)((drflac_int32)left  / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    float factor = 1 / 2147483648.0;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
        drflac_uint32 right0 = left0 - side0;
        drflac_uint32 right1 = left1 - side1;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        drflac_uint32 right3 = left3 - side3;
        pOutputSamples[i*8+0] = (drflac_int32)left0  * factor;
        pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
        pOutputSamples[i*8+2] = (drflac_int32)left1  * factor;
        pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
        pOutputSamples[i*8+4] = (drflac_int32)left2  * factor;
        pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
        pOutputSamples[i*8+6] = (drflac_int32)left3  * factor;
        pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left  * factor;
        pOutputSamples[i*2+1] = (drflac_int32)right * factor;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    __m128 factor;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    factor = _mm_set1_ps(1.0f / 8388608.0f);
    for (i = 0; i < frameCount4; ++i) {
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i right = _mm_sub_epi32(left, side);
        __m128 leftf  = _mm_mul_ps(_mm_cvtepi32_ps(left),  factor);
        __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);
        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    float32x4_t factor4;
    int32x4_t shift0_4;
    int32x4_t shift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    factor4  = vdupq_n_f32(1.0f / 8388608.0f);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t left;
        uint32x4_t side;
        uint32x4_t right;
        float32x4_t leftf;
        float32x4_t rightf;
        left   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        side   = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        right  = vsubq_u32(left, side);
        leftf  = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(left)),  factor4);
        rightf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(right)), factor4);
        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
        drflac_uint32 right = left - side;
        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_f32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSampl...
{
    drflac_uint64 i;
    for (i = 0; i < frameCount; ++i) {
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (float)((drflac_int32)left  / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    float factor = 1 / 2147483648.0;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
        drflac_uint32 left0 = right0 + side0;
        drflac_uint32 left1 = right1 + side1;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        drflac_uint32 left3 = right3 + side3;
        pOutputSamples[i*8+0] = (drflac_int32)left0  * factor;
        pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
        pOutputSamples[i*8+2] = (drflac_int32)left1  * factor;
        pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
        pOutputSamples[i*8+4] = (drflac_int32)left2  * factor;
        pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
        pOutputSamples[i*8+6] = (drflac_int32)left3  * factor;
        pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left  * factor;
        pOutputSamples[i*2+1] = (drflac_int32)right * factor;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    __m128 factor;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    factor = _mm_set1_ps(1.0f / 8388608.0f);
    for (i = 0; i < frameCount4; ++i) {
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        __m128i left  = _mm_add_epi32(right, side);
        __m128 leftf  = _mm_mul_ps(_mm_cvtepi32_ps(left),  factor);
        __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);
        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    float32x4_t factor4;
    int32x4_t shift0_4;
    int32x4_t shift1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    factor4  = vdupq_n_f32(1.0f / 8388608.0f);
    shift0_4 = vdupq_n_s32(shift0);
    shift1_4 = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        uint32x4_t side;
        uint32x4_t right;
        uint32x4_t left;
        float32x4_t leftf;
        float32x4_t rightf;
        side   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
        right  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
        left   = vaddq_u32(right, side);
        leftf  = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(left)),  factor4);
        rightf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(right)), factor4);
        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
        drflac_uint32 left  = right + side;
        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_f32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        drflac_uint32 mid  = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
        mid = (mid << 1) | (side & 0x01);
        pOutputSamples[i*2+0] = (float)((((drflac_int32)(mid + side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((((drflac_int32)(mid - side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample;
    float factor = 1 / 2147483648.0;
    if (shift > 0) {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);
            temp0L = (mid0 + side0) << shift;
            temp1L = (mid1 + side1) << shift;
            temp2L = (mid2 + side2) << shift;
            temp3L = (mid3 + side3) << shift;
            temp0R = (mid0 - side0) << shift;
            temp1R = (mid1 - side1) << shift;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            pOutputSamples[i*8+0] = (drflac_int32)temp0L * factor;
            pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
        }
    } else {
        for (i = 0; i < frameCount4; ++i) {
            drflac_uint32 temp0L;
            drflac_uint32 temp1L;
            drflac_uint32 temp2L;
            drflac_uint32 temp3L;
            drflac_uint32 temp0R;
            drflac_uint32 temp1R;
            drflac_uint32 temp2R;
            drflac_uint32 temp3R;
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid0 = (mid0 << 1) | (side0 & 0x01);
            mid1 = (mid1 << 1) | (side1 & 0x01);
            mid2 = (mid2 << 1) | (side2 & 0x01);
            mid3 = (mid3 << 1) | (side3 & 0x01);
            temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
            temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
            temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
            temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);
            temp0R = (drflac_uint32)((drflac_int32)(mid0 - side0) >> 1);
            temp1R = (drflac_uint32)((drflac_int32)(mid1 - side1) >> 1);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            pOutputSamples[i*8+0] = (drflac_int32)temp0L * factor;
            pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
            pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
            pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
            pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
            pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
            pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
            pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
        }
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
        mid = (mid << 1) | (side & 0x01);
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) * factor;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample - 8;
    float factor;
    __m128 factor128;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    factor = 1.0f / 8388608.0f;
    factor128 = _mm_set1_ps(factor);
    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i tempL;
            __m128i tempR;
            __m128  leftf;
            __m128  rightf;
            mid    = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
            mid    = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
            tempL  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
            tempR  = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
            leftf  = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
            rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);
            _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
            _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
            pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
        }
    } else {
        shift -= 1;
        for (i = 0; i < frameCount4; ++i) {
            __m128i mid;
            __m128i side;
            __m128i tempL;
            __m128i tempR;
            __m128 leftf;
            __m128 rightf;
            mid    = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
            side   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
            mid    = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
            tempL  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
            tempR  = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
            leftf  = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
            rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);
            _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
            _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
        }
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift = unusedBitsPerSample - 8;
    float factor;
    float32x4_t factor4;
    int32x4_t shift4;
    int32x4_t wbps0_4;
    int32x4_t wbps1_4;
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
    factor  = 1.0f / 8388608.0f;
    factor4 = vdupq_n_f32(factor);
    wbps0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
    wbps1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
    if (shift == 0) {
        for (i = 0; i < frameCount4; ++i) {
            int32x4_t lefti;
            int32x4_t righti;
            float32x4_t leftf;
            float32x4_t rightf;
            uint32x4_t mid  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbps0_4);
            uint32x4_t side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbps1_4);
            mid    = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
            lefti  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
            righti = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);
            leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
            rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
            drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
            pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
        }
    } else {
        shift -= 1;
        shift4 = vdupq_n_s32(shift);
        for (i = 0; i < frameCount4; ++i) {
            uint32x4_t mid;
            uint32x4_t side;
            int32x4_t lefti;
            int32x4_t righti;
            float32x4_t leftf;
            float32x4_t rightf;
            mid    = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbps0_4);
            side   = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbps1_4);
            mid    = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
            lefti  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
            righti = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));
            leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
            rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
            drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
        }
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
            mid = (mid << 1) | (side & 0x01);
            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
        }
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_f32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
#if 0
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOut...
{
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (float)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) / 2147483648.0);
        pOutputSamples[i*2+1] = (float)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) / 2147483648.0);
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutput...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
    float factor = 1 / 2147483648.0;
    for (i = 0; i < frameCount4; ++i) {
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
        pOutputSamples[i*8+0] = (drflac_int32)tempL0 * factor;
        pOutputSamples[i*8+1] = (drflac_int32)tempR0 * factor;
        pOutputSamples[i*8+2] = (drflac_int32)tempL1 * factor;
        pOutputSamples[i*8+3] = (drflac_int32)tempR1 * factor;
        pOutputSamples[i*8+4] = (drflac_int32)tempL2 * factor;
        pOutputSamples[i*8+5] = (drflac_int32)tempR2 * factor;
        pOutputSamples[i*8+6] = (drflac_int32)tempL3 * factor;
        pOutputSamples[i*8+7] = (drflac_int32)tempR3 * factor;
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
    }
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    float factor = 1.0f / 8388608.0f;
    __m128 factor128 = _mm_set1_ps(factor);
    for (i = 0; i < frameCount4; ++i) {
        __m128i lefti;
        __m128i righti;
        __m128 leftf;
        __m128 rightf;
        lefti  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
        righti = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
        leftf  = _mm_mul_ps(_mm_cvtepi32_ps(lefti),  factor128);
        rightf = _mm_mul_ps(_mm_cvtepi32_ps(righti), factor128);
        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
    }
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSa...
{
    drflac_uint64 i;
    drflac_uint64 frameCount4 = frameCount >> 2;
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
    float factor = 1.0f / 8388608.0f;
    float32x4_t factor4 = vdupq_n_f32(factor);
    int32x4_t shift0_4  = vdupq_n_s32(shift0);
    int32x4_t shift1_4  = vdupq_n_s32(shift1);
    for (i = 0; i < frameCount4; ++i) {
        int32x4_t lefti;
        int32x4_t righti;
        float32x4_t leftf;
        float32x4_t rightf;
        lefti  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4));
        righti = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4));
        leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
        rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
    }
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
    }
}
#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#if defined(DRFLAC_SUPPORT_SSE2)
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#elif defined(DRFLAC_SUPPORT_NEON)
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
        drflac_read_pcm_frames_f32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
    } else
#endif
    {
#if 0
        drflac_read_pcm_frames_f32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#else
        drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#endif
    }
}
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut)
{
    drflac_uint64 framesRead;
    drflac_uint32 unusedBitsPerSample;
    if (pFlac == NULL || framesToRead == 0) {
        return 0;
    }
    if (pBufferOut == NULL) {
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
    }
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;
    framesRead = 0;
    while (framesToRead > 0) {
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
                break;
            }
        } else {
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
            drflac_uint64 frameCountThisIteration = framesToRead;
            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
            }
            if (channelCount == 2) {
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
                switch (pFlac->currentFLACFrame.header.channelAssignment)
                {
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
                    {
                        drflac_read_pcm_frames_f32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
                    {
                        drflac_read_pcm_frames_f32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
                    {
                        drflac_read_pcm_frames_f32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
                    default:
                    {
                        drflac_read_pcm_frames_f32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
                    } break;
                }
            } else {
                drflac_uint64 i;
                for (i = 0; i < frameCountThisIteration; ++i) {
                    unsigned int j;
                    for (j = 0; j < channelCount; ++j) {
                        drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
                        pBufferOut[(i*channelCount)+j] = (float)(sampleS32 / 2147483648.0);
                    }
                }
            }
            framesRead                += frameCountThisIteration;
            pBufferOut                += frameCountThisIteration * channelCount;
            framesToRead              -= frameCountThisIteration;
            pFlac->currentPCMFrame    += frameCountThisIteration;
            pFlac->currentFLACFrame.pcmFramesRemaining -= (unsigned int)frameCountThisIteration;
        }
    }
    return framesRead;
}
DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
{
    if (pFlac == NULL) {
        return DRFLAC_FALSE;
    }
    if (pFlac->currentPCMFrame == pcmFrameIndex) {
        return DRFLAC_TRUE;
    }
    if (pFlac->firstFLACFramePosInBytes == 0) {
        return DRFLAC_FALSE;
    }
    if (pcmFrameIndex == 0) {
        pFlac->currentPCMFrame = 0;
        return drflac__seek_to_first_frame(pFlac);
    } else {
        drflac_bool32 wasSuccessful = DRFLAC_FALSE;
        drflac_uint64 originalPCMFrame = pFlac->currentPCMFrame;
        if (pcmFrameIndex > pFlac->totalPCMFrameCount) {
            pcmFrameIndex = pFlac->totalPCMFrameCount;
        }
        if (pcmFrameIndex > pFlac->currentPCMFrame) {
            drflac_uint32 offset = (drflac_uint32)(pcmFrameIndex - pFlac->currentPCMFrame);
            if (pFlac->currentFLACFrame.pcmFramesRemaining >  offset) {
                pFlac->currentFLACFrame.pcmFramesRemaining -= offset;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            drflac_uint32 currentFLACFramePCMFramesConsumed = currentFLACFramePCMFrameCount - pFlac->currentFLACFrame.pcmFramesRemaining;
            if (currentFLACFramePCMFramesConsumed > offsetAbs) {
                pFlac->currentFLACFrame.pcmFramesRemaining += offsetAbs;
                pFlac->currentPCMFrame = pcmFrameIndex;
                return DRFLAC_TRUE;
            }
        }
#ifndef DR_FLAC_NO_OGG
        if (pFlac->container == drflac_container_ogg)
        {
            wasSuccessful = drflac_ogg__seek_to_pcm_frame(pFlac, pcmFrameIndex);
        }
        else
#endif
        {
            if (!pFlac->_noSeekTableSeek) {
                wasSuccessful = drflac__seek_to_pcm_frame__seek_table(pFlac, pcmFrameIndex);
            }
#if !defined(DR_FLAC_NO_CRC)
            if (!wasSuccessful && !pFlac->_noBinarySearchSeek && pFlac->totalPCMFrameCount > 0) {
                wasSuccessful = drflac__seek_to_pcm_frame__binary_search(pFlac, pcmFrameIndex);
            }
#endif
            if (!wasSuccessful && !pFlac->_noBruteForceSeek) {
                wasSuccessful = drflac__seek_to_pcm_frame__brute_force(pFlac, pcmFrameIndex);
            }
        }
        if (wasSuccessful) {
            pFlac->currentPCMFrame = pcmFrameIndex;
        } else {
            if (drflac_seek_to_pcm_frame(pFlac, originalPCMFrame) == DRFLAC_FALSE) {
                drflac_seek_to_pcm_frame(pFlac, 0);
            }
        }
        return wasSuccessful;
    }
}
#if defined(SIZE_MAX)
    #define DRFLAC_SIZE_MAX  SIZE_MAX
#else
    #if defined(DRFLAC_64BIT)
        #define DRFLAC_SIZE_MAX  ((drflac_uint64)0xFFFFFFFFFFFFFFFF)

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    if (totalPCMFrameCount == 0) {                                                                                                                                  \
        type buffer[4096];                                                                                                                                          \
        drflac_uint64 pcmFramesRead;                                                                                                                                \
        size_t sampleDataBufferSize = sizeof(buffer);                                                                                                               \
                                                                                                                                                                    \
        pSampleData = (type*)drflac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks);                                                      \
        if (pSampleData == NULL) {                                                                                                                                  \
            goto on_error;                                                                                                                                          \
        }                                                                                                                                                           \
                                                                                                                                                                    \
        while ((pcmFramesRead = (drflac_uint64)drflac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) {          \
            if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) {                                                   \
                type* pNewSampleData;                                                                                                                               \
                size_t newSampleDataBufferSize;                                                                                                                     \
                                                                                                                                                                    \
                newSampleDataBufferSize = sampleDataBufferSize * 2;                                                                                                 \
                pNewSampleData = (type*)drflac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks);    \
                if (pNewSampleData == NULL) {                                                                                                                       \
                    drflac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks);                                                                          \
                    goto on_error;                                                                                                                                  \
                }                                                                                                                                                   \

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        drflac_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type);                                                                                   \
        if (dataSize > (drflac_uint64)DRFLAC_SIZE_MAX) {                                                                                                            \
            goto on_error;                                                                                                        \
        }                                                                                                                                                           \
                                                                                                                                                                    \
        pSampleData = (type*)drflac__malloc_from_callbacks((size_t)dataSize, &pFlac->allocationCallbacks);               \
        if (pSampleData == NULL) {                                                                                                                                  \
            goto on_error;                                                                                                                                          \
        }                                                                                                                                                           \
                                                                                                                                                                    \
        totalPCMFrameCount = drflac_read_pcm_frames_##extension(pFlac, pFlac->totalPCMFrameCount, pSampleData);                                                     \
    }                                                                                                                                                               \
                                                                                                                                                                    \
    if (sampleRateOut) *sampleRateOut = pFlac->sampleRate;                                                                                                          \
    if (channelsOut) *channelsOut = pFlac->channels;                                                                                                                \
    if (totalPCMFrameCountOut) *totalPCMFrameCountOut = totalPCMFrameCount;                                                                                         \
                                                                                                                                                                    \
    drflac_close(pFlac);                                                                                                                                            \
    return pSampleData;                                                                                                                                             \
                                                                                                                                                                    \
on_error:                                                                                                                                                           \
    drflac_close(pFlac);                                                                                                                                            \
    return NULL;                                                                                                                                                    \
}
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s32, drflac_int32)
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s16, drflac_int16)
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(f32, float)
DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_call...
{
    drflac* pFlac;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalPCMFrameCountOut) {
        *totalPCMFrameCountOut = 0;
    }
    pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_s32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}
DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_call...
{
    drflac* pFlac;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalPCMFrameCountOut) {
        *totalPCMFrameCountOut = 0;
    }
    pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_s16(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}
DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* ...
{
    drflac* pFlac;
    if (channelsOut) {
        *channelsOut = 0;
    }
    if (sampleRateOut) {
        *sampleRateOut = 0;
    }
    if (totalPCMFrameCountOut) {
        *totalPCMFrameCountOut = 0;
    }
    pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_f32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}
#ifndef DR_FLAC_NO_STDIO
DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;
    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {
        *totalPCMFrameCount = 0;
    }
    pFlac = drflac_open_file(filename, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
}
DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;
    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {
        *totalPCMFrameCount = 0;
    }
    pFlac = drflac_open_file(filename, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
}
DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;
    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {
        *totalPCMFrameCount = 0;
    }
    pFlac = drflac_open_file(filename, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_f32(pFlac, channels, sampleRate, totalPCMFrameCount);
}
#endif
DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;
    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {
        *totalPCMFrameCount = 0;
    }
    pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
}
DRFLAC_API drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;
    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {
        *totalPCMFrameCount = 0;
    }
    pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
}
DRFLAC_API float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac* pFlac;
    if (sampleRate) {
        *sampleRate = 0;
    }
    if (channels) {
        *channels = 0;
    }
    if (totalPCMFrameCount) {
        *totalPCMFrameCount = 0;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        { { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,16,24,28,32,40,48,56,64,72,80,88,96,112,128 } },
        { { 0,16,20,24,28,32,40,48,56,64,80,96,112,128,160 }, { 0,16,24,28,32,40,48,56,64,80,96,112,128,160,192 }, { 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224 } },
    };
    return 2*halfrate[!!DRMP3_HDR_TEST_MPEG1(h)][DRMP3_HDR_GET_LAYER(h) - 1][DRMP3_HDR_GET_BITRATE(h)];
}
static unsigned drmp3_hdr_sample_rate_hz(const drmp3_uint8 *h)
{
    static const unsigned g_hz[3] = { 44100, 48000, 32000 };
    return g_hz[DRMP3_HDR_GET_SAMPLE_RATE(h)] >> (int)!DRMP3_HDR_TEST_MPEG1(h) >> (int)!DRMP3_HDR_TEST_NOT_MPEG25(h);
}
static unsigned drmp3_hdr_frame_samples(const drmp3_uint8 *h)
{
    return DRMP3_HDR_IS_LAYER_1(h) ? 384 : (1152 >> (int)DRMP3_HDR_IS_FRAME_576(h));
}
static int drmp3_hdr_frame_bytes(const drmp3_uint8 *h, int free_format_size)
{
    int frame_bytes = drmp3_hdr_frame_samples(h)*drmp3_hdr_bitrate_kbps(h)*125/drmp3_hdr_sample_rate_hz(h);
    if (DRMP3_HDR_IS_LAYER_1(h))
    {
        frame_bytes &= ~3;
    }
    return frame_bytes ? frame_bytes : free_format_size;
}
static int drmp3_hdr_padding(const drmp3_uint8 *h)
{
    return DRMP3_HDR_TEST_PADDING(h) ? (DRMP3_HDR_IS_LAYER_1(h) ? 4 : 1) : 0;
}
#ifndef DR_MP3_ONLY_MP3
static const drmp3_L12_subband_alloc *drmp3_L12_subband_alloc_table(const drmp3_uint8 *hdr, drmp3_L12_scale_info *sci)
{
    const drmp3_L12_subband_alloc *alloc;
    int mode = DRMP3_HDR_GET_STEREO_MODE(hdr);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        remains = DRMP3_MAX_BITRESERVOIR_BYTES;
    }
    if (remains > 0)
    {
        DRMP3_MOVE_MEMORY(h->reserv_buf, s->maindata + pos, remains);
    }
    h->reserv = remains;
}
static int drmp3_L3_restore_reservoir(drmp3dec *h, drmp3_bs *bs, drmp3dec_scratch *s, int main_data_begin)
{
    int frame_bytes = (bs->limit - bs->pos)/8;
    int bytes_have = DRMP3_MIN(h->reserv, main_data_begin);
    DRMP3_COPY_MEMORY(s->maindata, h->reserv_buf + DRMP3_MAX(0, h->reserv - main_data_begin), DRMP3_MIN(h->reserv, main_data_begin));
    DRMP3_COPY_MEMORY(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes);
    drmp3_bs_init(&s->bs, s->maindata, bytes_have + frame_bytes);
    return h->reserv >= main_data_begin;
}
static void drmp3_L3_decode(drmp3dec *h, drmp3dec_scratch *s, drmp3_L3_gr_info *gr_info, int nch)
{
    int ch;
    for (ch = 0; ch < nch; ch++)
    {
        int layer3gr_limit = s->bs.pos + gr_info[ch].part_23_length;
        drmp3_L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch);
        drmp3_L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        for (i = 0; i < 15*64; i += 2)
        {
            qmf_state[i] = lins[nbands*64 + i];
        }
    } else
#endif
    {
        DRMP3_COPY_MEMORY(qmf_state, lins + nbands*64, sizeof(float)*15*64);
    }
}
static int drmp3d_match_frame(const drmp3_uint8 *hdr, int mp3_bytes, int frame_bytes)
{
    int i, nmatch;
    for (i = 0, nmatch = 0; nmatch < DRMP3_MAX_FRAME_SYNC_MATCHES; nmatch++)
    {
        i += drmp3_hdr_frame_bytes(hdr + i, frame_bytes) + drmp3_hdr_padding(hdr + i);
        if (i + DRMP3_HDR_SIZE > mp3_bytes)
            return nmatch > 0;
        if (!drmp3_hdr_compare(hdr, hdr + i))
            return 0;
    }
    return 1;
}
static int drmp3d_find_frame(const drmp3_uint8 *mp3, int mp3_bytes, int *free_format_bytes, int *ptr_frame_bytes)
{
    int i, k;
    for (i = 0; i < mp3_bytes - DRMP3_HDR_SIZE; i++, mp3++)
    {
        if (drmp3_hdr_valid(mp3))
        {
            int frame_bytes = drmp3_hdr_frame_bytes(mp3, *free_format_bytes);
            int frame_and_padding = frame_bytes + drmp3_hdr_padding(mp3);
            for (k = DRMP3_HDR_SIZE; !frame_bytes && k < DRMP3_MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - DRMP3_HDR_SIZE; k++)
            {
                if (drmp3_hdr_compare(mp3, mp3 + k))
                {
                    int fb = k - drmp3_hdr_padding(mp3);
                    int nextfb = fb + drmp3_hdr_padding(mp3 + k);
                    if (i + k + nextfb + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + k + nextfb))
                        continue;
                    frame_and_padding = k;
                    frame_bytes = fb;
                    *free_format_bytes = fb;
                }
            }
            if ((frame_bytes && i + frame_and_padding <= mp3_bytes &&
                drmp3d_match_frame(mp3, mp3_bytes - i, frame_bytes)) ||
                (!i && frame_and_padding == mp3_bytes))
            {
                *ptr_frame_bytes = frame_and_padding;
                return i;
            }
            *free_format_bytes = 0;
        }
    }
    *ptr_frame_bytes = 0;
    return mp3_bytes;
}
DRMP3_API void drmp3dec_init(drmp3dec *dec)
{
    dec->header[0] = 0;
}
DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info)
{
    int i = 0, igr, frame_size = 0, success = 1;
    const drmp3_uint8 *hdr;
    drmp3_bs bs_frame[1];
    drmp3dec_scratch scratch;
    if (mp3_bytes > 4 && dec->header[0] == 0xff && drmp3_hdr_compare(dec->header, mp3))
    {
        frame_size = drmp3_hdr_frame_bytes(mp3, dec->free_format_bytes) + drmp3_hdr_padding(mp3);
        if (frame_size != mp3_bytes && (frame_size + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + frame_size)))
        {
            frame_size = 0;
        }
    }
    if (!frame_size)
    {
        DRMP3_ZERO_MEMORY(dec, sizeof(drmp3dec));
        i = drmp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size);
        if (!frame_size || i + frame_size > mp3_bytes)
        {
            info->frame_bytes = i;
            return 0;
        }
    }
    hdr = mp3 + i;
    DRMP3_COPY_MEMORY(dec->header, hdr, DRMP3_HDR_SIZE);
    info->frame_bytes = i + frame_size;
    info->channels = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2;
    info->hz = drmp3_hdr_sample_rate_hz(hdr);
    info->layer = 4 - DRMP3_HDR_GET_LAYER(hdr);
    info->bitrate_kbps = drmp3_hdr_bitrate_kbps(hdr);
    drmp3_bs_init(bs_frame, hdr + DRMP3_HDR_SIZE, frame_size - DRMP3_HDR_SIZE);
    if (DRMP3_HDR_IS_CRC(hdr))
    {
        drmp3_bs_get_bits(bs_frame, 16);
    }
    if (info->layer == 3)
    {
        int main_data_begin = drmp3_L3_read_side_info(bs_frame, scratch.gr_info, hdr);
        if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit)
        {
            drmp3dec_init(dec);
            return 0;
        }
        success = drmp3_L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin);
        if (success && pcm != NULL)
        {
            for (igr = 0; igr < (DRMP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*576*info->channels))
            {
                DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float));
                drmp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels);
                drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]);
            }
        }
        drmp3_L3_save_reservoir(dec, &scratch);
    } else
    {
#ifdef DR_MP3_ONLY_MP3
        return 0;
#else
        drmp3_L12_scale_info sci[1];
        if (pcm == NULL) {
            return drmp3_hdr_frame_samples(hdr);
        }
        drmp3_L12_read_scale_info(hdr, bs_frame, sci);
        DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float));
        for (i = 0, igr = 0; igr < 3; igr++)
        {
            if (12 == (i += drmp3_L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1)))
            {
                i = 0;
                drmp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]);
                drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]);
                DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float));
                pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*384*info->channels);
            }
            if (bs_frame->pos > bs_frame->limit)
            {
                drmp3dec_init(dec);
                return 0;
            }
        }
#endif
    }
    return success*drmp3_hdr_frame_samples(dec->header);
}
DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples)
{
    size_t i = 0;
#if DRMP3_HAVE_SIMD
    size_t aligned_count = num_samples & ~7;
    for(; i < aligned_count; i+=8)
    {
        drmp3_f4 scale = DRMP3_VSET(32768.0f);
        drmp3_f4 a = DRMP3_VMUL(DRMP3_VLD(&in[i  ]), scale);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            offset = 0;
        } else {
            if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_current)) {
                return DRMP3_FALSE;
            }
            offset -= 0x7FFFFFFF;
        }
    }
    return DRMP3_TRUE;
}
static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
{
    drmp3_uint32 pcmFramesRead = 0;
    DRMP3_ASSERT(pMP3 != NULL);
    DRMP3_ASSERT(pMP3->onRead != NULL);
    if (pMP3->atEnd) {
        return 0;
    }
    for (;;) {
        drmp3dec_frame_info info;
        if (pMP3->dataSize < DRMP3_MIN_DATA_CHUNK_SIZE) {
            size_t bytesRead;
            if (pMP3->pData != NULL) {
                DRMP3_MOVE_MEMORY(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
            }
            pMP3->dataConsumed = 0;
            if (pMP3->dataCapacity < DRMP3_DATA_CHUNK_SIZE) {
                drmp3_uint8* pNewData;
                size_t newDataCap;
                newDataCap = DRMP3_DATA_CHUNK_SIZE;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

                }
            }
            pMP3->dataSize += bytesRead;
        }
        if (pMP3->dataSize > INT_MAX) {
            pMP3->atEnd = DRMP3_TRUE;
            return 0;
        }
        DRMP3_ASSERT(pMP3->pData != NULL);
        DRMP3_ASSERT(pMP3->dataCapacity > 0);
        pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info);
        if (info.frame_bytes > 0) {
            pMP3->dataConsumed += (size_t)info.frame_bytes;
            pMP3->dataSize     -= (size_t)info.frame_bytes;
        }
        if (pcmFramesRead > 0) {
            pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header);
            pMP3->pcmFramesConsumedInMP3Frame = 0;
            pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
            pMP3->mp3FrameChannels = info.channels;
            pMP3->mp3FrameSampleRate = info.hz;
            break;
        } else if (info.frame_bytes == 0) {
            size_t bytesRead;
            DRMP3_MOVE_MEMORY(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
            pMP3->dataConsumed = 0;
            if (pMP3->dataCapacity == pMP3->dataSize) {
                drmp3_uint8* pNewData;
                size_t newDataCap;
                newDataCap = pMP3->dataCapacity + DRMP3_DATA_CHUNK_SIZE;
                pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
                if (pNewData == NULL) {
                    return 0;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
            if (bytesRead == 0) {
                pMP3->atEnd = DRMP3_TRUE;
                return 0;
            }
            pMP3->dataSize += bytesRead;
        }
    };
    return pcmFramesRead;
}
static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
{
    drmp3_uint32 pcmFramesRead = 0;
    drmp3dec_frame_info info;
    DRMP3_ASSERT(pMP3 != NULL);
    DRMP3_ASSERT(pMP3->memory.pData != NULL);
    if (pMP3->atEnd) {
        return 0;
    }
    for (;;) {
        pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->memory.pData + pMP3->memory.currentReadPos, (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos), pPCMFrames, &info);
        if (pcmFramesRead > 0) {
            pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header);
            pMP3->pcmFramesConsumedInMP3Frame  = 0;
            pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
            pMP3->mp3FrameChannels             = info.channels;
            pMP3->mp3FrameSampleRate           = info.hz;
            break;
        } else if (info.frame_bytes > 0) {
            pMP3->memory.currentReadPos += (size_t)info.frame_bytes;
        } else {
            break;
        }
    }
    pMP3->memory.currentReadPos += (size_t)info.frame_bytes;
    return pcmFramesRead;
}
static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
{
    if (pMP3->memory.pData != NULL && pMP3->memory.dataSize > 0) {
        return drmp3_decode_next_frame_ex__memory(pMP3, pPCMFrames);
    } else {
        return drmp3_decode_next_frame_ex__callbacks(pMP3, pPCMFrames);
    }
}
static drmp3_uint32 drmp3_decode_next_frame(drmp3* pMP3)
{
    DRMP3_ASSERT(pMP3 != NULL);
    return drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames);
}
#if 0
static drmp3_uint32 drmp3_seek_next_frame(drmp3* pMP3)
{
    drmp3_uint32 pcmFrameCount;
    DRMP3_ASSERT(pMP3 != NULL);
    pcmFrameCount = drmp3_decode_next_frame_ex(pMP3, NULL);
    if (pcmFrameCount == 0) {
        return 0;
    }
    pMP3->currentPCMFrame             += pcmFrameCount;
    pMP3->pcmFramesConsumedInMP3Frame  = pcmFrameCount;
    pMP3->pcmFramesRemainingInMP3Frame = 0;
    return pcmFrameCount;
}
#endif
static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    DRMP3_ASSERT(pMP3 != NULL);
    DRMP3_ASSERT(onRead != NULL);
    drmp3dec_init(&pMP3->decoder);
    pMP3->onRead = onRead;
    pMP3->onSeek = onSeek;
    pMP3->pUserData = pUserData;
    pMP3->allocationCallbacks = drmp3_copy_allocation_callbacks_or_defaults(pAllocationCallbacks);
    if (pMP3->allocationCallbacks.onFree == NULL || (pMP3->allocationCallbacks.onMalloc == NULL && pMP3->allocationCallbacks.onRealloc == NULL)) {
        return DRMP3_FALSE;
    }
    if (drmp3_decode_next_frame(pMP3) == 0) {
        drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks);
        return DRMP3_FALSE;
    }
    pMP3->channels   = pMP3->mp3FrameChannels;
    pMP3->sampleRate = pMP3->mp3FrameSampleRate;
    return DRMP3_TRUE;
}
DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    if (pMP3 == NULL || onRead == NULL) {

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

static void drmp3_s16_to_f32(float* dst, const drmp3_int16* src, drmp3_uint64 sampleCount)
{
    drmp3_uint64 i;
    for (i = 0; i < sampleCount; i += 1) {
        float x = (float)src[i];
        x = x * 0.000030517578125f;
        dst[i] = x;
    }
}
#endif
static drmp3_uint64 drmp3_read_pcm_frames_raw(drmp3* pMP3, drmp3_uint64 framesToRead, void* pBufferOut)
{
    drmp3_uint64 totalFramesRead = 0;
    DRMP3_ASSERT(pMP3 != NULL);
    DRMP3_ASSERT(pMP3->onRead != NULL);
    while (framesToRead > 0) {
        drmp3_uint32 framesToConsume = (drmp3_uint32)DRMP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, framesToRead);
        if (pBufferOut != NULL) {
        #if defined(DR_MP3_FLOAT_OUTPUT)
            float* pFramesOutF32 = (float*)DRMP3_OFFSET_PTR(pBufferOut,          sizeof(float) * totalFramesRead                   * pMP3->channels);
            float* pFramesInF32  = (float*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
            DRMP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels);
        #else
            drmp3_int16* pFramesOutS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut,          sizeof(drmp3_int16) * totalFramesRead                   * pMP3->channels);
            drmp3_int16* pFramesInS16  = (drmp3_int16*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(drmp3_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
            DRMP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(drmp3_int16) * framesToConsume * pMP3->channels);
        #endif
        }
        pMP3->currentPCMFrame              += framesToConsume;
        pMP3->pcmFramesConsumedInMP3Frame  += framesToConsume;
        pMP3->pcmFramesRemainingInMP3Frame -= framesToConsume;
        totalFramesRead                    += framesToConsume;
        framesToRead                       -= framesToConsume;
        if (framesToRead == 0) {
            break;
        }
        DRMP3_ASSERT(pMP3->pcmFramesRemainingInMP3Frame == 0);
        if (drmp3_decode_next_frame(pMP3) == 0) {
            break;
        }
    }
    return totalFramesRead;
}
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut)
{
    if (pMP3 == NULL || pMP3->onRead == NULL) {
        return 0;
    }
#if defined(DR_MP3_FLOAT_OUTPUT)
    return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
#else
    {
        drmp3_int16 pTempS16[8192];
        drmp3_uint64 totalPCMFramesRead = 0;
        while (totalPCMFramesRead < framesToRead) {
            drmp3_uint64 framesJustRead;
            drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
            drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempS16) / pMP3->channels;
            if (framesToReadNow > framesRemaining) {
                framesToReadNow = framesRemaining;
            }
            framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempS16);
            if (framesJustRead == 0) {
                break;
            }
            drmp3_s16_to_f32((float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalPCMFramesRead * pMP3->channels), pTempS16, framesJustRead * pMP3->channels);
            totalPCMFramesRead += framesJustRead;
        }
        return totalPCMFramesRead;
    }
#endif
}
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut)
{
    if (pMP3 == NULL || pMP3->onRead == NULL) {
        return 0;
    }
#if !defined(DR_MP3_FLOAT_OUTPUT)
    return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
#else
    {
        float pTempF32[4096];
        drmp3_uint64 totalPCMFramesRead = 0;
        while (totalPCMFramesRead < framesToRead) {
            drmp3_uint64 framesJustRead;
            drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
            drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempF32) / pMP3->channels;
            if (framesToReadNow > framesRemaining) {
                framesToReadNow = framesRemaining;
            }
            framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempF32);
            if (framesJustRead == 0) {
                break;
            }
            drmp3_f32_to_s16((drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalPCMFramesRead * pMP3->channels), pTempF32, framesJustRead * pMP3->channels);
            totalPCMFramesRead += framesJustRead;
        }
        return totalPCMFramesRead;
    }
#endif
}
static void drmp3_reset(drmp3* pMP3)
{
    DRMP3_ASSERT(pMP3 != NULL);
    pMP3->pcmFramesConsumedInMP3Frame = 0;
    pMP3->pcmFramesRemainingInMP3Frame = 0;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

static drmp3_bool32 drmp3_seek_to_start_of_stream(drmp3* pMP3)
{
    DRMP3_ASSERT(pMP3 != NULL);
    DRMP3_ASSERT(pMP3->onSeek != NULL);
    if (!drmp3__on_seek(pMP3, 0, drmp3_seek_origin_start)) {
        return DRMP3_FALSE;
    }
    drmp3_reset(pMP3);
    return DRMP3_TRUE;
}
static drmp3_bool32 drmp3_seek_forward_by_pcm_frames__brute_force(drmp3* pMP3, drmp3_uint64 frameOffset)
{
    drmp3_uint64 framesRead;
#if defined(DR_MP3_FLOAT_OUTPUT)
    framesRead = drmp3_read_pcm_frames_f32(pMP3, frameOffset, NULL);
#else
    framesRead = drmp3_read_pcm_frames_s16(pMP3, frameOffset, NULL);
#endif
    if (framesRead != frameOffset) {
        return DRMP3_FALSE;
    }
    return DRMP3_TRUE;
}
static drmp3_bool32 drmp3_seek_to_pcm_frame__brute_force(drmp3* pMP3, drmp3_uint64 frameIndex)
{
    DRMP3_ASSERT(pMP3 != NULL);
    if (frameIndex == pMP3->currentPCMFrame) {
        return DRMP3_TRUE;
    }
    if (frameIndex < pMP3->currentPCMFrame) {
        if (!drmp3_seek_to_start_of_stream(pMP3)) {
            return DRMP3_FALSE;
        }
    }
    DRMP3_ASSERT(frameIndex >= pMP3->currentPCMFrame);
    return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, (frameIndex - pMP3->currentPCMFrame));
}
static drmp3_bool32 drmp3_find_closest_seek_point(drmp3* pMP3, drmp3_uint64 frameIndex, drmp3_uint32* pSeekPointIndex)
{
    drmp3_uint32 iSeekPoint;
    DRMP3_ASSERT(pSeekPointIndex != NULL);
    *pSeekPointIndex = 0;
    if (frameIndex < pMP3->pSeekPoints[0].pcmFrameIndex) {
        return DRMP3_FALSE;
    }
    for (iSeekPoint = 0; iSeekPoint < pMP3->seekPointCount; ++iSeekPoint) {
        if (pMP3->pSeekPoints[iSeekPoint].pcmFrameIndex > frameIndex) {
            break;
        }
        *pSeekPointIndex = iSeekPoint;
    }
    return DRMP3_TRUE;
}
static drmp3_bool32 drmp3_seek_to_pcm_frame__seek_table(drmp3* pMP3, drmp3_uint64 frameIndex)
{
    drmp3_seek_point seekPoint;
    drmp3_uint32 priorSeekPointIndex;
    drmp3_uint16 iMP3Frame;
    drmp3_uint64 leftoverFrames;
    DRMP3_ASSERT(pMP3 != NULL);
    DRMP3_ASSERT(pMP3->pSeekPoints != NULL);
    DRMP3_ASSERT(pMP3->seekPointCount > 0);
    if (drmp3_find_closest_seek_point(pMP3, frameIndex, &priorSeekPointIndex)) {
        seekPoint = pMP3->pSeekPoints[priorSeekPointIndex];
    } else {
        seekPoint.seekPosInBytes     = 0;
        seekPoint.pcmFrameIndex      = 0;
        seekPoint.mp3FramesToDiscard = 0;
        seekPoint.pcmFramesToDiscard = 0;
    }
    if (!drmp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, drmp3_seek_origin_start)) {
        return DRMP3_FALSE;
    }
    drmp3_reset(pMP3);
    for (iMP3Frame = 0; iMP3Frame < seekPoint.mp3FramesToDiscard; ++iMP3Frame) {
        drmp3_uint32 pcmFramesRead;
        drmp3d_sample_t* pPCMFrames;
        pPCMFrames = NULL;
        if (iMP3Frame == seekPoint.mp3FramesToDiscard-1) {
            pPCMFrames = (drmp3d_sample_t*)pMP3->pcmFrames;
        }
        pcmFramesRead = drmp3_decode_next_frame_ex(pMP3, pPCMFrames);
        if (pcmFramesRead == 0) {
            return DRMP3_FALSE;
        }
    }
    pMP3->currentPCMFrame = seekPoint.pcmFrameIndex - seekPoint.pcmFramesToDiscard;
    leftoverFrames = frameIndex - pMP3->currentPCMFrame;
    return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, leftoverFrames);
}
DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex)
{
    if (pMP3 == NULL || pMP3->onSeek == NULL) {
        return DRMP3_FALSE;
    }
    if (frameIndex == 0) {
        return drmp3_seek_to_start_of_stream(pMP3);
    }
    if (pMP3->pSeekPoints != NULL && pMP3->seekPointCount > 0) {
        return drmp3_seek_to_pcm_frame__seek_table(pMP3, frameIndex);
    } else {
        return drmp3_seek_to_pcm_frame__brute_force(pMP3, frameIndex);
    }
}
DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount)
{
    drmp3_uint64 currentPCMFrame;
    drmp3_uint64 totalPCMFrameCount;
    drmp3_uint64 totalMP3FrameCount;
    if (pMP3 == NULL) {
        return DRMP3_FALSE;
    }
    if (pMP3->onSeek == NULL) {
        return DRMP3_FALSE;
    }
    currentPCMFrame = pMP3->currentPCMFrame;
    if (!drmp3_seek_to_start_of_stream(pMP3)) {
        return DRMP3_FALSE;
    }
    totalPCMFrameCount = 0;
    totalMP3FrameCount = 0;
    for (;;) {
        drmp3_uint32 pcmFramesInCurrentMP3Frame;
        pcmFramesInCurrentMP3Frame = drmp3_decode_next_frame_ex(pMP3, NULL);
        if (pcmFramesInCurrentMP3Frame == 0) {
            break;
        }
        totalPCMFrameCount += pcmFramesInCurrentMP3Frame;
        totalMP3FrameCount += 1;
    }
    if (!drmp3_seek_to_start_of_stream(pMP3)) {
        return DRMP3_FALSE;
    }
    if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
        return DRMP3_FALSE;
    }
    if (pMP3FrameCount != NULL) {
        *pMP3FrameCount = totalMP3FrameCount;
    }
    if (pPCMFrameCount != NULL) {
        *pPCMFrameCount = totalPCMFrameCount;
    }
    return DRMP3_TRUE;
}
DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3)
{
    drmp3_uint64 totalPCMFrameCount;
    if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, NULL, &totalPCMFrameCount)) {
        return 0;
    }
    return totalPCMFrameCount;
}
DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3)
{
    drmp3_uint64 totalMP3FrameCount;
    if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, NULL)) {
        return 0;
    }
    return totalMP3FrameCount;
}
static void drmp3__accumulate_running_pcm_frame_count(drmp3* pMP3, drmp3_uint32 pcmFrameCountIn, drmp3_uint64* pRunningPCMFrameCount, float* pRunningPCMFrameCountFractionalPart)
{
    float srcRatio;
    float pcmFrameCountOutF;
    drmp3_uint32 pcmFrameCountOut;
    srcRatio = (float)pMP3->mp3FrameSampleRate / (float)pMP3->sampleRate;
    DRMP3_ASSERT(srcRatio > 0);
    pcmFrameCountOutF = *pRunningPCMFrameCountFractionalPart + (pcmFrameCountIn / srcRatio);
    pcmFrameCountOut  = (drmp3_uint32)pcmFrameCountOutF;
    *pRunningPCMFrameCountFractionalPart = pcmFrameCountOutF - pcmFrameCountOut;
    *pRunningPCMFrameCount += pcmFrameCountOut;
}
typedef struct
{
    drmp3_uint64 bytePos;
    drmp3_uint64 pcmFrameIndex;
} drmp3__seeking_mp3_frame_info;
DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints)
{
    drmp3_uint32 seekPointCount;
    drmp3_uint64 currentPCMFrame;
    drmp3_uint64 totalMP3FrameCount;
    drmp3_uint64 totalPCMFrameCount;
    if (pMP3 == NULL || pSeekPointCount == NULL || pSeekPoints == NULL) {
        return DRMP3_FALSE;
    }
    seekPointCount = *pSeekPointCount;
    if (seekPointCount == 0) {
        return DRMP3_FALSE;
    }
    currentPCMFrame = pMP3->currentPCMFrame;
    if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, &totalPCMFrameCount)) {
        return DRMP3_FALSE;
    }
    if (totalMP3FrameCount < DRMP3_SEEK_LEADING_MP3_FRAMES+1) {
        seekPointCount = 1;
        pSeekPoints[0].seekPosInBytes     = 0;
        pSeekPoints[0].pcmFrameIndex      = 0;
        pSeekPoints[0].mp3FramesToDiscard = 0;
        pSeekPoints[0].pcmFramesToDiscard = 0;
    } else {
        drmp3_uint64 pcmFramesBetweenSeekPoints;
        drmp3__seeking_mp3_frame_info mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES+1];
        drmp3_uint64 runningPCMFrameCount = 0;
        float runningPCMFrameCountFractionalPart = 0;
        drmp3_uint64 nextTargetPCMFrame;
        drmp3_uint32 iMP3Frame;
        drmp3_uint32 iSeekPoint;
        if (seekPointCount > totalMP3FrameCount-1) {
            seekPointCount = (drmp3_uint32)totalMP3FrameCount-1;
        }
        pcmFramesBetweenSeekPoints = totalPCMFrameCount / (seekPointCount+1);
        if (!drmp3_seek_to_start_of_stream(pMP3)) {
            return DRMP3_FALSE;
        }
        for (iMP3Frame = 0; iMP3Frame < DRMP3_SEEK_LEADING_MP3_FRAMES+1; ++iMP3Frame) {
            drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
            DRMP3_ASSERT(pMP3->streamCursor >= pMP3->dataSize);
            mp3FrameInfo[iMP3Frame].bytePos       = pMP3->streamCursor - pMP3->dataSize;
            mp3FrameInfo[iMP3Frame].pcmFrameIndex = runningPCMFrameCount;
            pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL);
            if (pcmFramesInCurrentMP3FrameIn == 0) {
                return DRMP3_FALSE;
            }
            drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
        }
        nextTargetPCMFrame = 0;
        for (iSeekPoint = 0; iSeekPoint < seekPointCount; ++iSeekPoint) {
            nextTargetPCMFrame += pcmFramesBetweenSeekPoints;
            for (;;) {
                if (nextTargetPCMFrame < runningPCMFrameCount) {
                    pSeekPoints[iSeekPoint].seekPosInBytes     = mp3FrameInfo[0].bytePos;
                    pSeekPoints[iSeekPoint].pcmFrameIndex      = nextTargetPCMFrame;
                    pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
                    pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
                    break;
                } else {
                    size_t i;
                    drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
                    for (i = 0; i < DRMP3_COUNTOF(mp3FrameInfo)-1; ++i) {
                        mp3FrameInfo[i] = mp3FrameInfo[i+1];
                    }
                    mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].bytePos       = pMP3->streamCursor - pMP3->dataSize;
                    mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].pcmFrameIndex = runningPCMFrameCount;
                    pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL);
                    if (pcmFramesInCurrentMP3FrameIn == 0) {
                        pSeekPoints[iSeekPoint].seekPosInBytes     = mp3FrameInfo[0].bytePos;
                        pSeekPoints[iSeekPoint].pcmFrameIndex      = nextTargetPCMFrame;
                        pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
                        pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
                        break;
                    }
                    drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
                }
            }
        }
        if (!drmp3_seek_to_start_of_stream(pMP3)) {
            return DRMP3_FALSE;
        }
        if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
            return DRMP3_FALSE;
        }
    }
    *pSeekPointCount = seekPointCount;
    return DRMP3_TRUE;
}
DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints)
{
    if (pMP3 == NULL) {
        return DRMP3_FALSE;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        pMP3->pSeekPoints = NULL;
    } else {
        pMP3->seekPointCount = seekPointCount;
        pMP3->pSeekPoints = pSeekPoints;
    }
    return DRMP3_TRUE;
}
static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
{
    drmp3_uint64 totalFramesRead = 0;
    drmp3_uint64 framesCapacity = 0;
    float* pFrames = NULL;
    float temp[4096];
    DRMP3_ASSERT(pMP3 != NULL);
    for (;;) {
        drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
        drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_f32(pMP3, framesToReadRightNow, temp);
        if (framesJustRead == 0) {
            break;
        }
        if (framesCapacity < totalFramesRead + framesJustRead) {
            drmp3_uint64 oldFramesBufferSize;
            drmp3_uint64 newFramesBufferSize;
            drmp3_uint64 newFramesCap;
            float* pNewFrames;
            newFramesCap = framesCapacity * 2;
            if (newFramesCap < totalFramesRead + framesJustRead) {
                newFramesCap = totalFramesRead + framesJustRead;
            }
            oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(float);
            newFramesBufferSize = newFramesCap   * pMP3->channels * sizeof(float);
            if (newFramesBufferSize > (drmp3_uint64)DRMP3_SIZE_MAX) {
                break;
            }
            pNewFrames = (float*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
            if (pNewFrames == NULL) {
                drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
                break;
            }
            pFrames = pNewFrames;
            framesCapacity = newFramesCap;
        }
        DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float)));
        totalFramesRead += framesJustRead;
        if (framesJustRead != framesToReadRightNow) {
            break;
        }
    }
    if (pConfig != NULL) {
        pConfig->channels   = pMP3->channels;
        pConfig->sampleRate = pMP3->sampleRate;
    }
    drmp3_uninit(pMP3);
    if (pTotalFrameCount) {
        *pTotalFrameCount = totalFramesRead;
    }
    return pFrames;
}
static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
{
    drmp3_uint64 totalFramesRead = 0;
    drmp3_uint64 framesCapacity = 0;
    drmp3_int16* pFrames = NULL;
    drmp3_int16 temp[4096];
    DRMP3_ASSERT(pMP3 != NULL);
    for (;;) {
        drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
        drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_s16(pMP3, framesToReadRightNow, temp);
        if (framesJustRead == 0) {
            break;
        }
        if (framesCapacity < totalFramesRead + framesJustRead) {
            drmp3_uint64 newFramesBufferSize;
            drmp3_uint64 oldFramesBufferSize;
            drmp3_uint64 newFramesCap;
            drmp3_int16* pNewFrames;
            newFramesCap = framesCapacity * 2;
            if (newFramesCap < totalFramesRead + framesJustRead) {
                newFramesCap = totalFramesRead + framesJustRead;
            }
            oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(drmp3_int16);
            newFramesBufferSize = newFramesCap   * pMP3->channels * sizeof(drmp3_int16);
            if (newFramesBufferSize > (drmp3_uint64)DRMP3_SIZE_MAX) {
                break;
            }
            pNewFrames = (drmp3_int16*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
            if (pNewFrames == NULL) {
                drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
                break;
            }
            pFrames = pNewFrames;
            framesCapacity = newFramesCap;
        }
        DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(drmp3_int16)));
        totalFramesRead += framesJustRead;
        if (framesJustRead != framesToReadRightNow) {
            break;
        }
    }
    if (pConfig != NULL) {
        pConfig->channels   = pMP3->channels;
        pConfig->sampleRate = pMP3->sampleRate;
    }
    drmp3_uninit(pMP3);
    if (pTotalFrameCount) {
        *pTotalFrameCount = totalFramesRead;
    }
    return pFrames;
}
DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    drmp3 mp3;
    if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
        return NULL;
    }
    return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
}
DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    drmp3 mp3;
    if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
        return NULL;
    }
    return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
}
DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    drmp3 mp3;
    if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
        return NULL;
    }
    return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
}
DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    drmp3 mp3;
    if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
        return NULL;
    }
    return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
}
#ifndef DR_MP3_NO_STDIO
DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    drmp3 mp3;
    if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
        return NULL;
    }
    return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
}
DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
    drmp3 mp3;
    if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
        return NULL;
    }
    return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
}
#endif
DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks)
{

share/public_html/static/music_worklet_inprogress/decoder/mhfscl.js  view on Meta::CPAN

        if(that.ptr){
            if(that.initialized) {
                MHFSCL.Module._mhfs_cl_track_deinit(that.ptr);
            }
            MHFSCL.Module._free(that.ptr);
            that.ptr = null;
        }                    
    };
    
    that.seek = function(pcmFrameIndex) {
        if(!MHFSCL.Module._mhfs_cl_track_seek_to_pcm_frame(that.ptr, pcmFrameIndex)) throw("Failed to seek to " + pcmFrameIndex);
    };

    that.seekSecs = function(floatseconds) {
        that.seek(Math.floor(floatseconds * that.sampleRate));
    };

    that._openPictureIfExists = function() {
        if(!that.picture) {
            return undefined;
        }

share/public_html/static/music_worklet_inprogress/decoder/mhfscl.js  view on Meta::CPAN

        console.log('MHFSCLDecoder, waiting for MHFSCL to be ready');
        await waitForEvent(MHFSCL, 'ready');
    }
	const that = {};
	that.ptr = MHFSCL.Module._mhfs_cl_decoder_open(outputSampleRate, outputChannelCount, outputSampleRate);
    if(! that.ptr) throw("Failed to open decoder");

    that.outputSampleRate = outputSampleRate;
    that.outputChannelCount = outputChannelCount;
    that.f32_size = 4;
    that.pcm_float_frame_size = that.f32_size * that.outputChannelCount;

    that.returnDataAlloc = MHFSCLAllocation(MHFSCL.mhfs_cl_track_return_data.sizeof);
    that.deinterleaveDataAlloc = MHFSCLArrsAlloc(outputChannelCount, that.outputSampleRate*that.f32_size);
    //that.DM = DownloadManager(262144);
    that.rd = MHFSCL.mhfs_cl_track_return_data.from(that.returnDataAlloc.ptr);

    that.flush = async function() {
        MHFSCL.Module._mhfs_cl_decoder_flush(that.ptr);
    };

share/public_html/static/music_worklet_inprogress/decoder/mhfscl.js  view on Meta::CPAN

        if(signal.aborted) {
            console.log('');
            await that.track.close();
            that.track = null;
            throw("abort after open track success");
        }

        return { duration : that.track.duration, mediametadata : that.track.mediametadata };
    };
	
	that.seek_input_pcm_frames = async function(pcmFrameIndex) {
        if(!that.track) throw("nothing to seek on");
        that.track.seek(pcmFrameIndex);
    };

    that.seek = async function(floatseconds) {
        if(!that.track) throw("nothing to seek on");
        that.track.seekSecs(floatseconds);
    }

    that.read_pcm_frames_f32_deinterleaved = async function(todec, destdata, mysignal) {
              
        while(1) {              
            // attempt to decode the samples
            const code = MHFSCL.Module._mhfs_cl_decoder_read_pcm_frames_f32_deinterleaved(that.ptr, that.track.ptr, todec, destdata, that.rd.ptr);

            // success, retdata is frames read
            if(code === MHFSCL.MHFS_CL_SUCCESS)
            {
                return that.rd.get('frames_read');
            }
            if(code !== MHFSCL.MHFS_CL_NEED_MORE_DATA)
            {
                throw("mhfs_cl_decoder_read_pcm_frames_f32_deinterleaved failed");
            }

            // download more data
            await that.track.downloadAndStoreChunk(that.rd.get('needed_offset'), mysignal);
        }        
    };

    that.read_pcm_frames_f32_AudioBuffer = async function(todec, mysignal) {
        let theerror;
        let returnval;
        const destdata = that.deinterleaveDataAlloc.with(todec*that.f32_size);
        try {
            const frames = await that.read_pcm_frames_f32_deinterleaved(todec, destdata, mysignal);
            if(frames) {
                const audiobuffer = new AudioBuffer({'length' : frames, 'numberOfChannels' : that.outputChannelCount, 'sampleRate' : that.outputSampleRate});
                const chanPtrs = new Uint32Array(MHFSCL.Module.HEAPU8.buffer, destdata, that.outputChannelCount);
                for( let i = 0; i < that.outputChannelCount; i++) {
                    const buf = new Float32Array(MHFSCL.Module.HEAPU8.buffer, chanPtrs[i], frames);
                    audiobuffer.copyToChannel(buf, i);
                }
                returnval = audiobuffer;
            }            
        }
        catch(error) {
            theerror = error;
        }
        finally {
            if(theerror) throw(theerror);
            return returnval;
        }        
    };

    that.read_pcm_frames_f32_arrs = async function(todec, mysignal) {
        let theerror;
        let returnval;
        const destdata = that.deinterleaveDataAlloc.with(todec*that.f32_size);
        try {
            const frames = await that.read_pcm_frames_f32_deinterleaved(todec, destdata, mysignal);
            if(frames) {
                const chanPtrs = new Uint32Array(MHFSCL.Module.HEAPU8.buffer, destdata, that.outputChannelCount);
                const obj = { 'length' : frames, 'chanData' : []};
                for( let i = 0; i < that.outputChannelCount; i++) {
                    obj.chanData[i] = new Float32Array(MHFSCL.Module.HEAPU8.buffer, chanPtrs[i], frames);
                }
                returnval = obj;
            }
        }
        catch(error) {
            theerror = error;
        }
        finally {
            if(theerror) throw(theerror);
            return returnval;

share/public_html/static/music_worklet_inprogress/decoder/src/mhfs_cl_decoder.h  view on Meta::CPAN


#include "mhfs_cl.h"

typedef struct {
    unsigned outputSampleRate;
    unsigned outputChannels;
    bool has_madc;
    ma_data_converter madc;
    size_t dcTempOutSize;
    float32_t *pDCTempOut;
    unsigned interleaveData_pcm_frames;
    float32_t interleavedData[];
} mhfs_cl_decoder;

LIBEXPORT mhfs_cl_decoder *mhfs_cl_decoder_open(const unsigned outputSampleRate, const unsigned outputChannels, const unsigned deinterleave_max_pcm_frames);
LIBEXPORT mhfs_cl_error mhfs_cl_decoder_read_pcm_frames_f32_deinterleaved(mhfs_cl_decoder *mhfs_d, mhfs_cl_track *pTrack, const uint32_t desired_pcm_frames, float32_t *outFloat[], mhfs_cl_track_return_data *pReturnData);
LIBEXPORT void mhfs_cl_decoder_close(mhfs_cl_decoder *mhfs_d);
LIBEXPORT void mhfs_cl_decoder_flush(mhfs_cl_decoder *mhfs_d);
#endif /* mhfs_cl_decoder_h */

#if defined(MHFSCLDECODER_IMPLEMENTATION)
#ifndef mhfs_cl_decoder_c
#define mhfs_cl_decoder_c

#include "mhfs_cl_track.h"

#ifndef MHFSCLDEC_PRINT_ON
    #define MHFSCLDEC_PRINT_ON 0
#endif

#define MHFSCLDEC_PRINT(...) \
    do { if (MHFSCLDEC_PRINT_ON) fprintf(stdout, __VA_ARGS__); } while (0)

size_t mhfs_cl_decoder_size(const unsigned outputChannels, const unsigned deinterleave_max_pcm_frames)
{
    return sizeof(mhfs_cl_decoder) + (sizeof(float32_t*) * outputChannels * deinterleave_max_pcm_frames);
}

mhfs_cl_decoder *mhfs_cl_decoder_open(const unsigned outputSampleRate, const unsigned outputChannels, const unsigned deinterleave_max_pcm_frames)
{
    mhfs_cl_decoder *mhfs_d = malloc(mhfs_cl_decoder_size(outputChannels, deinterleave_max_pcm_frames));
    if(mhfs_d == NULL) return NULL;
    mhfs_d->outputSampleRate = outputSampleRate;
    mhfs_d->outputChannels = outputChannels;
    mhfs_d->has_madc = false;
    mhfs_d->dcTempOutSize = 0;
    mhfs_d->pDCTempOut = NULL;
    mhfs_d->interleaveData_pcm_frames = deinterleave_max_pcm_frames;
    return mhfs_d;
}

void mhfs_cl_decoder_close(mhfs_cl_decoder *mhfs_d)
{
    if(mhfs_d->has_madc)  ma_data_converter_uninit(&mhfs_d->madc, NULL);
    if(mhfs_d->pDCTempOut != NULL) free(mhfs_d->pDCTempOut);
    free(mhfs_d);
}

void mhfs_cl_decoder_flush(mhfs_cl_decoder *mhfs_d)
{
    if(mhfs_d->has_madc)
    {
        ma_data_converter_uninit(&mhfs_d->madc, NULL);
        mhfs_d->has_madc = false;
    }
}

mhfs_cl_error mhfs_cl_decoder_read_pcm_frames_f32(mhfs_cl_decoder *mhfs_d, mhfs_cl_track *pTrack, const uint32_t desired_pcm_frames, float32_t *outFloat, mhfs_cl_track_return_data *pReturnData)
{
    // open the decoder if needed
    if(!pTrack->dec_initialized)
    {
        MHFSCLDEC_PRINT("force open ma_decoder (not initialized)\n");
        const mhfs_cl_error openCode = mhfs_cl_track_read_pcm_frames_f32(pTrack, 0, NULL, pReturnData);
        if(openCode != MHFS_CL_SUCCESS)
        {
            return openCode;
        }
    }
    
    // fast path, no resampling / channel conversion needed
    if((pTrack->meta.sampleRate == mhfs_d->outputSampleRate) && (pTrack->meta.channels == mhfs_d->outputChannels))
    {
        return mhfs_cl_track_read_pcm_frames_f32(pTrack, desired_pcm_frames, outFloat, pReturnData);
    }
    else
    {
        // initialize the data converter
        if(mhfs_d->has_madc && (mhfs_d->madc.channelsIn != pTrack->meta.channels))
        {
            ma_data_converter_uninit(&mhfs_d->madc, NULL);
            mhfs_d->has_madc = false;            
        }
        if(!mhfs_d->has_madc)

share/public_html/static/music_worklet_inprogress/decoder/src/mhfs_cl_decoder.h  view on Meta::CPAN

        else if(mhfs_d->madc.sampleRateIn != pTrack->meta.sampleRate)
        {
            if(ma_data_converter_set_rate(&mhfs_d->madc, pTrack->meta.sampleRate, mhfs_d->outputSampleRate) != MA_SUCCESS)
            {
                MHFSCLDEC_PRINT("failed to change data converter samplerate\n");
                return MHFS_CL_ERROR;
            }
        }

        // decode
        uint64_t dec_frames_req;
        if(ma_data_converter_get_required_input_frame_count(&mhfs_d->madc, desired_pcm_frames, &dec_frames_req) != MA_SUCCESS)
        {
            MHFSCLDEC_PRINT("failed to get data converter input frame count\n");
            return MHFS_CL_ERROR;
        }
        const size_t reqBytes = dec_frames_req * sizeof(float32_t)*pTrack->meta.channels;
        if(reqBytes > mhfs_d->dcTempOutSize)
        {
            float32_t *tempOut = realloc(mhfs_d->pDCTempOut, reqBytes);
            if(tempOut == NULL)
            {
                MHFSCLDEC_PRINT("realloc failed\n");
                return MHFS_CL_ERROR;
            }
            mhfs_d->dcTempOutSize = reqBytes;
            mhfs_d->pDCTempOut = tempOut;
        }
        const mhfs_cl_error readCode = mhfs_cl_track_read_pcm_frames_f32(pTrack, dec_frames_req, mhfs_d->pDCTempOut, pReturnData);
        if((readCode != MHFS_CL_SUCCESS) || (pReturnData->frames_read == 0))
        {
            return readCode;
        }
        uint64_t decoded_frames = pReturnData->frames_read;

        // resample
        uint64_t frameCountOut = desired_pcm_frames;       
        ma_result result = ma_data_converter_process_pcm_frames(&mhfs_d->madc, mhfs_d->pDCTempOut, &decoded_frames, outFloat, &frameCountOut);
        if(result != MA_SUCCESS)
        {
            MHFSCLDEC_PRINT("resample failed\n");
            return MHFS_CL_ERROR;
        }
        pReturnData->frames_read = frameCountOut;
        return MHFS_CL_SUCCESS;
    }
}

mhfs_cl_error mhfs_cl_decoder_read_pcm_frames_f32_deinterleaved(mhfs_cl_decoder *mhfs_d, mhfs_cl_track *pTrack, const uint32_t desired_pcm_frames, float32_t *outFloat[], mhfs_cl_track_return_data *pReturnData)
{
    if(desired_pcm_frames > mhfs_d->interleaveData_pcm_frames)
    {
        MHFSCLDEC_PRINT("%s: Not enough space to deinterleave internally\n", __func__);
        return MHFS_CL_ERROR;
    }
    const mhfs_cl_error code = mhfs_cl_decoder_read_pcm_frames_f32(mhfs_d, pTrack, desired_pcm_frames, mhfs_d->interleavedData, pReturnData);
    if(code == MHFS_CL_SUCCESS)
    {
        for(unsigned i = 0; i < pReturnData->frames_read; i++)
        {
            for(unsigned j = 0; j < mhfs_d->outputChannels; j++)
            {
                const float32_t sample = mhfs_d->interleavedData[(i*mhfs_d->outputChannels) + j];
                outFloat[j][i] = sample;
            }
        }
    }
    return code;
}

share/public_html/static/music_worklet_inprogress/decoder/src/mhfs_cl_misc.h  view on Meta::CPAN

        case 14:
        ET_EXPOSE_STRUCT_BEGIN(mhfs_cl_track);
        break;
        case 15:
        ET_EXPOSE_STRUCT_END();
        break;
        case 16:
        ET_EXPOSE_STRUCT_BEGIN(mhfs_cl_track_return_data);
        break;
        case 17:
        ET_EXPOSE_STRUCT_UINT32(mhfs_cl_track_return_data, frames_read);
        break;
        case 18:
        ET_EXPOSE_STRUCT_UINT32(mhfs_cl_track_return_data, needed_offset);
        break;
        case 19:
        ET_EXPOSE_STRUCT_END();
        break;
        case 20:
        ET_EXPOSE_CONST_IV(MCT_MAI_FLD_EMPTY);
        break;

share/public_html/static/music_worklet_inprogress/decoder/src/mhfs_cl_track.h  view on Meta::CPAN

    bool dec_initialized;
    blockvf vf;
    mhfs_cl_track_blockvf_data vfData;
    mhfs_cl_track_meta_audioinfo meta;
    unsigned afterID3Offset;
    bool meta_initialized;
    uint32_t currentFrame;
} mhfs_cl_track;

typedef union {
    uint32_t frames_read;
    uint32_t needed_offset;
} mhfs_cl_track_return_data;

LIBEXPORT void mhfs_cl_track_init(mhfs_cl_track *pTrack, const unsigned blocksize);
LIBEXPORT void mhfs_cl_track_deinit(mhfs_cl_track *pTrack);
LIBEXPORT void *mhfs_cl_track_add_block(mhfs_cl_track *pTrack, const uint32_t block_start, const unsigned filesize);
LIBEXPORT mhfs_cl_error mhfs_cl_track_load_metadata(mhfs_cl_track *pTrack, mhfs_cl_track_return_data *pReturnData, const char *mime, const char *fullfilename, const uint64_t totalPCMFrameCount, const mhfs_cl_track_on_metablock on_metablock, void *con...
LIBEXPORT int mhfs_cl_track_seek_to_pcm_frame(mhfs_cl_track *pTrack, const uint32_t pcmFrameIndex);
LIBEXPORT mhfs_cl_error mhfs_cl_track_read_pcm_frames_f32(mhfs_cl_track *pTrack, const uint32_t desired_pcm_frames, float32_t *outFloat, mhfs_cl_track_return_data *pReturnData);

LIBEXPORT double mhfs_cl_track_meta_audioinfo_durationInSecs(const mhfs_cl_track_meta_audioinfo *pInfo);
LIBEXPORT const mhfs_cl_track_meta_tags_comment *mhfs_cl_track_meta_tags_next_comment(mhfs_cl_track_meta_tags *pTags);
#endif /* mhfs_cl_track.h */

#if defined(MHFSCLTRACK_IMPLEMENTATION)
#ifndef mhfs_cl_track_c
#define mhfs_cl_track_c

#ifndef MHFSCLTR_PRINT_ON

share/public_html/static/music_worklet_inprogress/decoder/src/mhfs_cl_track.h  view on Meta::CPAN

{
    if(pTrack->dec_initialized) ma_decoder_uninit(&pTrack->decoder);
    blockvf_deinit(&pTrack->vf);
}

void *mhfs_cl_track_add_block(mhfs_cl_track *pTrack, const uint32_t block_start, const unsigned filesize)
{
    return blockvf_add_block(&pTrack->vf, block_start, filesize);
}

// mhfs_cl_track_read_pcm_frames_f32 will catch the error if we dont here
int mhfs_cl_track_seek_to_pcm_frame(mhfs_cl_track *pTrack, const uint32_t pcmFrameIndex)
{
    if(pTrack->dec_initialized)
    {
        if(pcmFrameIndex >= pTrack->meta.totalPCMFrameCount)
        {
            // allow seeking to 0 always
            if(pcmFrameIndex != 0)
            {
                return 0;
            }

share/public_html/static/music_worklet_inprogress/decoder/src/mhfs_cl_track.h  view on Meta::CPAN

        if(memcmp(id, "ID3", 3) != 0) break;
        uint16_t version;
        uint8_t flags;
        uint32_t tagSize;
        const mhfs_cl_error parseError = mhfs_cl_parse_id3_header_after_magic(&pTrack->vf, &pReturnData->needed_offset, &version, &flags, &tagSize);
        if(parseError != MHFS_CL_SUCCESS)
        {
            return parseError;
        }
        MHFSCLTR_PRINT("id3 version: %X %X\n", (version >> 8) & 0xFF, version & 0xFF);
        const uint8_t *frames;
        const blockvf_error frameError = blockvf_read_view(&pTrack->vf, tagSize, &frames, &pReturnData->needed_offset);
        if(frameError != BLOCKVF_SUCCESS)
        {
            return mhfs_cl_error_from_blockvf_error(frameError);
        }
        while(tagSize >= 10) {
            const uint32_t framesize = unsynchsafe_32(unaligned_beu32_to_native(frames+4));
            unsigned frameheadersize = 10;
            MHFSCLTR_PRINT("id3 frameid: %c %c %c %c size: %u\n", frames[0], frames[1], frames[2], frames[3], framesize);
            if(frames[9] & 0x3) {
                MHFSCLTR_PRINT("unsync applied\n");
            }
            else if(frames[9] & 0x1) {
                const uint32_t dli = unsynchsafe_32(unaligned_beu32_to_native(&frames[10]));
                MHFSCLTR_PRINT("data length indicator %u\n", dli);
                frameheadersize += 4;
            }
            if((framesize+frameheadersize) > tagSize)
            {
                MHFSCLTR_PRINT("id3 frame exceeds tag!, size left: %u\n", tagSize-frameheadersize);
                break;
            }
            if(memcmp(frames, "APIC", 4) == 0)
            {
                if(on_metablock != NULL)
                {
                    const uint8_t *apicCurrentItem = &frames[frameheadersize];
                    const uint8_t encoding = apicCurrentItem[0]; apicCurrentItem++;
                    const char *mime = (char*)apicCurrentItem;
                    const uint32_t mimeSize = strlen(mime); apicCurrentItem += (mimeSize+1);
                    uint8_t type = apicCurrentItem[0]; apicCurrentItem++;
                    const char *desc = (char*)apicCurrentItem;
                    const uint32_t descSize = strlen(desc); apicCurrentItem += (descSize+1);
                    uint32_t pictureDataSize = framesize - 4 - mimeSize - descSize;
                    const uint8_t *pictureData = apicCurrentItem;
                    if((pictureData+pictureDataSize) != (frames + (framesize+frameheadersize)))
                    {
                        MHFSCLTR_PRINT("picture size is messed up\n");
                    }
                    MHFSCLTR_PRINT("APIC encoding: %X mime: %s type: %X, desc: %s\n", encoding, mime, type, desc);
                    mhfs_cl_track_meta_picture picture = {
                        .pictureType = type,
                        .mimeSize = mimeSize,
                        .mime = (uint8_t*)mime,
                        .descSize = descSize,
                        .desc = (uint8_t*)desc,
                        .pictureDataSize = pictureDataSize,
                        .pictureData = pictureData
                    };
                    on_metablock(context, MHFS_CL_TRACK_M_PICTURE, &picture);
                }
            }

            tagSize -= (framesize+frameheadersize);
            frames += (framesize+frameheadersize);
        }
    }
    pTrack->vf.fileoffset = startoffset;

    // check for magic
    const uint8_t *id;
    const blockvf_error idError = blockvf_read_view(&pTrack->vf, 4, &id, &pReturnData->needed_offset);
    if(idError != BLOCKVF_SUCCESS)
    {
        return mhfs_cl_error_from_blockvf_error(idError);

share/public_html/static/music_worklet_inprogress/decoder/src/mhfs_cl_track.h  view on Meta::CPAN

    {
        const uint8_t *flagsBytes;
        const blockvf_error xingFlagsError = blockvf_read_view(&pTrack->vf, 4, &flagsBytes, &pReturnData->needed_offset);
        if(xingFlagsError != BLOCKVF_SUCCESS)
        {
            return mhfs_cl_error_from_blockvf_error(xingFlagsError);
        }
        const uint32_t xingFlags = unaligned_beu32_to_native(flagsBytes);
        if(xingFlags & 0x1)
        {
            const uint8_t *framesBytes;
            const blockvf_error framesError = blockvf_read_view(&pTrack->vf, 4, &framesBytes, &pReturnData->needed_offset);
            if(framesError != BLOCKVF_SUCCESS)
            {
                return mhfs_cl_error_from_blockvf_error(framesError);
            }
            const uint32_t frames = unaligned_beu32_to_native(framesBytes);
            MHFSCLTR_PRINT("xing frames %u\n", frames);
            // FIX ME FIX ME we add 1 to mp3frames because the decoder will currently (foolishly) decode the xing mp3frame
            mhfs_cl_track_meta_audioinfo_init(&pTrack->meta, (frames + 1) * 1152, sampleRate, channels, MCT_MAI_FLD_BITRATE, 0, bitrate);
            if(on_metablock != NULL)
            {
                on_metablock(context, MHFS_CL_TRACK_M_AUDIOINFO, &pTrack->meta);
            }
            pTrack->meta_initialized = true;
            return MHFS_CL_SUCCESS;
        }
        return MHFS_CL_ERROR;
    }

share/public_html/static/music_worklet_inprogress/decoder/src/mhfs_cl_track.h  view on Meta::CPAN

    }
    if(memcmp(vbriMagic, "VBRI", 4) == 0)
    {
        MHFSCLTR_PRINT("VBRI found\n");
        const uint8_t *vbriFields;
        const blockvf_error vbriFieldsError = blockvf_read_view(&pTrack->vf, 22, &vbriFields, &pReturnData->needed_offset);
        if(vbriFieldsError != BLOCKVF_SUCCESS)
        {
            return mhfs_cl_error_from_blockvf_error(vbriFieldsError);
        }
        const uint32_t frames = unaligned_beu32_to_native(&vbriFields[10]);
        MHFSCLTR_PRINT("vbri frames %u\n", frames);
        // FIX ME FIX ME need to verify pcmframes  calculation
        mhfs_cl_track_meta_audioinfo_init(&pTrack->meta, (frames + 1) * 1152, sampleRate, channels, MCT_MAI_FLD_BITRATE, 0, bitrate);
        if(on_metablock != NULL)
        {
            on_metablock(context, MHFS_CL_TRACK_M_AUDIOINFO, &pTrack->meta);
        }
        pTrack->meta_initialized = true;
        return MHFS_CL_SUCCESS;
    }

    // TODO

share/public_html/static/music_worklet_inprogress/decoder/src/mhfs_cl_track.h  view on Meta::CPAN

            sampleRate = unaligned_leu32_to_native(&fmtChunk[4]);
            /* byterate is here */
            const unsigned blockAlign = unaligned_leu16_to_native(&fmtChunk[12]);
            bitsPerSample = unaligned_leu16_to_native(&fmtChunk[14]);
            if(chunkSize > 16)
            {

            }

            /*
            The bytes per frame is a bit ambiguous. It can be either be based on the bits per sample, or the block align. The way I'm doing it here
            is that if the bits per sample is a multiple of 8, use floor(bitsPerSample*channels/8), otherwise fall back to the block align.
            */
            if ((bitsPerSample & 0x7) == 0) {
                /* Bits per sample is a multiple of 8. */
                bytesPerPCMFrame = (bitsPerSample * channels) >> 3;
            } else {
                bytesPerPCMFrame = blockAlign;
            }

            /* Validation for known formats. a-law and mu-law should be 1 byte per channel. If it's not, it's not decodable. */

share/public_html/static/music_worklet_inprogress/decoder/src/mhfs_cl_track.h  view on Meta::CPAN

    if(retval != MHFS_CL_SUCCESS)
    {
        return retval;
    }

    // read and store the metadata
    const unsigned savefileoffset = pTrack->vf.fileoffset;
    uint64_t totalPCMFrameCount = pTrack->meta.totalPCMFrameCount;
    if(pTrack->decoderConfig.encodingFormat != ma_encoding_format_mp3)
    {
        ma_decoder_get_length_in_pcm_frames(&pTrack->decoder, &totalPCMFrameCount);
    }
    MHFSCLTR_PRINT("decoder output samplerate %u\n", pTrack->decoder.outputSampleRate);
    mhfs_cl_track_meta_audioinfo_init(&pTrack->meta, totalPCMFrameCount, pTrack->decoder.outputSampleRate, pTrack->decoder.outputChannels, MCT_MAI_FLD_EMPTY, 0, 0);
    if(on_metablock != NULL)
    {
        on_metablock(context, MHFS_CL_TRACK_M_AUDIOINFO, &pTrack->meta);
    }

    if(retval == MHFS_CL_SUCCESS)
    {

share/public_html/static/music_worklet_inprogress/decoder/src/mhfs_cl_track.h  view on Meta::CPAN


    pTrack->decoderConfig.encodingFormat = encFmt;
    if(ioError.initialized)
    {
        pReturnData->needed_offset = ioError.neededOffset;
        return ioError.res;
    }
    return MHFS_CL_ERROR;
}

mhfs_cl_error mhfs_cl_track_read_pcm_frames_f32(mhfs_cl_track *pTrack, const uint32_t desired_pcm_frames, float32_t *outFloat, mhfs_cl_track_return_data *pReturnData)
{
    mhfs_cl_track_return_data rd;
    if(pReturnData == NULL) pReturnData = &rd;
    mhfs_cl_error retval = MHFS_CL_SUCCESS;

    // initialize the decoder if necessary
    if(!pTrack->meta_initialized)
    {
        MHFSCLTR_PRINT("metadata is somehow not initialized\n");
        return MHFS_CL_ERROR;
    }
    if(!pTrack->dec_initialized)
    {
        retval = mhfs_cl_track_open_ma_decoder(pTrack, &pReturnData->needed_offset);
        if(retval != MHFS_CL_SUCCESS) return retval;
    }

    // seek to sample
    MHFSCLTR_PRINT("seek to %u d_pcmframes %u\n", pTrack->currentFrame, desired_pcm_frames);
    const uint32_t currentPCMFrame32 = 0xFFFFFFFF;
    mhfs_cl_track_blockvf_ma_decoder_call_before(pTrack, true);
    const ma_result seekRes = ma_decoder_seek_to_pcm_frame(&pTrack->decoder, pTrack->currentFrame);
    const mhfs_cl_error seekBlockRes = mhfs_cl_track_blockvf_ma_decoder_call_after(pTrack, true, &pReturnData->needed_offset);
    if(seekBlockRes != MHFS_CL_SUCCESS)
    {
        MHFSCLTR_PRINT("%s: failed seek_to_pcm_frame NOT OK current: %u desired: %u\n", __func__, currentPCMFrame32, pTrack->currentFrame);
        return seekBlockRes;
    }
    if(seekRes != MA_SUCCESS)
    {
        MHFSCLTR_PRINT("%s: seek failed current: %u desired: %u ma_result %d\n", __func__, currentPCMFrame32, pTrack->currentFrame, seekRes);
        retval = MHFS_CL_ERROR;
        goto mhfs_cl_track_read_pcm_frames_f32_FAIL;
    }

    // finally read
    uint64_t frames_decoded = 0;
    if(desired_pcm_frames != 0)
    {
        uint64_t toread = desired_pcm_frames;

        // decode to pcm
        mhfs_cl_track_blockvf_ma_decoder_call_before(pTrack, true);
        ma_result decRes = ma_decoder_read_pcm_frames(&pTrack->decoder, outFloat, toread, &frames_decoded);
        const mhfs_cl_error decBlockRes = mhfs_cl_track_blockvf_ma_decoder_call_after(pTrack, true, &pReturnData->needed_offset);
        if(decBlockRes != MHFS_CL_SUCCESS)
        {
            MHFSCLTR_PRINT("mhfs_cl_track_read_pcm_frames_f32_mem: failed read_pcm_frames_f32\n");
            return decBlockRes;
        }
        if(decRes != MA_SUCCESS)
        {
            MHFSCLTR_PRINT("mhfs_cl_track_read_pcm_frames_f32_mem: failed read_pcm_frames_f32(decode), ma_result %d\n", decRes);
            retval = MHFS_CL_ERROR;
            if(decRes == MA_AT_END)
            {
                MHFSCLTR_PRINT("MA_AT_END\n"); // not a real error
            }
            goto mhfs_cl_track_read_pcm_frames_f32_FAIL;
        }
        if(frames_decoded != desired_pcm_frames)
        {
            MHFSCLTR_PRINT("mhfs_cl_track_read_pcm_frames_f32_mem: expected %u decoded %"PRIu64"\n", desired_pcm_frames, frames_decoded);
        }
        pTrack->currentFrame += frames_decoded;
    }

    MHFSCLTR_PRINT("returning from pTrack->currentFrame: %u, totalFrames %"PRIu64" frames_decoded %"PRIu64" desired %u\n", pTrack->currentFrame, pTrack->meta.totalPCMFrameCount, frames_decoded, desired_pcm_frames);
    pReturnData->frames_read = frames_decoded;
    return MHFS_CL_SUCCESS;

mhfs_cl_track_read_pcm_frames_f32_FAIL:
    if(pTrack->dec_initialized)
    {
        ma_decoder_uninit(&pTrack->decoder);
        pTrack->dec_initialized = false;
    }
    return retval;
}

#endif  /* mhfs_cl_track_c */
#endif  /* MHFSCLTRACK_IMPLEMENTATION */

share/public_html/static/music_worklet_inprogress/player/AudioWriterReader.js  view on Meta::CPAN

    
    gettime() {
        const count = this.getcount();
        return  count / this._samplerate;         
    }

    getspace() {
        return this._rb.getspace();
    }
    
    static createpreq(framecount, numberofchannels) {
        return {
            'rb' : RingBuffer.create(Float32Array, framecount, numberofchannels),
            'messages' : RingBuffer.create(Uint32Array, 4095, 2)
        };
    }
}

class Float32AudioRingBufferReader extends Float32AudioRingBuffer  {
    constructor(rb, samplerate, messages){
        super(rb, samplerate, messages);
        this._msgreader =  new RingBufferReader(messages);               
        this._reader = new RingBufferReader(rb);        
        this._inmessage = [new Uint32Array(1), new Uint32Array(1)];
    }
    
    static create(framecount, numberofchannels, samplerate) {
        const prereq = super.createpreq(framecount, numberofchannels); 
        return new Float32AudioRingBufferReader(prereq.rb, samplerate, prereq.messages);
    }
    
    static from(obj) {
        const rb = new RingBuffer(Float32Array, obj._rb._capacity, obj._rb._subbuffercount, obj._rb._sharedvarssab, obj._rb._sab);
        const messages = new RingBuffer(Uint32Array, obj._messages._capacity, obj._messages._subbuffercount, obj._messages._sharedvarssab, obj._messages._sab);
        return new Float32AudioRingBufferReader(rb, obj._samplerate, messages);
    }

    // (READER ONLY) reduces the amount of data to read. never move it farther than writehead 

share/public_html/static/music_worklet_inprogress/player/AudioWriterReader.js  view on Meta::CPAN

}

class Float32AudioRingBufferWriter extends Float32AudioRingBuffer{
    constructor(rb, samplerate, messages){        
        super(rb, samplerate, messages);
        this._msgwriter = new RingBufferWriter(messages);
        this._writer = new RingBufferWriter(rb);
        this._outmessage = [new Uint32Array(1), new Uint32Array(1)];
    }

    static create(framecount, numberofchannels, samplerate) {
        const prereq = super.createpreq(framecount, numberofchannels); 
        return new Float32AudioRingBufferWriter(prereq.rb, samplerate, prereq.messages);
    }
    
    to() {
        return {
            '_rb' : this._rb.to(),
            '_messages' : this._messages.to(),
            '_samplerate' : this._samplerate        
        };
    }

share/public_html/static/music_worklet_inprogress/player/mhfsplayer.js  view on Meta::CPAN


        // determine the current track if still unknown
        track ||= that.AudioQueue[0].track;
        that.playlistCursor = track;
        QueueUpdate.track = track;

        // show the track
        that.gui.OnQueueUpdate(QueueUpdate);
    }

    // passes in the dest array, the maximum frames to read and when they will be played
    const ReadAudioQueue = function (dest, count, when) {
        UpdateTrack();
        let framesWritten = 0;
        let destoffset = 0;
        for(let i = 0; that.AudioQueue[i]; i++) {
            const item = that.AudioQueue[i];
            if(item.queued) continue;
            if(item.sampleCount === 0) break;
            const toread = Math.min(count, item.sampleCount);
            that.decoderdatareader.read(dest, toread, destoffset);         
            framesWritten += toread;
            item.sampleCount -= toread;
            ProcessTimes(item, toread, when);        
            item.queued = item.donedecode && (item.sampleCount === 0);
            if(!item.queued) break;
            count -= toread;
            if(count === 0) break;
            destoffset = framesWritten;
            when += (toread / that.sampleRate); 
        }
        return framesWritten;
    };

    // The Audio Pump
    const PumpAudioData = [];
    for(let i = 0; i < that.channels; i++) {
        PumpAudioData[i] = new Float32Array(that.ARBLen);
    }
    const PumpAudioZeros = [];
    for(let i = 0; i < that.channels; i++) {
        PumpAudioZeros[i] = new Float32Array(that.ARBLen);

share/public_html/static/music_worklet_inprogress/player/mhfsplayer.js  view on Meta::CPAN

                while(that.decoderdatawriter.getspace() < that.ac.sampleRate) {
                    if(!(await abortablesleep_status(250, mysignal)))
                    {
                        break TRACKLOOP;                    
                    }
                }
                
                // decode
                let decdata;
                try {
                    decdata = await decoder.read_pcm_frames_f32_arrs(todec, mysignal);
                    pbtrack.startedLoading = undefined;
                    if(!decdata) break SAMPLELOOP;
                }
                catch(error) {
                    console.error(error);
                    if(mysignal.aborted) {
                        break TRACKLOOP;
                    }
                    await decoder.closeCurrentTrack();
                    break SAMPLELOOP;

share/public_html/static/music_worklet_inprogress/player/worklet_processor_ff.js  view on Meta::CPAN

    
    gettime() {
        const count = this.getcount();
        return  count / this._samplerate;         
    }

    getspace() {
        return this._rb.getspace();
    }
    
    static createpreq(framecount, numberofchannels) {
        return {
            'rb' : RingBuffer.create(Float32Array, framecount, numberofchannels),
            'messages' : RingBuffer.create(Uint32Array, 4095, 2)
        };
    }
}

class Float32AudioRingBufferReader extends Float32AudioRingBuffer  {
    constructor(rb, samplerate, messages){
        super(rb, samplerate, messages);
        this._msgreader =  new RingBufferReader(messages);               
        this._reader = new RingBufferReader(rb);        
        this._inmessage = [new Uint32Array(1), new Uint32Array(1)];
    }
    
    static create(framecount, numberofchannels, samplerate) {
        const prereq = super.createpreq(framecount, numberofchannels); 
        return new Float32AudioRingBufferReader(prereq.rb, samplerate, prereq.messages);
    }
    
    static from(obj) {
        const rb = new RingBuffer(Float32Array, obj._rb._capacity, obj._rb._subbuffercount, obj._rb._sharedvarssab, obj._rb._sab);
        const messages = new RingBuffer(Uint32Array, obj._messages._capacity, obj._messages._subbuffercount, obj._messages._sharedvarssab, obj._messages._sab);
        return new Float32AudioRingBufferReader(rb, obj._samplerate, messages);
    }

    // (READER ONLY) reduces the amount of data to read. never move it farther than writehead 

share/public_html/static/music_worklet_inprogress/player/worklet_processor_ff.js  view on Meta::CPAN

}

class Float32AudioRingBufferWriter extends Float32AudioRingBuffer{
    constructor(rb, samplerate, messages){        
        super(rb, samplerate, messages);
        this._msgwriter = new RingBufferWriter(messages);
        this._writer = new RingBufferWriter(rb);
        this._outmessage = [new Uint32Array(1), new Uint32Array(1)];
    }

    static create(framecount, numberofchannels, samplerate) {
        const prereq = super.createpreq(framecount, numberofchannels); 
        return new Float32AudioRingBufferWriter(prereq.rb, samplerate, prereq.messages);
    }
    
    to() {
        return {
            '_rb' : this._rb.to(),
            '_messages' : this._messages.to(),
            '_samplerate' : this._samplerate        
        };
    }

share/templates/music_legacy.html  view on Meta::CPAN

</div>
</div>
<div class="footer row" style="background-color:blue;">    
  
    <table border="1" width="80%">
    <tr><th>Previous</th><th>Now Playing</th><th>Next</th></tr>
	<tr><td><div id="prev_text"></div></td><td><div id="play_text"></div></td><td><div id="next_text"></div></td></tr>  
	</table> 
    <input type="button" value="PREV" onclick="playPreviousTrack();"><audio id="mainplayer" controls="controls" preload="none"> <source id="audio_src" src=""></source></audio><input type="button" value="NEXT" onclick="playNextTrack()">
	
    <iframe src="static/250ms_silence.mp3" allow="autoplay" id="audio" style="display:none"></iframe>
</div>
    <script>
        function GetItemPath(elm) {
            var els = [];
            var lastitem;
            do {                        
                var elmtemp = elm;
                while(elmtemp.firstChild)
                {
                    elmtemp = elmtemp.firstChild;



( run in 2.136 seconds using v1.01-cache-2.11-cpan-e1769b4cff6 )