33 *
44 *
55 * @author MaximAL
6+ * @since 2018-10-22 Added `getWaveformData()` method and `$soxCommand` configuration
67 * @since 2016-11-21
78 * @date 2016-11-21
89 * @time 19:08
@@ -31,6 +32,9 @@ class Waveform
3132 public static $ backgroundColor = [245 , 245 , 245 , 1 ];
3233 public static $ axisColor = [0 , 0 , 0 , 0.1 ];
3334
35+ // SoX command: 'sox', '/usr/local/bin/sox' etc
36+ public static $ soxCommand = 'sox ' ;
37+
3438
3539 public function __construct ($ filename )
3640 {
@@ -41,7 +45,7 @@ public function getInfo()
4145 {
4246 $ out = null ;
4347 $ ret = null ;
44- exec (' sox --i ' . escapeshellarg ($ this ->filename ) . ' 2>&1 ' , $ out , $ ret );
48+ exec (self :: $ soxCommand . ' --i ' . escapeshellarg ($ this ->filename ) . ' 2>&1 ' , $ out , $ ret );
4549 $ str = implode ('| ' , $ out );
4650
4751 $ match = null ;
@@ -100,8 +104,58 @@ public function getDuration()
100104 return $ this ->duration ;
101105 }
102106
103-
104107 public function getWaveform ($ filename , $ width , $ height )
108+ {
109+ // Calculating parameters
110+ $ needChannels = $ this ->getChannels () > 1 ? 2 : 1 ;
111+ $ data = $ this ->getWaveformData ($ width );
112+ $ lines1 = $ data ['lines1 ' ];
113+ $ lines2 = $ data ['lines2 ' ];
114+
115+ // Creating image
116+ $ img = imagecreatetruecolor ($ width , $ height );
117+ imagesavealpha ($ img , true );
118+ //if (function_exists('imageantialias')) {
119+ // imageantialias($img, true);
120+ //}
121+
122+ // Colors
123+ $ back = self ::rgbaToColor ($ img , self ::$ backgroundColor );
124+ $ color = self ::rgbaToColor ($ img , self ::$ color );
125+ $ axis = self ::rgbaToColor ($ img , self ::$ axisColor );
126+ imagefill ($ img , 0 , 0 , $ back );
127+
128+ // Center Ys
129+ $ center1 = $ needChannels === 2 ? ($ height / 2 - 1 ) / 2 : $ height / 2 ;
130+ $ center2 = $ needChannels === 2 ? $ height - $ center1 : null ;
131+
132+ // Drawing channel 1
133+ for ($ i = 0 ; $ i < count ($ lines1 ); $ i += 2 ) {
134+ $ min = $ lines1 [$ i ];
135+ $ max = $ lines1 [$ i +1 ];
136+ $ x = $ i / 2 / self ::$ linesPerPixel ;
137+
138+ imageline ($ img , $ x , $ center1 - $ min * $ center1 , $ x , $ center1 - $ max * $ center1 , $ color );
139+ }
140+ // Drawing channel 2
141+ for ($ i = 0 ; $ i < count ($ lines2 ); $ i += 2 ) {
142+ $ min = $ lines2 [$ i ];
143+ $ max = $ lines2 [$ i + 1 ];
144+ $ x = $ i / 2 / self ::$ linesPerPixel ;
145+
146+ imageline ($ img , $ x , $ center2 - $ min * $ center1 , $ x , $ center2 - $ max * $ center1 , $ color );
147+ }
148+
149+ // Axis
150+ imageline ($ img , 0 , $ center1 , $ width - 1 , $ center1 , $ axis );
151+ if ($ center2 !== null ) {
152+ imageline ($ img , 0 , $ center2 , $ width - 1 , $ center2 , $ axis );
153+ }
154+
155+ return imagepng ($ img , $ filename );
156+ }
157+
158+ public function getWaveformData ($ width )
105159 {
106160 // Calculating parameters
107161 $ needChannels = $ this ->getChannels () > 1 ? 2 : 1 ;
@@ -113,7 +167,7 @@ public function getWaveform($filename, $width, $height)
113167 //}
114168
115169 // Command text
116- $ command = ' sox ' . escapeshellarg ($ this ->filename ) .
170+ $ command = self :: $ soxCommand . ' ' . escapeshellarg ($ this ->filename ) .
117171 ' -c ' . $ needChannels .
118172 ' -r ' . $ needRate . ' -e floating-point -t raw - ' ;
119173
@@ -126,7 +180,7 @@ public function getWaveform($filename, $width, $height)
126180 $ pipes = null ;
127181 $ proc = proc_open ($ command , $ outputs , $ pipes );
128182 if (!$ proc ) {
129- throw new \Exception ('Failed to run sox command ' );
183+ throw new \Exception ('Failed to run ` sox` command ' );
130184 }
131185
132186 $ lines1 = [];
@@ -157,47 +211,7 @@ public function getWaveform($filename, $width, $height)
157211 throw new \Exception ('Failed to run `sox` command. Error: ' . PHP_EOL . $ err );
158212 }
159213
160- // Creating image
161- $ img = imagecreatetruecolor ($ width , $ height );
162- imagesavealpha ($ img , true );
163- //if (function_exists('imageantialias')) {
164- // imageantialias($img, true);
165- //}
166-
167- // Colors
168- $ back = self ::rgbaToColor ($ img , self ::$ backgroundColor );
169- $ color = self ::rgbaToColor ($ img , self ::$ color );
170- $ axis = self ::rgbaToColor ($ img , self ::$ axisColor );
171- imagefill ($ img , 0 , 0 , $ back );
172-
173- // Center Ys
174- $ center1 = $ needChannels === 2 ? ($ height / 2 - 1 ) / 2 : $ height / 2 ;
175- $ center2 = $ needChannels === 2 ? $ height - $ center1 : null ;
176-
177- // Drawing channel 1
178- for ($ i = 0 ; $ i < count ($ lines1 ); $ i += 2 ) {
179- $ min = $ lines1 [$ i ];
180- $ max = $ lines1 [$ i +1 ];
181- $ x = $ i / 2 / self ::$ linesPerPixel ;
182-
183- imageline ($ img , $ x , $ center1 - $ min * $ center1 , $ x , $ center1 - $ max * $ center1 , $ color );
184- }
185- // Drawing channel 2
186- for ($ i = 0 ; $ i < count ($ lines2 ); $ i += 2 ) {
187- $ min = $ lines2 [$ i ];
188- $ max = $ lines2 [$ i + 1 ];
189- $ x = $ i / 2 / self ::$ linesPerPixel ;
190-
191- imageline ($ img , $ x , $ center2 - $ min * $ center1 , $ x , $ center2 - $ max * $ center1 , $ color );
192- }
193-
194- // Axis
195- imageline ($ img , 0 , $ center1 , $ width - 1 , $ center1 , $ axis );
196- if ($ center2 !== null ) {
197- imageline ($ img , 0 , $ center2 , $ width - 1 , $ center2 , $ axis );
198- }
199-
200- return imagepng ($ img , $ filename );
214+ return ['lines1 ' => $ lines1 , 'lines2 ' => $ lines2 ];
201215 }
202216
203217 public static function rgbaToColor ($ img , $ rgba )
0 commit comments