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
1617namespace maximal \audio ;
1718
19+ /**
20+ * Waveform class allows you to get waveform data and images from audio files
21+ * @package maximal\audio
22+ */
1823class 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
0 commit comments