@@ -51,11 +51,44 @@ class WaveformDataParser
5151 var pointsPerSecond : Float = sampleRate / samplesPerPoint ; // 172 samples per second for most songs is plenty precise while still being performant..
5252
5353 // TODO: Make this work better on HTML5.
54- var soundData : lime.utils. Int16Array = cast soundBuffer .data ;
54+ var bytes : haxe.io. Bytes = soundBuffer .data .toBytes ();
55+ var soundData : Array <Int > = [];
56+ soundData .resize (Std .int (bytes .length / (bitsPerSample / 8 )));
57+ var minSampleValue : Int ;
58+ var maxSampleValue : Int ;
59+
60+ switch (bitsPerSample )
61+ {
62+ case 8 :
63+ for (i in 0 ... soundData .length )
64+ {
65+ soundData [i ] = bytes .get (i ) - 128 ;
66+ }
67+ minSampleValue = INT8_MIN ;
68+ maxSampleValue = INT8_MAX ;
69+ case 16 :
70+ for (i in 0 ... soundData .length )
71+ {
72+ var val = bytes .getUInt16 (i * 2 );
73+ if (val > INT16_MAX ) val - = 65536 ;
74+ soundData [i ] = val ;
75+ };
76+ minSampleValue = INT16_MIN ;
77+ maxSampleValue = INT16_MAX ;
78+ case 32 :
79+ for (i in 0 ... soundData .length )
80+ {
81+ soundData [i ] = Std .int (bytes .getFloat (i * 4 ) * INT16_MAX );
82+ }
83+ minSampleValue = INT16_MIN ;
84+ maxSampleValue = INT16_MAX ;
85+ default :
86+ throw ' Unsupported bits per sample: $bitsPerSample ' ;
87+ }
5588
5689 var soundDataRawLength : Int = soundData .length ;
57- var soundDataSampleCount : Int = Std . int ( Math .ceil (soundDataRawLength / channels / ( bitsPerSample == 16 ? 2 : 1 )) );
58- var outputPointCount : Int = Std . int ( Math .ceil (soundDataSampleCount / samplesPerPoint ) );
90+ var soundDataSampleCount : Int = Math .ceil (soundDataRawLength / channels );
91+ var outputPointCount : Int = Math .ceil (soundDataSampleCount / samplesPerPoint );
5992
6093 // trace('Interpreting audio buffer:');
6194 // trace(' sampleRate: ${sampleRate}');
@@ -68,9 +101,6 @@ class WaveformDataParser
68101 // trace(' soundDataRawLength/4: ${soundDataRawLength / 4}');
69102 // trace(' outputPointCount: ${outputPointCount}');
70103
71- var minSampleValue : Int = bitsPerSample == 16 ? INT16_MIN : INT8_MIN ;
72- var maxSampleValue : Int = bitsPerSample == 16 ? INT16_MAX : INT8_MAX ;
73-
74104 var outputData : Array <Int > = [];
75105
76106 var perfStart : Float = TimerUtil .start ();
@@ -82,8 +112,8 @@ class WaveformDataParser
82112
83113 for (i in 0 ... channels )
84114 {
85- values .push (bitsPerSample == 16 ? INT16_MAX : INT8_MAX );
86- values .push (bitsPerSample == 16 ? INT16_MIN : INT8_MIN );
115+ values .push (maxSampleValue );
116+ values .push (minSampleValue );
87117 }
88118
89119 var rangeStart = pointIndex * samplesPerPoint ;
@@ -95,18 +125,20 @@ class WaveformDataParser
95125 for (channelIndex in 0 ... channels )
96126 {
97127 var sampleIndex : Int = sampleIndex * channels + channelIndex ;
98- var sampleValue = soundData [sampleIndex ];
128+ var sampleValue : Int = soundData [sampleIndex ];
99129
100130 if (sampleValue < values [channelIndex * 2 ]) values [(channelIndex * 2 )] = sampleValue ;
101131 if (sampleValue > values [channelIndex * 2 + 1 ]) values [(channelIndex * 2 ) + 1 ] = sampleValue ;
102132 }
103133 }
104134
105135 // We now have the min and max values for the range.
106- for (value in values )
107- outputData .push (value );
136+ outputData = outputData .concat (values );
108137 }
109138
139+ // We cheated before by scaling the values to fit in a 16-bit range.
140+ if (bitsPerSample == 32 ) bitsPerSample = 16 ;
141+
110142 var outputDataLength : Int = Std .int (outputData .length / channels / 2 );
111143 var result = new WaveformData (null , channels , sampleRate , samplesPerPoint , bitsPerSample , outputPointCount , outputData );
112144
0 commit comments