swf2ass/src/AudioStream.php

100 lines
2.6 KiB
PHP

<?php
namespace swf2ass;
class AudioStream{
const FORMAT_UNCOMPRESSED_NATIVE_ENDIAN = 0;
const FORMAT_UNCOMPRESSED_LITTLE_ENDIAN = 3;
const FORMAT_ADPCM = 1;
const FORMAT_MP3 = 2;
const FORMAT_NELLYMOSER_16 = 4;
const FORMAT_NELLYMOSER_8 = 5;
const FORMAT_NELLYMOSER = 6;
const FORMAT_SPEEX = 11;
private int $format;
private int $sampleRate;
private int $sampleSize;
private int $channels;
private ?int $start = null;
private array $frames = [];
public function __construct(int $format, int $sampleRate, int $sampleSize, int $channels){
$this->format = $format;
$this->sampleRate = $sampleRate;
$this->sampleSize = $sampleSize;
$this->channels = $channels;
}
public function getFormat() : int{
return $this->format;
}
public function setStartFrame(?int $start){
$this->start = $start;
}
public function getStartFrame() : ?int{
return $this->start;
}
public function addStreamBlock(array $node){
if($node["tagType"] !== "SoundStreamBlock"){
throw new \Exception("Invalid tag ". $node["tagType"] );
}
switch ($this->format){
case self::FORMAT_MP3:
$this->addMP3SoundData($node["soundStreamData"]);
break;
}
}
private function addMP3SoundData(string $bin){
$offset = 0;
[,$sampleCount] = unpack("v", $bin, $offset);
$offset += 2;
[,$seekSamples] = unpack("s", $bin, $offset);
$offset += 2;
$frameSize = $this->sampleRate <= 11025 ? 576 : 1152;
$this->frames[] = substr($bin, $offset);
}
public function getAudioData() : string{
//TODO: header?
return implode("", $this->frames);
}
public static function fromSoundStreamHeadTag(array $node) : ?AudioStream{
if(!isset($node["streamSoundCompression"]) or !isset($node["streamSoundRate"]) or !isset($node["streamSoundSize"]) or !isset($node["streamSoundType"])){
return null;
}
$rate = null;
switch ($node["streamSoundRate"]){
case 0:
$rate = 5512;
break;
case 1:
$rate = 11025;
break;
case 2:
$rate = 22050;
break;
case 3:
$rate = 44100;
break;
}
return new AudioStream($node["streamSoundCompression"], $rate, $node["streamSoundSize"] === 1 ? 16 : 8, $node["streamSoundType"] === 1 ? 2 : 1);
}
}