Completed
Push — master ( 7b220e...d0f73c )
by Patrick
08:53
created

Stop   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 75
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 3
dl 0
loc 75
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 3
A fromFrequency() 0 9 2
A getFrequency() 0 6 1
A getStringLength() 0 4 1
A centsToStringLength() 0 4 1
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace ExtendedStrings\Strings;
6
7
class Stop
8
{
9
    private $stringLength;
10
11
    /**
12
     * Stop constructor.
13
     *
14
     * @param float $stringLength The length of string that is left vibrating,
15
     *                            as a fraction.
16
     */
17
    public function __construct(float $stringLength)
18
    {
19
        if ($stringLength < 0 || $stringLength > 1) {
20
            throw new \InvalidArgumentException(sprintf('Invalid string length: %f', $stringLength));
21
        }
22
23
        $this->stringLength = $stringLength;
24
    }
25
26
    /**
27
     * Create a Stop instance from a frequency over a string.
28
     *
29
     * @param float                                             $frequency
30
     * @param \ExtendedStrings\Strings\VibratingStringInterface $string
31
     *
32
     * @return \ExtendedStrings\Strings\Stop
33
     */
34
    public static function fromFrequency(float $frequency, VibratingStringInterface $string): self
35
    {
36
        if (Math::isZero($frequency)) {
37
            throw new \InvalidArgumentException(sprintf('Invalid frequency: %f', $frequency));
38
        }
39
        $centsOverString = Cent::frequenciesToCents($string->getFrequency(), $frequency);
40
41
        return new self(self::centsToStringLength($centsOverString));
42
    }
43
44
    /**
45
     * Returns the frequency of the stop (assuming normal pressure).
46
     *
47
     * @param VibratingStringInterface $string
48
     *
49
     * @return float
50
     */
51
    public function getFrequency(VibratingStringInterface $string): float
52
    {
53
        $centsOverString = Cent::frequenciesToCents($this->stringLength, 1);
54
55
        return Cent::centsToFrequency($centsOverString, $string->getFrequency());
56
    }
57
58
    /**
59
     * Returns the length of string that is left vibrating, as a fraction.
60
     *
61
     * @return float
62
     */
63
    public function getStringLength(): float
64
    {
65
        return $this->stringLength;
66
    }
67
68
    /**
69
     * Convert a number of cents over a string to a string length.
70
     *
71
     * @param float $cents The number of cents between the open string and the
72
     *                     stopped pitch.
73
     *
74
     * @return float The length of the vibrating string, as a fraction of the
75
     * whole string's length.
76
     */
77
    private static function centsToStringLength(float $cents): float
78
    {
79
        return 1 / pow(2, $cents / 1200);
80
    }
81
}
82