Skip to content

Commit 036a315

Browse files
authored
Merge branch 'master' into allow-positive-phase-only
2 parents bc4ab19 + 76cd6b8 commit 036a315

6 files changed

Lines changed: 100 additions & 25 deletions

File tree

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# IDEA files
2+
.idea
3+
4+
# Audio files
5+
*.ogg
6+
*.mp3

Waveform.php

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,23 @@
33
*
44
*
55
* @author MaximAL
6+
* @since 2019-02-13 Added `$onePhase` parameters to get only positive waveform data and image
67
* @since 2018-10-22 Added `getWaveformData()` method and `$soxCommand` configuration
78
* @since 2016-11-21
89
* @date 2016-11-21
910
* @time 19:08
1011
* @link http://maximals.ru
1112
* @link http://sijeko.ru
1213
* @link https://github.com/maximal/audio-waveform-php
13-
* @copyright © MaximAL, Sijeko 2016
14+
* @copyright © MaximAL, Sijeko 2016-2019
1415
*/
1516

1617
namespace maximal\audio;
1718

19+
/**
20+
* Waveform class allows you to get waveform data and images from audio files
21+
* @package maximal\audio
22+
*/
1823
class Waveform
1924
{
2025
protected $filename;
@@ -104,11 +109,20 @@ public function getDuration()
104109
return $this->duration;
105110
}
106111

107-
public function getWaveform($filename, $width, $height)
112+
/**
113+
* Get waveform from the audio file.
114+
* @param string $filename Audio file name
115+
* @param int $width Width of the image file in pixels
116+
* @param int $height Height of the image file in pixels
117+
* @param bool $onePhase `true` to get positive values only, `false` to get both phases
118+
* @return bool Returns `true` on success or `false` on failure.
119+
* @throws \Exception
120+
*/
121+
public function getWaveform($filename, $width, $height, $onePhase = false)
108122
{
109123
// Calculating parameters
110124
$needChannels = $this->getChannels() > 1 ? 2 : 1;
111-
$data = $this->getWaveformData($width);
125+
$data = $this->getWaveformData($width, $onePhase);
112126
$lines1 = $data['lines1'];
113127
$lines2 = $data['lines2'];
114128

@@ -126,24 +140,37 @@ public function getWaveform($filename, $width, $height)
126140
imagefill($img, 0, 0, $back);
127141

128142
// Center Ys
129-
$center1 = $needChannels === 2 ? ($height / 2 - 1) / 2 : $height / 2;
130-
$center2 = $needChannels === 2 ? $height - $center1 : null;
143+
if ($onePhase) {
144+
$center1 = $needChannels === 2 ? $height / 2 - 1: $height - 1;
145+
$center2 = $needChannels === 2 ? $height - 1 : null;
146+
} else {
147+
$center1 = $needChannels === 2 ? ($height / 2 - 1) / 2 : $height / 2;
148+
$center2 = $needChannels === 2 ? $height - $center1 : null;
149+
}
131150

132151
// Drawing channel 1
133152
for ($i = 0; $i < count($lines1); $i += 2) {
134-
$min = $lines1[$i];
135-
$max = $lines1[$i+1];
136153
$x = $i / 2 / self::$linesPerPixel;
137-
138-
imageline($img, $x, $center1 - $min * $center1, $x, $center1 - $max * $center1, $color);
154+
if ($onePhase) {
155+
$max = max($lines1[$i], $lines1[$i + 1]);
156+
imageline($img, $x, $center1, $x, $center1 - $max * $center1, $color);
157+
} else {
158+
$min = $lines1[$i];
159+
$max = $lines1[$i + 1];
160+
imageline($img, $x, $center1 - $min * $center1, $x, $center1 - $max * $center1, $color);
161+
}
139162
}
140163
// Drawing channel 2
141164
for ($i = 0; $i < count($lines2); $i += 2) {
142-
$min = $lines2[$i];
143-
$max = $lines2[$i + 1];
144165
$x = $i / 2 / self::$linesPerPixel;
145-
146-
imageline($img, $x, $center2 - $min * $center1, $x, $center2 - $max * $center1, $color);
166+
if ($onePhase) {
167+
$max = max($lines2[$i], $lines2[$i + 1]);
168+
imageline($img, $x, $center2, $x, $center2 - $max * $center1, $color);
169+
} else {
170+
$min = $lines2[$i];
171+
$max = $lines2[$i + 1];
172+
imageline($img, $x, $center2 - $min * $center1, $x, $center2 - $max * $center1, $color);
173+
}
147174
}
148175

149176
// Axis
@@ -155,7 +182,14 @@ public function getWaveform($filename, $width, $height)
155182
return imagepng($img, $filename);
156183
}
157184

158-
public function getWaveformData($width, $positivePhaseOnly = false)
185+
/**
186+
* Get waveform data from the audio file.
187+
* @param int $width Desired width of the image file in pixels
188+
* @param bool $onePhase `true` to get positive values only, `false` to get both phases
189+
* @return array
190+
* @throws \Exception
191+
*/
192+
public function getWaveformData($width, $onePhase = false)
159193
{
160194
// Calculating parameters
161195
$needChannels = $this->getChannels() > 1 ? 2 : 1;
@@ -196,15 +230,22 @@ public function getWaveformData($width, $positivePhaseOnly = false)
196230
$channel1 []= $sample;
197231
}
198232
}
199-
if (!$positivePhaseOnly) {
200-
$lines1 []= min($channel1);
201-
}
202-
$lines1 []= max($channel1);
203-
if ($needChannels === 2) {
204-
if (!$positivePhaseOnly) {
205-
$lines2 []= min($channel2);
206-
}
207-
$lines2 []= max($channel2);
233+
if ($onePhase) {
234+
// Rectifying to get positive values only
235+
$lines1 []= abs(min($channel1));
236+
$lines1 []= abs(max($channel1));
237+
if ($needChannels === 2) {
238+
$lines2 []= abs(min($channel2));
239+
$lines2 []= abs(max($channel2));
240+
}
241+
} else {
242+
// Two phases
243+
$lines1 []= min($channel1);
244+
$lines1 []= max($channel1);
245+
if ($needChannels === 2) {
246+
$lines2 []= min($channel2);
247+
$lines2 []= max($channel2);
248+
}
208249
}
209250
}
210251

one-phase-mono.png

6.53 KB
Loading

one-phase-stereo.png

12.7 KB
Loading

readme.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,20 @@ $waveform = new Waveform('track.mp3');
4848
$success = $waveform->getWaveform('thumbnail.png', 1024, 512);
4949
```
5050

51+
### One Phase
52+
To get positive waveform only (i.e. one phase) pass `onePhase` parameter set to `true`:
53+
```php
54+
$waveform->getWaveform('one-phase.png', 800, 400, true);
55+
```
56+
57+
Stereo source:
58+
59+
![One phase stereo](one-phase-stereo.png)
60+
61+
Mono source:
62+
63+
![One phase stereo](one-phase-mono.png)
64+
5165

5266
## Settings
5367

@@ -116,6 +130,12 @@ $data = $waveform->getWaveformData($width);
116130
// $data['lines1'] and $data['lines2'] now have the waveform data for channels 1 and 2
117131
```
118132

133+
To get positive values only (i.e. one phase) pass `onePhase` parameter set to `true`:
134+
135+
```php
136+
$data = $waveform->getWaveformData($width, true);
137+
```
138+
119139

120140
## Contact the author
121141

thumbnailer.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
echo 'Error: audio and thumbnail files not specified!', PHP_EOL;
3434
echo 'Usage: php ', $argv[0],
3535
' <audio file> <thumbnail file> [<thumbnail size in pixels, default is ',
36-
$width, '×', $height, '>]',
36+
$width, '×', $height, '>] [two-phase|positive, default is `two-phase`]',
3737
PHP_EOL;
3838
exit(1);
3939
}
@@ -57,6 +57,14 @@
5757
}
5858
}
5959

60+
// Parsing phase setting
61+
$onePhase = false;
62+
if (count($argv) > 4) {
63+
if (strtolower($argv[4]) === 'positive') {
64+
$onePhase = true;
65+
}
66+
}
67+
6068
if (!is_file($filename)) {
6169
echo 'Error: file «', $filename, '» not found!', PHP_EOL;
6270
exit(3);
@@ -67,7 +75,7 @@
6775
// Some settings
6876
//Waveform::$color = [255, 0, 0, 0.5];
6977
//Waveform::$backgroundColor = [0, 0, 0, 0];
70-
if (!$waveform->getWaveform($thumbnail, $width, $height)) {
78+
if (!$waveform->getWaveform($thumbnail, $width, $height, $onePhase)) {
7179
exit(4);
7280
}
7381

0 commit comments

Comments
 (0)