Initial commit

This commit is contained in:
2017-02-13 02:53:48 +01:00
commit b347a8e22b
25 changed files with 1449 additions and 0 deletions

8
src/Card/Card.php Normal file
View File

@ -0,0 +1,8 @@
<?php
namespace NoccyLabs\PulseAudio\Card;
class Card
{
}

8
src/Card/CardList.php Normal file
View File

@ -0,0 +1,8 @@
<?php
namespace NoccyLabs\PulseAudio\Card;
class CardList
{
}

8
src/Client/Client.php Normal file
View File

@ -0,0 +1,8 @@
<?php
namespace NoccyLabs\PulseAudio\Client;
class Client
{
}

View File

@ -0,0 +1,8 @@
<?php
namespace NoccyLabs\PulseAudio\Client;
class ClientList
{
}

133
src/Helper/Pacmd.php Normal file
View File

@ -0,0 +1,133 @@
<?php
namespace NoccyLabs\PulseAudio\Helper;
class Pacmd
{
public static function call($command, array $args=[])
{
// assemble command lin
$cmdl = array_merge([ $command ], $args);
$cmdl = join(" ", array_map("escapeshellarg", $cmdl));
// call pacmd
exec("pacmd {$cmdl}", $output, $retval);
// handle errors
if ($retval != 0) {
throw new \RuntimeException("Failed to call pacmd. exitcode={$retval}");
}
// return output
return $output;
}
public static function query($command, array $args=[])
{
$output = Pacmd::call($command, $args);
$status = array_shift($output);
// printf("[pacmd] %s\n", $status);
$parser = new ListParser();
$output = $parser->parse($output);
return $output;
}
}
class ListParser
{
public function parse(array $lines)
{
$lines = $this->prepare($lines);
return $this->parseRecursive($lines, 0);
}
private function prepare(array $lines)
{
$data = [];
foreach ($lines as $line) {
if ($line=="") continue;
if ($line[0] == " ") {
$data[] = [ 0, trim($line) ];
} else {
$depth = 0;
while ($line[0]=="\t") {
$depth++;
$line = substr($line,1);
}
$data[] = [ $depth, $line ];
}
}
return $data;
}
private function parseRecursive(array $lines, $current=0)
{
$ret = [];
while (count($lines)>0) {
$line = array_shift($lines);
$children = [];
while ((count($lines)>0) && ($lines[0][0]>$current)) {
$children[] = array_shift($lines);
}
if (count($children)>0) {
$key = trim(str_replace("index: ","", $line[1]),":* ");
$ret[$key] = $this->parseRecursive($children, $line[0]+1);
} else {
if (strpos($line[1]," = ")!==false) {
list ($k,$v) = array_map("trim", explode("=",$line[1],2));
$ret[$k] = $this->parseVal($v);
} elseif (strpos($line[1],": ")!==false) {
list ($k,$v) = array_map("trim", explode(":",$line[1],2));
$ret[$k] = $this->parseVal($v);
}
}
}
return $ret;
}
private function parseVal($value)
{
if ($value=="") {
return null;
} elseif ($value=="yes") {
return true;
} elseif ($value=="no") {
return false;
} elseif ($value[0]=="<") {
$kvs = trim($value,"<>");
if (strpos($kvs,"=")===false) {
return $kvs;
}
$kvs = explode(" ",$kvs);
$val = [];
foreach ($kvs as $kv) {
list ($k,$v) = explode("=",$kv,2);
$val[$k] = $v;
}
return $val;
} elseif ($value[0]=="\"") {
return trim($value,"\"");
} else {
return $value;
}
}
private function parseKeyVal($kvs)
{
$kvs = explode(" ",$kvs,2 );
$val = [];
foreach ($kvs as $kv) {
list ($k,$v) = explode("=",$kv,2);
$val[$k] = $this->parseKeyVal($v);
}
return $val;
}
}

94
src/Module/Module.php Normal file
View File

@ -0,0 +1,94 @@
<?php
namespace NoccyLabs\PulseAudio\Module;
use NoccyLabs\PulseAudio\PropertyList;
/**
* Contains information on a PulseAudio module.
*
*
*/
class Module
{
/** @var string */
protected $name;
/** @var array */
protected $arguments = [];
/** @var int */
protected $used;
/** @var bool */
protected $loadOnce;
/** @var PropertyList */
protected $properties;
/**
*
*
* @param string $name
* @param array $arguments
* @param int $used
* @param bool $loadOnce
* @param array $properties
*/
public function __construct(array $info)
{
$this->name = $info['name'];
$this->arguments = $info['argument'];
$this->used = $info['used'];
$this->loadOnce = $info['load once'];
$props = array_key_exists('properties',$info)?$info['properties']:[];
$this->properties = new PropertyList($props, true);
}
/**
*
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
*
*
* @return array
*/
public function getArguments()
{
return $this->arguments;
}
/**
*
*
* @return int
*/
public function getUsed()
{
return $this->used;
}
/**
*
*
* @return bool
*/
public function getLoadOnce()
{
return $this->loadOnce;
}
/**
*
*
* @return PropertyList
*/
public function getProperties()
{
return $this->properties;
}
}

65
src/Module/ModuleList.php Normal file
View File

@ -0,0 +1,65 @@
<?php
namespace NoccyLabs\PulseAudio\Module;
use NoccyLabs\PulseAudio\Helper\Pacmd;
use IteratorAggregate;
use ArrayIterator;
class ModuleList implements IteratorAggregate
{
protected $modules = [];
public function __construct()
{
$modules = Pacmd::query("list-modules");
foreach ($modules as $info) {
$this->modules[] = new Module($info);
}
}
public function getIterator()
{
return new ArrayIterator($this->modules);
}
/**
* Load a module
*
* @param string $name
* @param array $args
*/
public function loadModule($name, array $args=[])
{}
/**
* Unload a loaded module
*
* @return bool
*/
public function unloadModule($name)
{}
/**
*
*
* @return Module[]
* @throws InvalidArgumentException
*/
public function getModules($name)
{
$ret = [];
foreach ($this->modules as $module) {
if ($module->getName() == $name) {
$ret[] = $module;
}
}
return $ret;
}
public function hasModule($name)
{
}
}

61
src/PropertyList.php Normal file
View File

@ -0,0 +1,61 @@
<?php
namespace NoccyLabs\PulseAudio;
use ArrayAccess;
use IteratorAggregate;
use Countable;
class PropertyList implements ArrayAccess, IteratorAggregate, Countable
{
protected $properties = [];
protected $readOnly = false;
public function __construct(array $properties=[], $readOnly=false)
{
$this->properties = $properties;
$this->readOnly = $readOnly;
}
public function getIterator()
{
return new ArrayIterator($this->properties);
}
public function offsetGet($key)
{
if (!array_key_exist($key, $this->properties)) {
throw new InvalidArgumentException("No such property: {$key}");
}
return $this->properties[$key];
}
public function offsetSet($key, $value)
{
if ($this->readOnly) {
return;
}
$this->properties[$key] = $value;
}
public function offsetUnset($key)
{
if ($this->readOnly) {
return;
}
unset($this->properties[$key]);
}
public function offsetExists($key)
{
return array_key_exists($key, $this->properties);
}
public function count()
{
return count($this->properties);
}
}

56
src/PulseAudio.php Normal file
View File

@ -0,0 +1,56 @@
<?php
namespace NoccyLabs\PulseAudio;
use NoccyLabs\PulseAudio\Module\ModuleList;
use NoccyLabs\PulseAudio\Sink\SinkList;
use NoccyLabs\PulseAudio\Sink\SinkInputList;
use NoccyLabs\PulseAudio\Source\SourceList;
use NoccyLabs\PulseAudio\Source\SourceOutputList;
use NoccyLabs\PulseAudio\Client\ClientList;
use NoccyLabs\PulseAudio\Card\CardList;
class PulseAudio
{
/**
*
*
* @return ModuleList
*/
public function getModules()
{
return new ModuleList();
}
public function getSinks()
{
return new SinkList();
}
public function getSinkInputs()
{
return new SinkInputList();
}
public function getSources()
{
return new SourceList();
}
public function getSourceOutputs()
{
return new SourceOutputList();
}
public function getClients()
{
return new ClientList();
}
public function getCards()
{
return new CardList();
}
}

0
src/Sink/Recorder.php Normal file
View File

60
src/Sink/Sink.php Normal file
View File

@ -0,0 +1,60 @@
<?php
namespace NoccyLabs\PulseAudio\Sink;
use NoccyLabs\PulseAudio\PropertyList;
class Sink
{
protected $index;
protected $name;
protected $card;
protected $driver;
protected $properties;
public function __construct($index, array $sink)
{
$this->index = $index;
$this->name = $sink['name'];
$this->card = $sink['card'];
$this->driver = $sink['driver'];
$this->properties = new PropertyList($sink['properties'], true);
}
public function getProperties()
{
return $this->properties;
}
public function getIndex()
{
return $this->index;
}
public function getName()
{
return $this->name;
}
public function getCard()
{
return $this->card;
}
public function getDriver()
{
return $this->driver;
}
public function moveToSink(Sink $sink)
{
}
}

47
src/Sink/SinkInput.php Normal file
View File

@ -0,0 +1,47 @@
<?php
namespace NoccyLabs\PulseAudio\Sink;
use NoccyLabs\PulseAudio\PropertyList;
class SinkInput
{
protected $index;
protected $sink;
protected $client;
protected $properties;
public function __construct($index, array $input=[])
{
$this->index = $index;
$this->sink = $input['sink'];
$this->client = $input['client'];
$this->properties = new PropertyList($input['properties'], true);
}
public function getIndex()
{
return $this->index;
}
public function getSink()
{
return $this->sink;
}
public function getClient()
{
return $this->client;
}
public function moveToSink(Sink $sink)
{
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace NoccyLabs\PulseAudio\Sink;
use NoccyLabs\PulseAudio\Helper\Pacmd;
use ArrayAccess;
use ArrayIterator;
use IteratorAggregate;
use Countable;
class SinkInputList implements ArrayAccess, IteratorAggregate, Countable
{
protected $inputs = [];
public function __construct()
{
$inputs = Pacmd::query("list-sink-inputs");
foreach ($inputs as $index=>$input) {
$this->inputs[] = new SinkInput($index, $input);
}
}
public function createSink($name)
{
}
public function destroySink($id)
{}
public function getIterator()
{
return new ArrayIterator($this->inputs);
}
public function offsetGet($key)
{
foreach ($this->inputs as $input) {
if ($input->getIndex() == $key) {
return $input;
}
}
return null;
}
public function offsetSet($key, $value)
{}
public function offsetUnset($key)
{}
public function offsetExists($key)
{
return array_key_exists($key, $this->inputs);
}
public function count()
{
return count($this->inputs);
}
}

68
src/Sink/SinkList.php Normal file
View File

@ -0,0 +1,68 @@
<?php
namespace NoccyLabs\PulseAudio\Sink;
use NoccyLabs\PulseAudio\Helper\Pacmd;
use ArrayAccess;
use IteratorAggregate;
use ArrayIterator;
use Countable;
class SinkList implements ArrayAccess, IteratorAggregate, Countable
{
protected $sinks = [];
public function __construct()
{
$sinks = Pacmd::query("list-sinks");
foreach ($sinks as $index=>$sink) {
$this->sinks[] = new Sink($index, $sink);
}
}
public function createSink($name)
{
}
public function createRecorder($name)
{
}
public function destroySink($id)
{
}
public function getIterator()
{
return new ArrayIterator($this->sinks);
}
public function offsetGet($key)
{
if (!array_key_exist($key, $this->sinks)) {
throw new InvalidArgumentException("No such sink: {$key}");
}
return $this->sinks[$key];
}
public function offsetSet($key, $value)
{}
public function offsetUnset($key)
{}
public function offsetExists($key)
{
return array_key_exists($key, $this->sinks);
}
public function count()
{
return count($this->sinks);
}
}

8
src/Source/Source.php Normal file
View File

@ -0,0 +1,8 @@
<?php
namespace NoccyLabs\PulseAudio\Source;
class Source
{
}

View File

@ -0,0 +1,8 @@
<?php
namespace NoccyLabs\PulseAudio\Source;
class SourceList
{
}

View File

@ -0,0 +1,8 @@
<?php
namespace NoccyLabs\PulseAudio\Source;
class SourceOutput
{
}

View File

@ -0,0 +1,8 @@
<?php
namespace NoccyLabs\PulseAudio\Source;
class SourceOutputList
{
}