2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | package org.woheller69.audio_analyzer_for_android;
17 |
18 | import android.os.SystemClock;
19 | import android.util.Log;
20 |
21 | /**
22 | * For checking Recorder running status.
23 | * Especially buffer overrun, i.e. too few data from the recorder.
24 | */
25 | class RecorderMonitor {
26 | private static final String TAG0 = "RecorderMonitor:";
27 | private final String TAG;
28 | private long timeUpdateOld, timeUpdateInterval, timeStarted; // in ms
29 | private long lastOverrunTime;
30 | private long nSamplesRead;
31 | private int sampleRate;
32 | private int bufferSampleSize;
33 | private double sampleRateReal;
34 | private boolean lastCheckOverrun = false;
35 |
36 | RecorderMonitor(int sampleRateIn, int bufferSampleSizeIn, String TAG1) {
37 | sampleRate = sampleRateIn;
38 | bufferSampleSize = bufferSampleSizeIn;
39 | timeUpdateInterval = 2000;
40 | TAG = TAG1 + TAG0;
41 | }
42 |
43 | // When start recording, call this
44 | void start() {
45 | nSamplesRead = 0;
46 | lastOverrunTime = 0;
47 | timeStarted = SystemClock.uptimeMillis();
48 | timeUpdateOld = timeStarted;
49 | sampleRateReal = sampleRate;
50 | }
51 |
52 | // Input number of audio frames that read
53 | // Return true if an overrun check is performed, otherwise false.
54 | boolean updateState(int numOfReadShort) {
55 | long timeNow = SystemClock.uptimeMillis();
56 | if (nSamplesRead == 0) { // get overrun checker synchronized
57 | timeStarted = timeNow - numOfReadShort*1000/sampleRate;
58 | }
59 | nSamplesRead += numOfReadShort;
60 | if (timeUpdateOld + timeUpdateInterval > timeNow) {
61 | return false; // do the checks below every timeUpdateInterval ms
62 | }
63 | timeUpdateOld += timeUpdateInterval;
64 | if (timeUpdateOld + timeUpdateInterval <= timeNow) {
65 | timeUpdateOld = timeNow; // catch up the time (so that at most one output per timeUpdateInterval)
66 | }
67 | long nSamplesFromTime = (long)((timeNow - timeStarted) * sampleRateReal / 1000);
68 | double f1 = (double) nSamplesRead / sampleRateReal;
69 | double f2 = (double) nSamplesFromTime / sampleRateReal;
70 | // Log.i(TAG, "Buffer"
71 | // + " should read " + nSamplesFromTime + " (" + Math.round(f2*1000)/1000.0 + "s),"
72 | // + " actual read " + nSamplesRead + " (" + Math.round(f1*1000)/1000.0 + "s)\n"
73 | // + " diff " + (nSamplesFromTime-nSamplesRead) + " (" + Math.round((f2-f1)*1000)/1e3 + "s)"
74 | // + " sampleRate = " + Math.round(sampleRateReal*100)/100.0);
75 | // Check if buffer overrun occur
76 | if (nSamplesFromTime > bufferSampleSize + nSamplesRead) {
77 | Log.w(TAG, "SamplingLoop::run(): Buffer Overrun occurred !\n"
78 | + " should read " + nSamplesFromTime + " (" + Math.round(f2*1000)/1000.0 + "s),"
79 | + " actual read " + nSamplesRead + " (" + Math.round(f1*1000)/1000.0 + "s)\n"
80 | + " diff " + (nSamplesFromTime-nSamplesRead) + " (" + Math.round((f2-f1)*1000)/1e3 + "s)"
81 | + " sampleRate = " + Math.round(sampleRateReal*100)/100.0
82 | + "\n Overrun counter reset.");
83 | lastOverrunTime = timeNow;
84 | nSamplesRead = 0; // start over
85 | }
86 | // Update actual sample rate
87 | if (nSamplesRead > 10*sampleRate) {
88 | sampleRateReal = 0.9*sampleRateReal + 0.1*(nSamplesRead * 1000.0 / (timeNow - timeStarted));
89 | if (Math.abs(sampleRateReal-sampleRate) > 0.0145*sampleRate) { // 0.0145 = 25 cent
90 | Log.w(TAG, "SamplingLoop::run(): Sample rate inaccurate, possible hardware problem !\n"
91 | + " should read " + nSamplesFromTime + " (" + Math.round(f2*1000)/1000.0 + "s),"
92 | + " actual read " + nSamplesRead + " (" + Math.round(f1*1000)/1000.0 + "s)\n"
93 | + " diff " + (nSamplesFromTime-nSamplesRead) + " (" + Math.round((f2-f1)*1000)/1e3 + "s)"
94 | + " sampleRate = " + Math.round(sampleRateReal*100)/100.0
95 | + "\n Overrun counter reset.");
96 | nSamplesRead = 0;
97 | }
98 | }
99 | lastCheckOverrun = lastOverrunTime == timeNow;
100 | return true; // state updated during this check
101 | }
102 |
103 | boolean getLastCheckOverrun() {
104 | return lastCheckOverrun;
105 | }
106 |
107 | long getLastOverrunTime() {
108 | return lastOverrunTime;
109 | }
110 |
111 | double getSampleRate() {
112 | return sampleRateReal;
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/audioSpectrumAnalyzer/src/main/java/org/woheller69/audio_analyzer_for_android/besselCal.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.audio_analyzer_for_android;
2 |
3 | class besselCal {
4 | /*
5 | Copyright © 1999 CERN - European Organization for Nuclear Research.
6 | Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose
7 | is hereby granted without fee, provided that the above copyright notice appear in all copies and
8 | that both that copyright notice and this permission notice appear in supporting documentation.
9 | CERN makes no representations about the suitability of this software for any purpose.
10 | It is provided "as is" without expressed or implied warranty.
11 | */
12 |
13 | // https://github.com/carlsonp/Colt/blob/master/src/cern/jet/math/Arithmetic.java
14 | // package cern.jet.math;
15 | /**
16 | * Evaluates the series of Chebyshev polynomials Ti at argument x/2.
17 | * The series is given by
18 | *
19 | * N-1
20 | * - '
21 | * y = > coef[i] T (x/2)
22 | * - i
23 | * i=0
24 | *
25 | * Coefficients are stored in reverse order, i.e. the zero
26 | * order term is last in the array. Note N is the number of
27 | * coefficients, not the order.
28 | *
29 | * If coefficients are for the interval a to b, x must
30 | * have been transformed to x -> 2(2x - b - a)/(b-a) before
31 | * entering the routine. This maps x from (a, b) to (-1, 1),
32 | * over which the Chebyshev polynomials are defined.
33 | *
34 | * If the coefficients are for the inverted interval, in
35 | * which (a, b) is mapped to (1/b, 1/a), the transformation
36 | * required is x -> 2(2ab/x - b - a)/(b-a). If b is infinity,
37 | * this becomes x -> 4a/x - 1.
38 | *
39 | * SPEED:
40 | *
41 | * Taking advantage of the recurrence properties of the
42 | * Chebyshev polynomials, the routine requires one more
43 | * addition per loop than evaluating a nested polynomial of
44 | * the same degree.
45 | *
46 | * @param x argument to the polynomial.
47 | * @param coef the coefficients of the polynomial.
48 | * @param N the number of coefficients.
49 | */
50 | static double chbevl(double x, double coef[], int N) throws ArithmeticException {
51 | double b0, b1, b2;
52 |
53 | int p = 0;
54 | int i;
55 |
56 | b0 = coef[p++];
57 | b1 = 0.0;
58 | i = N - 1;
59 |
60 | do {
61 | b2 = b1;
62 | b1 = b0;
63 | b0 = x * b1 - b2 + coef[p++];
64 | } while( --i > 0);
65 |
66 | return( 0.5*(b0-b2) );
67 | }
68 |
69 | // https://github.com/carlsonp/Colt/blob/master/src/cern/jet/math/Bessel.java
70 | // package cern.jet.math;
71 |
72 | private static final double[] A_i0 = {
73 | -4.41534164647933937950E-18,
74 | 3.33079451882223809783E-17,
75 | -2.43127984654795469359E-16,
76 | 1.71539128555513303061E-15,
77 | -1.16853328779934516808E-14,
78 | 7.67618549860493561688E-14,
79 | -4.85644678311192946090E-13,
80 | 2.95505266312963983461E-12,
81 | -1.72682629144155570723E-11,
82 | 9.67580903537323691224E-11,
83 | -5.18979560163526290666E-10,
84 | 2.65982372468238665035E-9,
85 | -1.30002500998624804212E-8,
86 | 6.04699502254191894932E-8,
87 | -2.67079385394061173391E-7,
88 | 1.11738753912010371815E-6,
89 | -4.41673835845875056359E-6,
90 | 1.64484480707288970893E-5,
91 | -5.75419501008210370398E-5,
92 | 1.88502885095841655729E-4,
93 | -5.76375574538582365885E-4,
94 | 1.63947561694133579842E-3,
95 | -4.32430999505057594430E-3,
96 | 1.05464603945949983183E-2,
97 | -2.37374148058994688156E-2,
98 | 4.93052842396707084878E-2,
99 | -9.49010970480476444210E-2,
100 | 1.71620901522208775349E-1,
101 | -3.04682672343198398683E-1,
102 | 6.76795274409476084995E-1
103 | };
104 |
105 | /**
106 | * Chebyshev coefficients for exp(-x) sqrt(x) I0(x)
107 | * in the inverted interval [8,infinity].
108 | *
109 | * lim(x->inf){ exp(-x) sqrt(x) I0(x) } = 1/sqrt(2pi).
110 | */
111 | private static final double[] B_i0 = {
112 | -7.23318048787475395456E-18,
113 | -4.83050448594418207126E-18,
114 | 4.46562142029675999901E-17,
115 | 3.46122286769746109310E-17,
116 | -2.82762398051658348494E-16,
117 | -3.42548561967721913462E-16,
118 | 1.77256013305652638360E-15,
119 | 3.81168066935262242075E-15,
120 | -9.55484669882830764870E-15,
121 | -4.15056934728722208663E-14,
122 | 1.54008621752140982691E-14,
123 | 3.85277838274214270114E-13,
124 | 7.18012445138366623367E-13,
125 | -1.79417853150680611778E-12,
126 | -1.32158118404477131188E-11,
127 | -3.14991652796324136454E-11,
128 | 1.18891471078464383424E-11,
129 | 4.94060238822496958910E-10,
130 | 3.39623202570838634515E-9,
131 | 2.26666899049817806459E-8,
132 | 2.04891858946906374183E-7,
133 | 2.89137052083475648297E-6,
134 | 6.88975834691682398426E-5,
135 | 3.36911647825569408990E-3,
136 | 8.04490411014108831608E-1
137 | };
138 |
139 | /**
140 | * Returns the modified Bessel function of order 0 of the
141 | * argument.
142 | *
143 | * The function is defined as i0(x) = j0( ix ).
144 | *
145 | * The range is partitioned into the two intervals [0,8] and
146 | * (8, infinity). Chebyshev polynomial expansions are employed
147 | * in each interval.
148 | *
149 | * @param x the value to compute the bessel function of.
150 | */
151 | static double i0(double x) throws ArithmeticException {
152 | double y;
153 | if( x < 0 ) x = -x;
154 | if( x <= 8.0 ) {
155 | y = (x/2.0) - 2.0;
156 | return( Math.exp(x) * chbevl( y, A_i0, 30 ) );
157 | }
158 |
159 | return( Math.exp(x) * chbevl( 32.0/x - 2.0, B_i0, 25 ) / Math.sqrt(x) );
160 | }
161 |
162 | }
163 |
--------------------------------------------------------------------------------
/audioSpectrumAnalyzer/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | - Hot
6 | - Black-body
7 | - Jet
8 | - Parula (Matlab)
9 | - Gray
10 | - inferno (Matplotlib)
11 | - magma (Matplotlib)
12 | - plasma (Matplotlib)
13 | - viridis (Matplotlib)
14 |
15 | viridis
16 |
17 | - hot
18 | - blackbody_uniform
19 | - jet
20 | - parula
21 | - gray
22 | - inferno
23 | - magma
24 | - plasma
25 | - viridis
26 |
27 | -120
28 | -120
29 |
30 | - -30
31 | - -60
32 | - -90
33 | - -120
34 | - -150
35 |
36 | 6.0
37 |
38 | - 2.0
39 | - 4.0
40 | - 6.0
41 | - 8.0
42 | - 10.0
43 |
44 | 8
45 |
46 | - 8
47 | - 12
48 | - 18
49 | - 27
50 | - 40
51 | - 60
52 |
53 |
54 | 1
55 |
56 | - 1
57 | - 2
58 | - 4
59 | - 8
60 |
61 |
62 |
63 | - Off
64 | - 2x
65 | - 4x
66 | - 8x
67 |
68 |
69 | Hanning
70 |
71 | - Rectangular
72 | - Bartlett
73 | - Hanning
74 | - Blackman
75 | - Blackman Harris
76 | - Kaiser, a=2.0
77 | - Kaiser, a=3.0
78 | - Kaiser, a=4.0
79 | - Flat-top
80 | - Nuttall
81 | - Gaussian, b=3.0
82 | - Gaussian, b=5.0
83 | - Gaussian, b=6.0
84 | - Gaussian, b=7.0
85 | - Gaussian, b=8.0
86 |
87 |
88 | - 0%
89 | - 50%
90 | - 75%
91 | - 87.5%
92 | - 93.75%
93 |
94 |
95 | - 0.0
96 | - 50.0
97 | - 75.0
98 | - 87.5
99 | - 93.75
100 |
101 | 50.0
102 |
103 | - VOICE_RECOGNITION
104 | - DEFAULT
105 | - MIC
106 | - VOICE_UPLINK
107 | - VOICE_DOWNLINK
108 | - VOICE_CALL
109 | - CAMCORDER
110 | - test signal 1\n\t 440Hz @ -6dB
111 | - test signal 2\n\t 625Hz @ -6dB\n +1875Hz @ -12dB
112 | - white noise
113 |
114 |
115 | - 6
116 | - 0
117 | - 1
118 | - 2
119 | - 3
120 | - 4
121 | - 5
122 | - 1000
123 | - 1001
124 | - 1002
125 |
126 | 6
127 |
128 | - @string/sample_rates_name
129 | - 8000::8000
130 | - 11025::11025
131 | - 16000::16000
132 | - 22050::22050
133 | - 32000::32000
134 | - 44100::44100
135 | - 48000::48000
136 | - 96000::96000
137 | - 192k::192000
138 |
139 |
140 | - @string/fft_len_name
141 | - 64::64
142 | - 128::128
143 | - 256::256
144 | - 512::512
145 | - 1024::1024
146 | - 2048::2048
147 | - 4096::4096
148 | - 8192::8192
149 | - 16384::16384
150 | - 32768::32768
151 |
152 |
153 | - @string/fft_ave_num_name
154 | - 1::1
155 | - 2::2
156 | - 4::4
157 | - 8::8
158 | - 16::16
159 | - 32::32
160 | - 64::64
161 | - 128::128
162 | - 256::256
163 | - 512::512
164 | - 1024::1024
165 |
166 |
167 |
--------------------------------------------------------------------------------
/audioSpectrumAnalyzer/src/main/res/values-zh-rTW/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 運行::停止
4 | 錄音: 00:00:00.0, 剩餘空間: 0000:00:00
5 | 偏好
6 | 峰值:XXXXX.XHz(AX#+XX) -XXX.XdB
7 | 峰值:
8 | 錄音:
9 | ", 剩餘空間: "
10 | 確定
11 | 取消
12 | 指針
13 | 監聽::錄音
14 | 指針:XXXXX.XHz(AX#+XX) -XXX.XdB
15 | 指針:
16 | 采樣率
17 | FFT長度
18 | N平均
19 | 采樣率::0
20 | FFT長度::0
21 | N平均::0
22 | 設定頻率下限和上限
23 | 設定分貝下限和上限
24 | 頻率上限
25 | 分貝下限
26 | 分貝上限
27 | 鎖定範圍
28 | 均方根:dB \n-XXX.X
29 | 音頻頻譜分析器
30 | 頻率 [Hz]
31 | 使用幫助
32 | 偏好設定
33 | 錄音源設定
34 | 顯示範圍設定
35 | 手動
36 | 偏好設定
37 | 測試
38 | \n--- 錄音源測試 ---\n
39 | \n錄音源: %1$s\n
40 | "%1$5d Hz "
41 | 成功
42 | 讀取樣本失敗
43 | 初始化失敗
44 | (來源更改: %1$s)>
45 | .\n
46 | 常規設定
47 | 保持熒幕開
48 | 音頻源
49 | 分析時阻止熒幕和設備關閉
50 | 用於短時傅里葉變換(STFT)的窗函數
51 | 窗函數
52 | 高時窗重叠比例
53 | 頻譜設定
54 | 頻譜顯示為線條(而不是柱狀圓)
55 | 僅顯示頻譜輪廓線條
56 | 頻譜顯示的動態範圍
57 | 頻譜動態範圍
58 | 時頻譜設定
59 | 時頻譜隨時間平移,而不是覆蓋式
60 | 平移式時頻譜
61 | 錄音源信息
62 | 測試標準錄音源
63 | 測試支持的錄音源
64 | 測試所有錄音源
65 | " Hz 錯誤\n"
66 | 讀取 0 byte
67 | 顯示時間軸
68 | 也即縱軸作爲時間軸
69 | 橫軸作爲頻率軸
70 | 時頻譜隨時間平移,而不是覆蓋式
71 | 平移式時頻譜
72 | 選擇分貝與顔色映射的風格
73 | 色彩映射風格
74 | 時頻譜顯示的動態範圍
75 | 時頻譜動態範圍
76 | 時頻譜記錄時長(頻譜平均數為1時)
77 | 頻譜圖持續時間
78 | 調高可獲得更平滑的圖像,調低可節省電量。
79 | 刷新率限制
80 | 雜項
81 | 當音頻緩衝區溢出時,顯示警告
82 | Overrun 警告
83 | 開發者選項
84 | 僅在縮放時重新繪製頻譜圖(節省電量)
85 | 對數軸繪製方法: 縮放時重新繪製
86 | 減少樣本量並用零填充
87 | 確定
88 | 不
89 | 也許以後
90 | 你喜歡這款應用程式嗎?請在 GitHub 上點個星星,或透過 PayPal 給開發者買杯咖啡。
91 | 關於
92 | 隱私政策
93 | 實驗功能
94 | "螢幕截圖已儲存在 "
95 | 寫入儲存權限被拒絕。
96 | 麥克風使用許可被拒絕。
97 | 秒
98 | 峰值保持時間
99 | 峰值衰減率
100 | 非法參數
101 | 用於頻譜分析的音頻源
102 | 高時窗重叠比例解析度越精細,低則節省CPU資源
103 | 線性::對數::音符
104 | 頻率下限
105 | 設定游標頻率 [Hz]
106 | 顯示時間軸及時間標籤
107 | 載入之前設定
108 |
109 |
--------------------------------------------------------------------------------
/audioSpectrumAnalyzer/src/main/res/values/instructions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | User Manual
4 | Close
5 | Button operation
6 | 1D/2D
7 |
1D: Show the real time spectrum.
8 |
2D: Show the spectrogram in a duration. The color represents strength of the sound at a certain frequency and time.
9 |
10 | dB/dBA
11 |
Switch between dBFS and A-weighting dBFS. dBA is widely used in environmental noise measurement. But here, dBA is only for reference, see notes below.
12 |
13 | linear/log/note
14 |
Switch between linear, logarithmic or musical note frequency axis. In log and note mode, the lowest frequency is determined by sampling rate divided by Fourier transform length.
15 |
16 | run/stop
17 |
stop Pauses the display, so that it is easier to inspect the spectrum/spectrogram. However, the recorder will keep recording.
18 |
run Real time monitoring of the audio samples.
19 |
20 | SAMPLE/S
21 |
Sampling rate selection. Higher sampling rate can see higher frequency information.
22 |
23 | FFT LEN
24 |
Fourier transform length selection. Larger FFT length will give higher frequency resolution while have lower time resolution.
25 |
26 | N AVE
27 |
Number of spectrum average for a display of spectrum or spectrogram. Higher value will make the spectrum less noisy and more smooth, at the cost of lower time resolution.
28 |
29 | Curs
30 |
Set precise cursor frequency by keypad.
31 |
32 |
33 | Viewport operation
34 | Drag and Swipe
35 |
Move the spectrum or spectrogram.
36 |
37 | Pinch
38 |
Scales the spectrum or spectrogram.
39 |
40 | Double click
41 |
Reset the scaling.
42 |
43 | Long press
44 |
Place a cursor at the point pressing, you can move the cursor while pressing. Once the finger leaves the screen, the cursor fixed at the last position.
45 |
Move the cursor outside viewport to delete it.
46 |
Tap the Curs button to set the cursor frequency precisely by keyboard.
47 |
48 |
49 | Get a screen shot
50 | General (>=Android 4.0):
51 |
Press \"Volume Down\" + \"Power\" at the same time.
52 |
For Samsung:
53 |
Press \"Power\" + \"Home\" at the same time.
54 |
55 |
56 | Preferences
57 | Audio source
58 | It is recommended to use VOICE_RECOGNITION for measurement purpose.
59 | Window Function
60 | It is recommended to use Hanning for general purpose.
61 |
The window function with high dynamical range (i.e. low leakage) will be poor in locating the frequency, and vise versa.
62 |
Dynamical range from low to high (frequency accuracy high to low) is:
63 |
64 |
Rectangular: 57 dB (54 Hz)
65 |
Bartlett: 105 dB (79 dB, 82 Hz)
66 |
Kaiser,a=2.0: 90 dB (93 Hz)
67 |
Hanning: 154 dB (90 dB, 94 Hz)
68 |
Blackman: 162 dB (107 dB, 107 Hz)
69 |
Kaiser,a=3.0: 114 dB (111 Hz)
70 |
Blackman-harris: 133 dB (124 Hz)
71 |
Kaiser,a=4.0: 138 dB (127 Hz)
72 |
73 |
Dynamical range measured at half highest frequency away from the peak and use FFT length 1024, (frequency accuracy at sampling rate 48kHz).
74 |
For "Blackman", "Hanning" and "Bartlett" the dynamical range increase fast when away from the central frequency. For these window function, the dynamical range in parenthesis is measured using DPSS window function with identical frequency accuracy.
75 |
Doubling the FFT length will make dynamical range at least +6 dB, for "Bartlett", "Hanning" and "Blackman" the increament is +12dB, +18dB and +18dB.
76 |
77 |
78 |
79 | Technical Notes
80 | \u2022 In this software, we define all instances of “dB” to represent decibels relative to full scale (dBFS). There is no simple way to convert dBFS to acoustical dB (e.g. dB SPL, dBC, or dBA) without at least requiring a full spectrum calibration.
81 |
82 | \u2022 A full-scale sine wave is designated at reference: 0 dBFS. Hence the RMS of a full-scale square wave will be about 3.0 dBFS and its base frequency is about 2.0 dBFS. The signal of 1/32768 of full-scale will be about -90.3 dBFS.
83 |
84 | \u2022 The dBA in this software is a simple minded, A-weighting dBFS measure, instead of acoustics dBA which requires acoustical dB.
85 |
86 | \u2022 The spectrum (hence spectrogram) below -110 dB is essentially noise, due to the precision limitation and accumulated error in the Fourier transform procedure. However, most measurement error is still originated from the microphone hardware.
87 |
88 | \u2022 Some, if not many, mobile devices have a low-quality sampling rate converter. In these devices, one may see false spectrum lines (generally weak, while visible). To test that, you may generate a sine wave swap signal, then analyze its spectrogram using a different sampling rate.
89 |
90 | \u2022 This software consumes power at a high rate, e.g. about half the rate of viewing a HD video.
91 |
92 |
93 | Implementation Notes
94 | \u2022 All calculations of spectrum and spectrogram are done through fast Fourier transform (FFT) with the chosen window function, with a 50% data overlap.
95 |
96 | \u2022 The peak frequency is found by identifying the maximum spectrum point, then correcting it through quadratic interpolation fitting using three nearby points. The error is usually smaller than one tenth of (sample rate)/(FFT length). In the case of 48kHz samping and 8192 FFT length, that is about 0.6 Hz.
97 |
98 | \u2022 spam mode expends more power to run than in spum mode, and in a low-end device, that may exhaust all available computing power (CPU/GPU), especially at high sampling rates. Check Preferences to ensure you will receive a "Recorder buffer overrun" alert.
99 |
100 | \u2022 This software will drop frames when the specified sample rate is too high. For example, a sampling rate (SAMPLE/S) of 48000, with FFT length (FFT LEN) set to 1024 results in a frame rate per second (fps) equal to:
(SAMPLES/LENGTH)*2 = 48000 / 1024 * 2 = (93.75) fps, which is far too high for a mobile device.
101 |
102 |
103 |
104 |
105 |
106 |
107 | ]]>
108 |
109 |
110 |
--------------------------------------------------------------------------------
/audioSpectrumAnalyzer/src/main/java/org/woheller69/audio_analyzer_for_android/SelectorText.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2011 Google Inc.
2 | *
3 | *Licensed under the Apache License, Version 2.0 (the "License");
4 | *you may not use this file except in compliance with the License.
5 | *You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *Unless required by applicable law or agreed to in writing, software
10 | *distributed under the License is distributed on an "AS IS" BASIS,
11 | *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | *See the License for the specific language governing permissions and
13 | *limitations under the License.
14 | *
15 | * @author Stephen Uhler
16 | */
17 |
18 | package org.woheller69.audio_analyzer_for_android;
19 |
20 | import android.annotation.SuppressLint;
21 | import android.content.Context;
22 | import android.content.res.TypedArray;
23 | import android.graphics.Canvas;
24 | import android.graphics.Color;
25 | import android.graphics.Paint;
26 | import android.graphics.RectF;
27 | import android.util.AttributeSet;
28 | import android.util.Log;
29 | import android.view.animation.Animation;
30 | import android.view.animation.Animation.AnimationListener;
31 | import android.view.animation.RotateAnimation;
32 |
33 | import androidx.appcompat.widget.AppCompatTextView;
34 |
35 | /**
36 | * Text view that toggles through a set of values.
37 | * @author suhler@google.com (Stephen Uhler)
38 | */
39 |
40 | public class SelectorText extends AppCompatTextView {
41 | static final String TAG = "SelectorText:";
42 | private static float DPRatio;
43 | private static final int ANIMATION_DELAY = 70;
44 | private int value_id = 0;
45 | private String[] values = new String[0];
46 | private String[] valuesDisplay = new String[0];
47 | private Paint paint, bg;
48 | private RectF rect = new RectF();
49 | private RectF bgRect = new RectF();
50 | private float r;
51 |
52 | public SelectorText(Context context, AttributeSet attrs, int defStyle) {
53 | super(context, attrs, defStyle);
54 | setup(context, attrs);
55 | }
56 | public SelectorText(Context context, AttributeSet attrs) {
57 | super(context, attrs);
58 | setup(context, attrs);
59 | }
60 | public SelectorText(Context context) {
61 | super(context);
62 | setup(context, null);
63 | }
64 |
65 | @SuppressLint("ClickableViewAccessibility")
66 | @Override
67 | public boolean performClick() {
68 | setText(getText()); // fix the no-animation bug
69 | //setText(valuesDisplay[value_id]);
70 | Animation an = createAnimation(true, ANIMATION_DELAY);
71 | an.setAnimationListener(new AnimationListener() {
72 | @Override
73 | public void onAnimationEnd(Animation animation) {
74 | nextValue();
75 | SelectorText.super.performClick();
76 | createAnimation(false, ANIMATION_DELAY).start();
77 | }
78 | @Override public void onAnimationRepeat(Animation animation) {}
79 | @Override public void onAnimationStart(Animation animation) {}
80 | });
81 | an.start();
82 | return true;
83 | }
84 |
85 | /**
86 | * Choose an arbitrary animation for the text view.
87 | * @param start If true, animate the old value "out", otherwise animate the old value in
88 | * @param millis Animation time for this step, ms
89 | */
90 |
91 | private Animation createAnimation(boolean start, int millis) {
92 | RotateAnimation ra = new RotateAnimation(start?0f:180f, start?180f:360f, getWidth()/2, getHeight()/2);
93 | // Log.d("SelectorText", " createAnimation(): ");
94 | ra.setDuration(millis);
95 | setAnimation(ra);
96 | return ra;
97 | }
98 |
99 | /**
100 | * Compute the value of our "select" indicator.
101 | */
102 |
103 | @Override
104 | protected void onSizeChanged (int w, int h, int oldw, int oldh) {
105 | rect.set(2f*DPRatio, h/2 - 5f*DPRatio, 12f*DPRatio, h/2 + 7f*DPRatio);
106 | bgRect.set(1f*DPRatio, 1f*DPRatio, w - 2f*DPRatio, h - 1f*DPRatio);
107 | }
108 |
109 | /**
110 | * Draw the selector, then the selected text.
111 | */
112 | @Override
113 | protected void onDraw(Canvas c) {
114 | super.onDraw(c);
115 | //c.drawRoundRect(rect, r, r, paint);
116 | c.drawRoundRect(bgRect, r, r, paint);
117 | }
118 |
119 | /**
120 | * Initialize our selector. We could make most of the features customizable via XML.
121 | */
122 |
123 | private void setup(Context context, AttributeSet attrs) {
124 | DPRatio = getResources().getDisplayMetrics().density;
125 | r = 3 * DPRatio;
126 |
127 | bg = new Paint();
128 | bg.setStrokeWidth(2*DPRatio);
129 | bg.setColor(Color.GRAY);
130 | bg.setStyle(Paint.Style.STROKE);
131 | paint = new Paint(bg);
132 | paint.setColor(Color.GREEN);
133 |
134 | setClickable(true);
135 | if (attrs != null) {
136 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SelectorText);
137 | String items = a.getString(R.styleable.SelectorText_items);
138 | String delim = getValue(a, R.styleable.SelectorText_itemDelim, " ");
139 | String itemsDisplay = a.getString(R.styleable.SelectorText_itemsDisplay);
140 | if (items != null) {
141 | // Log.i(AnalyzerActivity.TAG, "items: " + items);
142 | if (itemsDisplay != null && itemsDisplay.length() > 0) {
143 | setValues(items.split(delim), itemsDisplay.split("::"));
144 | } else {
145 | setValues(items.split(delim), items.split(delim));
146 | }
147 | }
148 | a.recycle();
149 | }
150 | if (valuesDisplay.length > 0) {
151 | setText(valuesDisplay[0]);
152 | }
153 | }
154 |
155 | private static String getValue(TypedArray a, int index, String dflt) {
156 | String result = a.getString(index);
157 | return result == null ? dflt : result;
158 | }
159 |
160 | public void setValues(String[] values, String[] valuesDisplay) {
161 | this.values = values;
162 | if (values.length == valuesDisplay.length) {
163 | this.valuesDisplay = valuesDisplay;
164 | } else {
165 | Log.w(TAG, "values.length != valuesDisplay.length");
166 | this.valuesDisplay = values;
167 | }
168 | adjustWidth();
169 | invalidate();
170 | }
171 |
172 | public String getValue() { return values[value_id]; }
173 |
174 | public String[] getValues() {
175 | return values;
176 | }
177 |
178 | public void setValue(String v) {
179 | for (int i = 0; i < values.length; i++) {
180 | if (! v.equals(values[value_id])) {
181 | nextValue();
182 | }
183 | }
184 | }
185 |
186 | public String nextValue() {
187 | if (values.length != 0) {
188 | value_id++;
189 | if (value_id >= values.length) {
190 | value_id = 0;
191 | }
192 | setText(valuesDisplay[value_id]);
193 | return valuesDisplay[value_id];
194 | }
195 | return getText().toString();
196 | }
197 |
198 | private void adjustWidth() {
199 | Paint p = getPaint();
200 | int adj = getPaddingLeft() + getPaddingRight();
201 | int width = 0;
202 | for (String s : valuesDisplay) {
203 | width = Math.max(width, Math.round(p.measureText(s)));
204 | }
205 | setMinWidth(width + adj + (int)(4*DPRatio));
206 | }
207 | }
--------------------------------------------------------------------------------
/audioSpectrumAnalyzer/src/main/res/xml/preferences.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
14 |
15 |
22 |
29 |
36 |
43 |
44 |
45 |
48 |
53 |
54 |
61 |
62 |
69 |
70 |
76 |
77 |
78 |
79 |
82 |
87 |
92 |
97 |
102 |
103 |
110 |
117 |
124 |
131 |
132 |
133 |
136 |
141 |
142 |
143 |
146 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/audioSpectrumAnalyzer/src/main/java/org/woheller69/audio_analyzer_for_android/AxisTickLabels.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.audio_analyzer_for_android;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 |
6 | class AxisTickLabels {
7 | private static final String[] axisNames = {"Hz", "dB", "Sec", "Hz", "Pitch"}; // See GridLabel.Type
8 |
9 | // Draw ticks and labels for a axisMap.
10 | // labelPaint should use fixed width font
11 | static void draw(Canvas c, ScreenPhysicalMapping axisMap, GridLabel gridLabel,
12 | float axisBeginX, float axisBeginY, int directionI, int labelSide,
13 | Paint labelPaint, Paint gridPaint, Paint rulerBrightPaint) {
14 | String axisName = axisNames[gridLabel.getGridType().getValue()];
15 |
16 | float textHeight = labelPaint.getFontMetrics(null);
17 | float labelLargeLen = 0.7f * textHeight;
18 | float labelSmallLen = 0.6f * labelLargeLen;
19 |
20 | // directionI: 0:+x, 1:+y, 2:-x, 3:-y
21 | // labelSide: 1: label at positive side of axis, -1: otherwise
22 | boolean drawOnXAxis = directionI % 2 == 0;
23 | int directionSign = directionI <=1 ? 1 : -1;
24 |
25 | // Plot axis marks
26 | float posAlongAxis;
27 | for (int k = 0; k < 2; k ++) {
28 | float labelLen = (k == 0 ? labelSmallLen : labelLargeLen) * labelSide;
29 | Paint tickPainter = k == 0 ? gridPaint : rulerBrightPaint;
30 | double[] values = k == 0 ? gridLabel.ticks : gridLabel.values;
31 | for (int i = 0; i < values.length; i++) {
32 | posAlongAxis = (float)axisMap.pixelFromV(values[i]) * directionSign;
33 | if (drawOnXAxis) {
34 | c.drawLine(axisBeginX + posAlongAxis, axisBeginY,
35 | axisBeginX + posAlongAxis, axisBeginY + labelLen, tickPainter);
36 | } else {
37 | c.drawLine(axisBeginX, axisBeginY + posAlongAxis,
38 | axisBeginX + labelLen, axisBeginY + posAlongAxis, tickPainter);
39 | }
40 | }
41 | }
42 | // Straight line
43 | if (drawOnXAxis) {
44 | c.drawLine(axisBeginX, axisBeginY, axisBeginX + (float)axisMap.nCanvasPixel * (1-directionI), axisBeginY, labelPaint);
45 | } else {
46 | c.drawLine(axisBeginX, axisBeginY, axisBeginX, axisBeginY + (float)axisMap.nCanvasPixel * (2-directionI), labelPaint);
47 | }
48 |
49 | // Plot labels
50 | float widthDigit = labelPaint.measureText("0");
51 | float widthAxisName = widthDigit * axisName.length();
52 | float widthAxisNameExt = widthAxisName +.5f*widthDigit; // with a safe boundary
53 |
54 | // For drawOnXAxis == true
55 | float axisNamePosX = directionSign==1
56 | ? - widthAxisNameExt + (float)axisMap.nCanvasPixel
57 | : - widthAxisNameExt;
58 | // For drawOnXAxis == false
59 | // always show y-axis name at the smaller (in pixel) position.
60 | float axisNamePosY = directionSign==1
61 | ? textHeight
62 | : textHeight - (float)axisMap.nCanvasPixel;
63 | if (gridLabel.getGridType() == GridLabel.Type.DB) {
64 | // For dB axis, show axis name far from 0dB (directionSign==1)
65 | axisNamePosY = (float)axisMap.nCanvasPixel - 0.8f*widthDigit;
66 | }
67 |
68 | float labelPosY = axisBeginY + ( labelSide == 1 ? 0.1f*labelLargeLen + textHeight : -0.3f*labelLargeLen);
69 | float labelPosX;
70 | int notShowNextLabel = 0;
71 |
72 | for(int i = 0; i < gridLabel.strings.length; i++) {
73 | posAlongAxis = (float)axisMap.pixelFromV(gridLabel.values[i]) * directionSign;
74 | float thisDigitWidth = drawOnXAxis ? widthDigit*gridLabel.strings[i].length() + 0.3f*widthDigit
75 | : -textHeight;
76 | float axisNamePos = drawOnXAxis ? axisNamePosX
77 | : axisNamePosY;
78 | float axisNameLen = drawOnXAxis ? widthAxisNameExt
79 | : -textHeight;
80 |
81 | // Avoid label overlap:
82 | // (1) No overlap to axis name like "Hz";
83 | // (2) If no (1), no overlap to important label 1, 10, 100, 1000, 10000, 1k, 10k;
84 | // (3) If no (1) and (2), no overlap to previous label.
85 | if (isIntvOverlap(posAlongAxis, thisDigitWidth,
86 | axisNamePos, axisNameLen)) {
87 | continue; // case (1)
88 | }
89 | if (notShowNextLabel > 0) {
90 | notShowNextLabel--;
91 | continue; // case (3)
92 | }
93 | int j = i+1;
94 | while (j < gridLabel.strings.length) {
95 | float nextDigitPos = (float)axisMap.pixelFromV(gridLabel.values[j]) * directionSign;
96 | float nextDigitWidth = drawOnXAxis ? widthDigit*gridLabel.strings[j].length() + 0.3f*widthDigit
97 | : -textHeight;
98 | if (! isIntvOverlap(posAlongAxis, thisDigitWidth,
99 | nextDigitPos, nextDigitWidth)) {
100 | break; // no overlap of case (3)
101 | }
102 | notShowNextLabel++;
103 | if (gridLabel.isImportantLabel(j)) {
104 | // do not show label i (case (2))
105 | // but also check case (1) for label j
106 | if (! isIntvOverlap(nextDigitPos, nextDigitWidth,
107 | axisNamePos, axisNameLen)) {
108 | notShowNextLabel = -1;
109 | break;
110 | }
111 | }
112 | j++;
113 | }
114 | if (notShowNextLabel == -1) {
115 | notShowNextLabel = j - i - 1; // show the label in case (2)
116 | continue;
117 | }
118 |
119 | // Now safe to draw label
120 | if (drawOnXAxis) {
121 | c.drawText(gridLabel.chars[i], 0, gridLabel.strings[i].length(),
122 | axisBeginX + posAlongAxis, labelPosY, labelPaint);
123 | } else {
124 | labelPosX = labelSide == -1
125 | ? axisBeginX - 0.5f * labelLargeLen - widthDigit * gridLabel.strings[i].length()
126 | : axisBeginX + 0.5f * labelLargeLen;
127 | c.drawText(gridLabel.chars[i], 0, gridLabel.strings[i].length(),
128 | labelPosX, axisBeginY + posAlongAxis, labelPaint);
129 | }
130 | }
131 | if (drawOnXAxis) {
132 | c.drawText(axisName, axisBeginX + axisNamePosX, labelPosY, labelPaint);
133 | } else {
134 | labelPosX = labelSide == -1
135 | ? axisBeginX - 0.5f * labelLargeLen - widthAxisName
136 | : axisBeginX + 0.5f * labelLargeLen;
137 | c.drawText(axisName, labelPosX, axisBeginY + axisNamePosY, labelPaint);
138 | }
139 |
140 | }
141 |
142 | // Return true if two intervals [pos1, pos1+len1] [pos2, pos2+len2] overlaps.
143 | private static boolean isIntvOverlap(float pos1, float len1, float pos2, float len2) {
144 | if (len1 < 0) { pos1 -= len1; len1 = -len1; }
145 | if (len2 < 0) { pos2 -= len2; len2 = -len2; }
146 | return pos1 <= pos2 && pos2 <= pos1+len1 || pos2 <= pos1 && pos1 <= pos2+len2;
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/audioSpectrumAnalyzer/src/main/java/org/woheller69/audio_analyzer_for_android/ScreenPhysicalMapping.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2017 Eddy Xiao
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | package org.woheller69.audio_analyzer_for_android;
17 |
18 | import android.util.Log;
19 |
20 | import static java.lang.Math.exp;
21 | import static java.lang.Math.log;
22 |
23 | /**
24 | * Mapping between physical value and screen pixel position
25 | * Use double or float ?
26 | */
27 |
28 | // | lower bound ... higher bound | physical unit
29 | // | 0 ... 1 | "unit 1" (Mapping can be linear or logarithmic)
30 |
31 | // In LINEAR mode (default):
32 | // |lower value ... higher value| physical unit
33 | // | shift ... shift + 1/zoom | "unit 1", 0=vLowerBound, 1=vUpperBound
34 | // | 0 | 1 | ... | n-1 | pixel
35 |
36 | // In LINEAR_ON mode (not implemented):
37 | // |lower value ... higher value| physical unit
38 | // | shift ... shift + 1/zoom | "unit 1" window
39 | // | 0 | 1 | ... | n-1 | pixel
40 |
41 | class ScreenPhysicalMapping {
42 | private final static String TAG = "ScreenPhysicalMapping";
43 |
44 | enum Type { // java's enum type is inconvenient
45 | LINEAR(0), LINEAR_ON(1), LOG(2);
46 |
47 | private final int value;
48 | Type(int value) { this.value = value; }
49 | public int getValue() { return value; }
50 | }
51 |
52 | Type mapType; // Linear or Log
53 | double nCanvasPixel;
54 | double vLowerBound, vUpperBound; // Physical limits
55 | private double vLowerViewBound, vUpperViewBound; // view bounds
56 | private double zoom = 1, shift = 0; // zoom==1: no zooming, shift=0: no shift
57 |
58 | ScreenPhysicalMapping(double _nCanvasPixel, double _vLowerBound, double _vHigherBound, ScreenPhysicalMapping.Type _mapType) {
59 | nCanvasPixel = _nCanvasPixel;
60 | vLowerBound = _vLowerBound;
61 | vUpperBound = _vHigherBound;
62 | vLowerViewBound = vLowerBound;
63 | vUpperViewBound = vUpperBound;
64 | mapType = _mapType;
65 | }
66 |
67 | ScreenPhysicalMapping(ScreenPhysicalMapping _axis) {
68 | mapType = _axis.mapType;
69 | nCanvasPixel = _axis.nCanvasPixel;
70 | vLowerBound = _axis.vLowerBound;
71 | vUpperBound = _axis.vUpperBound;
72 | vLowerViewBound = _axis.vLowerViewBound;
73 | vUpperViewBound = _axis.vUpperViewBound;
74 | zoom = _axis.zoom;
75 | shift = _axis.shift;
76 | }
77 |
78 | void setNCanvasPixel(double _nCanvasPixel) {
79 | nCanvasPixel = _nCanvasPixel;
80 | }
81 |
82 | void setBounds(double _vL, double _vU) {
83 | vLowerBound = _vL;
84 | vUpperBound = _vU;
85 | // Reset view range, preserve zoom and shift
86 | setZoomShift(zoom, shift);
87 | if (AnalyzerUtil.isAlmostInteger(vLowerViewBound)) { // dirty fix...
88 | vLowerViewBound = Math.round(vLowerViewBound);
89 | }
90 | if (AnalyzerUtil.isAlmostInteger(vUpperViewBound)) {
91 | vUpperViewBound = Math.round(vUpperViewBound);
92 | }
93 | setViewBounds(vLowerViewBound, vUpperViewBound); // refine zoom shift
94 | }
95 |
96 | double getZoom() { return zoom; }
97 | double getShift() { return shift; }
98 |
99 | void setZoomShift(double _zoom, double _shift) {
100 | zoom = _zoom;
101 | shift = _shift;
102 | vLowerViewBound = vFromUnitPosition(0, zoom, shift);
103 | vUpperViewBound = vFromUnitPosition(1, zoom, shift);
104 | }
105 |
106 | // set zoom and shift from physical value bounds
107 | void setViewBounds(double vL, double vU) {
108 | if (vL == vU) {
109 | return; // Or throw an exception?
110 | }
111 | double p1 = UnitPositionFromV(vL, vLowerBound, vUpperBound);
112 | double p2 = UnitPositionFromV(vU, vLowerBound, vUpperBound);
113 | zoom = 1 / (p2 - p1);
114 | shift = p1;
115 | vLowerViewBound = vL;
116 | vUpperViewBound = vU;
117 | }
118 |
119 | double UnitPositionFromV(double v, double vL, double vU) {
120 | if (vL == vU) {
121 | return 0;
122 | }
123 | if (mapType == Type.LINEAR) {
124 | return (v - vL) / (vU - vL);
125 | } else {
126 | return log(v/vL) / log(vU/vL);
127 | }
128 | }
129 |
130 | double vFromUnitPosition(double u, double zoom, double shift) {
131 | if (zoom == 0) {
132 | return 0;
133 | }
134 | if (mapType == Type.LINEAR) {
135 | return (u / zoom + shift) * (vUpperBound - vLowerBound) + vLowerBound;
136 | } else {
137 | return exp((u / zoom + shift) * log(vUpperBound / vLowerBound)) * vLowerBound;
138 | }
139 | }
140 |
141 | double pixelFromV(double v) {
142 | return UnitPositionFromV(v, vLowerViewBound, vUpperViewBound) * nCanvasPixel;
143 | }
144 |
145 | double vFromPixel(double pixel) {
146 | if (nCanvasPixel == 0)
147 | return vLowerViewBound;
148 | return vFromUnitPosition(pixel / nCanvasPixel, zoom, shift);
149 | }
150 |
151 | double vMinInView() {
152 | return vLowerViewBound;
153 | }
154 |
155 | double vMaxInView() {
156 | return vUpperViewBound;
157 | }
158 |
159 | double pixelNoZoomFromV(double v) {
160 | return UnitPositionFromV(v, vLowerBound, vUpperBound) * nCanvasPixel;
161 | }
162 |
163 | double diffVBounds() { return vUpperBound - vLowerBound; }
164 |
165 | void reverseBounds() {
166 | double oldVL = vLowerViewBound;
167 | double oldVU = vUpperViewBound;
168 | setBounds(vUpperBound, vLowerBound);
169 | setViewBounds(oldVU, oldVL);
170 | }
171 |
172 | void setMappingType(ScreenPhysicalMapping.Type _mapType, double lower_bound_ref) {
173 | // Set internal variables if possible
174 | double vL = vMinInView();
175 | double vH = vMaxInView();
176 | if (_mapType == Type.LOG) {
177 | if (vLowerBound == 0) vLowerBound = lower_bound_ref;
178 | if (vUpperBound == 0) vUpperBound = lower_bound_ref;
179 | } else {
180 | if (vLowerBound == lower_bound_ref) vLowerBound = 0;
181 | if (vUpperBound == lower_bound_ref) vUpperBound = 0;
182 | }
183 | boolean bNeedUpdateZoomShift = mapType != _mapType;
184 | mapType = _mapType;
185 | if (!bNeedUpdateZoomShift || nCanvasPixel == 0 || vLowerBound == vUpperBound) {
186 | return;
187 | }
188 |
189 | // Update zoom and shift
190 | // lower_bound_ref is for how to map zero
191 | // Only support non-negative bounds
192 | if (_mapType == Type.LOG) {
193 | if (vL < 0 || vH < 0) {
194 | Log.e(TAG, "setMappingType(): negative bounds.");
195 | return;
196 | }
197 | if (vL < lower_bound_ref) vL = lower_bound_ref;
198 | if (vH < lower_bound_ref) vH = lower_bound_ref;
199 | } else {
200 | if (vL <= lower_bound_ref) vL = 0;
201 | if (vH <= lower_bound_ref) vH = 0;
202 | }
203 | setViewBounds(vL, vH);
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/audioSpectrumAnalyzer/src/main/java/org/woheller69/audio_analyzer_for_android/SpectrumPlot.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2014 Eddy Xiao
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | package org.woheller69.audio_analyzer_for_android;
17 |
18 | import android.content.Context;
19 | import android.content.SharedPreferences;
20 | import android.graphics.Canvas;
21 | import android.graphics.Color;
22 | import android.graphics.Paint;
23 | import android.graphics.Typeface;
24 | import android.os.SystemClock;
25 | import android.util.Log;
26 | import androidx.preference.PreferenceManager;
27 |
28 | /**
29 | * The spectrum plot part of AnalyzerGraphic
30 | */
31 |
32 | class SpectrumPlot {
33 | private static final String TAG = "SpectrumPlot:";
34 | boolean showLines;
35 | private Paint linePaint, linePaintLight, linePeakPaint;
36 | private Paint cursorPaint;
37 | private Paint gridPaint;
38 | private Paint labelPaint;
39 | private Paint calibNamePaint;
40 | private Paint calibLinePaint;
41 | private int canvasHeight=0, canvasWidth=0;
42 |
43 | private float DPRatio;
44 | private AnalyzerUtil.PeakHoldAndFall peakHold;
45 | double cursorFreq, cursorDB; // cursor location
46 | private Plot2D plot2D;
47 | ScreenPhysicalMapping axisX, axisY;
48 |
49 | SpectrumPlot(Context _context) {
50 | DPRatio = _context.getResources().getDisplayMetrics().density;
51 |
52 | linePaint = new Paint();
53 | linePaint.setColor(Color.parseColor("#0D2C6D"));
54 | linePaint.setStyle(Paint.Style.STROKE);
55 | linePaint.setStrokeWidth(1);
56 |
57 | linePaintLight = new Paint(linePaint);
58 | linePaintLight.setColor(Color.parseColor("#3AB3E2"));
59 |
60 | linePeakPaint = new Paint(linePaint);
61 | linePeakPaint.setColor(0xFF00A0A0);
62 |
63 | gridPaint = new Paint();
64 | gridPaint.setColor(Color.DKGRAY);
65 | gridPaint.setStyle(Paint.Style.STROKE);
66 | gridPaint.setStrokeWidth(1.0f * DPRatio);
67 |
68 | cursorPaint = new Paint(gridPaint);
69 | cursorPaint.setColor(Color.parseColor("#00CD00"));
70 | cursorPaint.setStrokeWidth(2);
71 |
72 | labelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
73 | labelPaint.setColor(Color.GRAY);
74 | labelPaint.setTextSize(14.0f * DPRatio);
75 | labelPaint.setTypeface(Typeface.MONOSPACE); // or Typeface.SANS_SERIF
76 |
77 | calibNamePaint = new Paint(labelPaint);
78 | calibNamePaint.setColor(Color.YELLOW & 0x66ffffff);
79 | calibLinePaint = new Paint(linePaint);
80 | calibLinePaint.setColor(Color.YELLOW);
81 |
82 | cursorFreq = cursorDB = 0f;
83 |
84 | plot2D = new Plot2D(
85 | ScreenPhysicalMapping.Type.LINEAR, GridLabel.Type.FREQ,
86 | ScreenPhysicalMapping.Type.LINEAR, GridLabel.Type.DB,
87 | canvasWidth, canvasHeight, DPRatio);
88 | axisX = plot2D.axisX;
89 | axisY = plot2D.axisY;
90 |
91 | SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(_context);
92 | int peakHoldTime = sharedPref.getInt("prefPeakHold",2);
93 | int peakDropSpeed = sharedPref.getInt("prefPeakDropSpeed", 20);
94 | peakHold = new AnalyzerUtil.PeakHoldAndFall((double) peakHoldTime, (double) peakDropSpeed);
95 | }
96 |
97 | void setCanvas(int _canvasWidth, int _canvasHeight, double[] axisBounds) {
98 | // Log.i("SpectrumPlot", "setCanvas: W="+_canvasWidth+" H="+_canvasHeight);
99 | canvasWidth = _canvasWidth;
100 | canvasHeight = _canvasHeight;
101 | plot2D.setCanvasBound(_canvasWidth, _canvasHeight, axisBounds, DPRatio);
102 | }
103 |
104 | void setZooms(double xZoom, double xShift, double yZoom, double yShift) {
105 | plot2D.axisX.setZoomShift(xZoom, xShift);
106 | plot2D.axisY.setZoomShift(yZoom, yShift);
107 | }
108 |
109 | // Linear or Logarithmic frequency axis
110 | void setFreqAxisMode(ScreenPhysicalMapping.Type mapType, double freq_lower_bound_for_log, GridLabel.Type gridType) {
111 | plot2D.axisX.setMappingType(mapType, freq_lower_bound_for_log);
112 | plot2D.gridLabelX.setGridType(gridType);
113 | Log.i(TAG, "setFreqAxisMode(): set to mode " + mapType + " axisX.vL=" + plot2D.axisX.vLowerBound + " freq_lower_bound_for_log = " + freq_lower_bound_for_log);
114 | }
115 |
116 | private double[] y_calib = null;
117 | private double[] x_calib = null;
118 | private String name_calib = null;
119 |
120 | void addCalibCurve(double[] y, double[] x, String name) {
121 | y_calib = y;
122 | x_calib = x;
123 | name_calib = name;
124 | }
125 |
126 | private double[] db_cache = null;
127 | private long timeLastCall;
128 |
129 | // Plot the spectrum into the Canvas c
130 | private void drawSpectrumOnCanvas(Canvas c, final double[] _db) {
131 | if (canvasHeight < 1 || _db == null || _db.length == 0) {
132 | return;
133 | }
134 | AnalyzerGraphic.setIsBusy(true);
135 |
136 | synchronized (_db) { // TODO: need lock on savedDBSpectrum, but how?
137 | if (db_cache == null || db_cache.length != _db.length) {
138 | Log.d(TAG, "drawSpectrumOnCanvas(): new db_cache");
139 | db_cache = new double[_db.length];
140 | }
141 | System.arraycopy(_db, 0, db_cache, 0, _db.length);
142 | }
143 |
144 | long timeNow = SystemClock.uptimeMillis();
145 | peakHold.addCurrentValue(db_cache, (timeNow - timeLastCall)/1000.0);
146 | timeLastCall = timeNow;
147 |
148 | // Spectrum peak hold
149 | plot2D.plotLineBar(c, peakHold.v_peak, null, false, linePeakPaint, null);
150 |
151 | // Spectrum line and bar
152 | plot2D.plotLineBar(c, db_cache, null, !showLines, linePaintLight, linePaint);
153 |
154 | // Name of calibration curve.
155 | if (name_calib != null) {
156 | c.save();
157 | c.translate(30*DPRatio, (float)plot2D.axisY.pixelFromV(0));
158 | c.drawText(name_calib, 0, 0, calibNamePaint);
159 | c.restore();
160 | }
161 | plot2D.plotLineBar(c, y_calib, x_calib, false, calibLinePaint, null);
162 |
163 | AnalyzerGraphic.setIsBusy(false);
164 | }
165 |
166 | // x, y is in pixel unit
167 | void setCursor(double x, double y) {
168 | cursorFreq = plot2D.axisX.vFromPixel(x); // frequency
169 | cursorDB = plot2D.axisY.vFromPixel(y); // decibel
170 | }
171 |
172 | // x, y is in frequency/DB units
173 | void setCursorFreq(double x, double y) {
174 | cursorFreq = x;
175 | cursorDB = y;
176 | }
177 |
178 | double getCursorFreq() {
179 | return canvasWidth == 0 ? 0 : cursorFreq;
180 | }
181 |
182 | double getCursorDB() {
183 | return canvasHeight == 0 ? 0 : cursorDB;
184 | }
185 |
186 | void hideCursor() {
187 | cursorFreq = 0;
188 | cursorDB = 0;
189 | }
190 |
191 | // Plot spectrum with axis and ticks on the whole canvas c
192 | void drawSpectrumPlot(Canvas c, double[] savedDBSpectrum) {
193 | plot2D.updateGridLabels();
194 | plot2D.drawGridLines(c, gridPaint);
195 | drawSpectrumOnCanvas(c, savedDBSpectrum);
196 | if (cursorFreq != 0) {
197 | plot2D.plotCrossline(c, cursorFreq, cursorDB, cursorPaint);
198 | }
199 |
200 | plot2D.drawAxisLabels(c, labelPaint, gridPaint, gridPaint);
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/audioSpectrumAnalyzer/src/main/java/org/woheller69/audio_analyzer_for_android/WavWriter.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2014 Eddy Xiao
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | package org.woheller69.audio_analyzer_for_android;
17 |
18 | import static android.os.Environment.DIRECTORY_MUSIC;
19 | import android.annotation.SuppressLint;
20 | import android.os.Environment;
21 | import android.os.StatFs;
22 | import android.util.Log;
23 |
24 | import java.io.File;
25 | import java.io.FileOutputStream;
26 | import java.io.IOException;
27 | import java.io.OutputStream;
28 | import java.io.RandomAccessFile;
29 | import java.text.DateFormat;
30 | import java.text.SimpleDateFormat;
31 | import java.util.Date;
32 | import java.util.Locale;
33 |
34 | class WavWriter {
35 | private static final String TAG = "WavWriter";
36 | private File outPath;
37 | private OutputStream out;
38 | private byte[] header = new byte[44];
39 |
40 | private int channels = 1;
41 | private byte RECORDER_BPP = 16; // bits per sample
42 | private int byteRate; // Average bytes per second
43 | private int totalDataLen = 0; // (file size) - 8
44 | private int totalAudioLen = 0; // bytes of audio raw data
45 | private int framesWritten = 0;
46 |
47 | WavWriter(int sampleRate) {
48 | byteRate = sampleRate*RECORDER_BPP/8*channels;
49 |
50 | header[0] = 'R'; // RIFF/WAVE header
51 | header[1] = 'I';
52 | header[2] = 'F';
53 | header[3] = 'F';
54 | header[4] = (byte) (totalDataLen & 0xff);
55 | header[5] = (byte) ((totalDataLen >> 8) & 0xff);
56 | header[6] = (byte) ((totalDataLen >> 16) & 0xff);
57 | header[7] = (byte) ((totalDataLen >> 24) & 0xff);
58 | header[8] = 'W';
59 | header[9] = 'A';
60 | header[10] = 'V';
61 | header[11] = 'E';
62 | header[12] = 'f'; // 'fmt ' chunk
63 | header[13] = 'm';
64 | header[14] = 't';
65 | header[15] = ' ';
66 | header[16] = 16; // 4 bytes: size of 'fmt ' chunk
67 | header[17] = 0;
68 | header[18] = 0;
69 | header[19] = 0;
70 | header[20] = 1; // format = 1, PCM/uncompressed
71 | header[21] = 0;
72 | header[22] = (byte) channels;
73 | header[23] = 0;
74 | header[24] = (byte) (sampleRate & 0xff);
75 | header[25] = (byte) ((sampleRate >> 8) & 0xff);
76 | header[26] = (byte) ((sampleRate >> 16) & 0xff);
77 | header[27] = (byte) ((sampleRate >> 24) & 0xff);
78 | header[28] = (byte) (byteRate & 0xff); // Average bytes per second
79 | header[29] = (byte) ((byteRate >> 8) & 0xff);
80 | header[30] = (byte) ((byteRate >> 16) & 0xff);
81 | header[31] = (byte) ((byteRate >> 24) & 0xff);
82 | header[32] = (byte) (channels * RECORDER_BPP / 8); // Block align (number of bytes per sample slice)
83 | header[33] = 0;
84 | header[34] = RECORDER_BPP; // bits per sample (Significant bits per sample)
85 | header[35] = 0; // Extra format bytes
86 | header[36] = 'd';
87 | header[37] = 'a';
88 | header[38] = 't';
89 | header[39] = 'a';
90 | header[40] = (byte) (totalAudioLen & 0xff);
91 | header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
92 | header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
93 | header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
94 | }
95 |
96 | private static final int version = android.os.Build.VERSION.SDK_INT;
97 |
98 | @SuppressLint("NewApi")
99 | @SuppressWarnings("deprecation")
100 | double secondsLeft() {
101 | long byteLeft;
102 | if (version >= 9) {
103 | byteLeft = outPath.getFreeSpace(); // Need API level 9
104 | } else {
105 | StatFs statFs = new StatFs(outPath.getAbsolutePath());
106 | byteLeft = (statFs.getAvailableBlocks() * (long)statFs.getBlockSize());
107 | }
108 | if (byteRate == 0 || byteLeft == 0) {
109 | return 0;
110 | }
111 | return (double)byteLeft / byteRate;
112 | }
113 |
114 | boolean start() {
115 | if (!isExternalStorageWritable()) {
116 | return false;
117 | }
118 | File path = Environment.getExternalStoragePublicDirectory(DIRECTORY_MUSIC);
119 | if (!path.exists() && !path.mkdirs()) {
120 | Log.e(TAG, "Failed to make directory: " + path.toString());
121 | return false;
122 | }
123 | DateFormat df = new SimpleDateFormat("yyyy-MM-dd_HH'h'mm'm'ss.SSS's'", Locale.US);
124 | String nowStr = df.format(new Date());
125 | outPath = new File(path, "rec" + nowStr + ".wav");
126 |
127 | try {
128 | out = new FileOutputStream(outPath);
129 | out.write(header, 0, 44);
130 | // http://developer.android.com/reference/android/os/Environment.html#getExternalStoragePublicDirectory%28java.lang.String%29
131 | } catch (IOException e) {
132 | Log.w(TAG, "start(): Error writing " + outPath, e);
133 | out = null;
134 | }
135 | return true;
136 | }
137 |
138 | void stop() {
139 | if (out == null) {
140 | Log.w(TAG, "stop(): Error closing " + outPath + " null pointer");
141 | return;
142 | }
143 | try {
144 | out.close();
145 | } catch (IOException e) {
146 | Log.w(TAG, "stop(): Error closing " + outPath, e);
147 | }
148 | out = null;
149 | // Modify totalDataLen and totalAudioLen to match data
150 | RandomAccessFile raf;
151 | try {
152 | totalAudioLen = framesWritten * RECORDER_BPP / 8 * channels;
153 | totalDataLen = header.length + totalAudioLen - 8;
154 | raf = new RandomAccessFile(outPath, "rw");
155 | raf.seek(4);
156 | raf.write((byte) ((totalDataLen ) & 0xff));
157 | raf.write((byte) ((totalDataLen >> 8) & 0xff));
158 | raf.write((byte) ((totalDataLen >> 16) & 0xff));
159 | raf.write((byte) ((totalDataLen >> 24) & 0xff));
160 | raf.seek(40);
161 | raf.write((byte) ((totalAudioLen ) & 0xff));
162 | raf.write((byte) ((totalAudioLen >> 8) & 0xff));
163 | raf.write((byte) ((totalAudioLen >> 16) & 0xff));
164 | raf.write((byte) ((totalAudioLen >> 24) & 0xff));
165 | raf.close();
166 | } catch (IOException e) {
167 | Log.w(TAG, "stop(): Error modifying " + outPath, e);
168 | }
169 | }
170 |
171 | private byte[] byteBuffer;
172 |
173 | // Assume RECORDER_BPP == 16 and channels == 1
174 | void pushAudioShort(short[] ss, int numOfReadShort) {
175 | if (out == null) {
176 | Log.w(TAG, "pushAudioShort(): Error writing " + outPath + " null pointer");
177 | return;
178 | }
179 | if (byteBuffer == null || byteBuffer.length != ss.length*2) {
180 | byteBuffer = new byte[ss.length*2];
181 | }
182 | for (int i = 0; i < numOfReadShort; i++) {
183 | byteBuffer[2*i ] = (byte)(ss[i] & 0xff);
184 | byteBuffer[2*i+1] = (byte)((ss[i]>>8) & 0xff);
185 | }
186 | framesWritten += numOfReadShort;
187 | try {
188 | out.write(byteBuffer, 0, numOfReadShort*2);
189 | // if use out.write(byte), then a lot of GC will generated
190 | } catch (IOException e) {
191 | Log.w(TAG, "pushAudioShort(): Error writing " + outPath, e);
192 | out = null;
193 | }
194 | }
195 |
196 | double secondsWritten() {
197 | return (double) framesWritten /(byteRate*8/RECORDER_BPP/channels);
198 | }
199 |
200 | /* Checks if external storage is available for read and write */
201 | boolean isExternalStorageWritable() {
202 | String state = Environment.getExternalStorageState(); // Need API level 8
203 | return Environment.MEDIA_MOUNTED.equals(state);
204 | }
205 |
206 | String getPath() {
207 | return outPath.getPath();
208 | }
209 |
210 | String getDir(){
211 | return String.valueOf(Environment.getExternalStoragePublicDirectory(DIRECTORY_MUSIC));
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/util/inferno.csv:
--------------------------------------------------------------------------------
1 | 0.001462, 0.000466, 0.013866
2 | 0.002267, 0.001270, 0.018570
3 | 0.003299, 0.002249, 0.024239
4 | 0.004547, 0.003392, 0.030909
5 | 0.006006, 0.004692, 0.038558
6 | 0.007676, 0.006136, 0.046836
7 | 0.009561, 0.007713, 0.055143
8 | 0.011663, 0.009417, 0.063460
9 | 0.013995, 0.011225, 0.071862
10 | 0.016561, 0.013136, 0.080282
11 | 0.019373, 0.015133, 0.088767
12 | 0.022447, 0.017199, 0.097327
13 | 0.025793, 0.019331, 0.105930
14 | 0.029432, 0.021503, 0.114621
15 | 0.033385, 0.023702, 0.123397
16 | 0.037668, 0.025921, 0.132232
17 | 0.042253, 0.028139, 0.141141
18 | 0.046915, 0.030324, 0.150164
19 | 0.051644, 0.032474, 0.159254
20 | 0.056449, 0.034569, 0.168414
21 | 0.061340, 0.036590, 0.177642
22 | 0.066331, 0.038504, 0.186962
23 | 0.071429, 0.040294, 0.196354
24 | 0.076637, 0.041905, 0.205799
25 | 0.081962, 0.043328, 0.215289
26 | 0.087411, 0.044556, 0.224813
27 | 0.092990, 0.045583, 0.234358
28 | 0.098702, 0.046402, 0.243904
29 | 0.104551, 0.047008, 0.253430
30 | 0.110536, 0.047399, 0.262912
31 | 0.116656, 0.047574, 0.272321
32 | 0.122908, 0.047536, 0.281624
33 | 0.129285, 0.047293, 0.290788
34 | 0.135778, 0.046856, 0.299776
35 | 0.142378, 0.046242, 0.308553
36 | 0.149073, 0.045468, 0.317085
37 | 0.155850, 0.044559, 0.325338
38 | 0.162689, 0.043554, 0.333277
39 | 0.169575, 0.042489, 0.340874
40 | 0.176493, 0.041402, 0.348111
41 | 0.183429, 0.040329, 0.354971
42 | 0.190367, 0.039309, 0.361447
43 | 0.197297, 0.038400, 0.367535
44 | 0.204209, 0.037632, 0.373238
45 | 0.211095, 0.037030, 0.378563
46 | 0.217949, 0.036615, 0.383522
47 | 0.224763, 0.036405, 0.388129
48 | 0.231538, 0.036405, 0.392400
49 | 0.238273, 0.036621, 0.396353
50 | 0.244967, 0.037055, 0.400007
51 | 0.251620, 0.037705, 0.403378
52 | 0.258234, 0.038571, 0.406485
53 | 0.264810, 0.039647, 0.409345
54 | 0.271347, 0.040922, 0.411976
55 | 0.277850, 0.042353, 0.414392
56 | 0.284321, 0.043933, 0.416608
57 | 0.290763, 0.045644, 0.418637
58 | 0.297178, 0.047470, 0.420491
59 | 0.303568, 0.049396, 0.422182
60 | 0.309935, 0.051407, 0.423721
61 | 0.316282, 0.053490, 0.425116
62 | 0.322610, 0.055634, 0.426377
63 | 0.328921, 0.057827, 0.427511
64 | 0.335217, 0.060060, 0.428524
65 | 0.341500, 0.062325, 0.429425
66 | 0.347771, 0.064616, 0.430217
67 | 0.354032, 0.066925, 0.430906
68 | 0.360284, 0.069247, 0.431497
69 | 0.366529, 0.071579, 0.431994
70 | 0.372768, 0.073915, 0.432400
71 | 0.379001, 0.076253, 0.432719
72 | 0.385228, 0.078591, 0.432955
73 | 0.391453, 0.080927, 0.433109
74 | 0.397674, 0.083257, 0.433183
75 | 0.403894, 0.085580, 0.433179
76 | 0.410113, 0.087896, 0.433098
77 | 0.416331, 0.090203, 0.432943
78 | 0.422549, 0.092501, 0.432714
79 | 0.428768, 0.094790, 0.432412
80 | 0.434987, 0.097069, 0.432039
81 | 0.441207, 0.099338, 0.431594
82 | 0.447428, 0.101597, 0.431080
83 | 0.453651, 0.103848, 0.430498
84 | 0.459875, 0.106089, 0.429846
85 | 0.466100, 0.108322, 0.429125
86 | 0.472328, 0.110547, 0.428334
87 | 0.478558, 0.112764, 0.427475
88 | 0.484789, 0.114974, 0.426548
89 | 0.491022, 0.117179, 0.425552
90 | 0.497257, 0.119379, 0.424488
91 | 0.503493, 0.121575, 0.423356
92 | 0.509730, 0.123769, 0.422156
93 | 0.515967, 0.125960, 0.420887
94 | 0.522206, 0.128150, 0.419549
95 | 0.528444, 0.130341, 0.418142
96 | 0.534683, 0.132534, 0.416667
97 | 0.540920, 0.134729, 0.415123
98 | 0.547157, 0.136929, 0.413511
99 | 0.553392, 0.139134, 0.411829
100 | 0.559624, 0.141346, 0.410078
101 | 0.565854, 0.143567, 0.408258
102 | 0.572081, 0.145797, 0.406369
103 | 0.578304, 0.148039, 0.404411
104 | 0.584521, 0.150294, 0.402385
105 | 0.590734, 0.152563, 0.400290
106 | 0.596940, 0.154848, 0.398125
107 | 0.603139, 0.157151, 0.395891
108 | 0.609330, 0.159474, 0.393589
109 | 0.615513, 0.161817, 0.391219
110 | 0.621685, 0.164184, 0.388781
111 | 0.627847, 0.166575, 0.386276
112 | 0.633998, 0.168992, 0.383704
113 | 0.640135, 0.171438, 0.381065
114 | 0.646260, 0.173914, 0.378359
115 | 0.652369, 0.176421, 0.375586
116 | 0.658463, 0.178962, 0.372748
117 | 0.664540, 0.181539, 0.369846
118 | 0.670599, 0.184153, 0.366879
119 | 0.676638, 0.186807, 0.363849
120 | 0.682656, 0.189501, 0.360757
121 | 0.688653, 0.192239, 0.357603
122 | 0.694627, 0.195021, 0.354388
123 | 0.700576, 0.197851, 0.351113
124 | 0.706500, 0.200728, 0.347777
125 | 0.712396, 0.203656, 0.344383
126 | 0.718264, 0.206636, 0.340931
127 | 0.724103, 0.209670, 0.337424
128 | 0.729909, 0.212759, 0.333861
129 | 0.735683, 0.215906, 0.330245
130 | 0.741423, 0.219112, 0.326576
131 | 0.747127, 0.222378, 0.322856
132 | 0.752794, 0.225706, 0.319085
133 | 0.758422, 0.229097, 0.315266
134 | 0.764010, 0.232554, 0.311399
135 | 0.769556, 0.236077, 0.307485
136 | 0.775059, 0.239667, 0.303526
137 | 0.780517, 0.243327, 0.299523
138 | 0.785929, 0.247056, 0.295477
139 | 0.791293, 0.250856, 0.291390
140 | 0.796607, 0.254728, 0.287264
141 | 0.801871, 0.258674, 0.283099
142 | 0.807082, 0.262692, 0.278898
143 | 0.812239, 0.266786, 0.274661
144 | 0.817341, 0.270954, 0.270390
145 | 0.822386, 0.275197, 0.266085
146 | 0.827372, 0.279517, 0.261750
147 | 0.832299, 0.283913, 0.257383
148 | 0.837165, 0.288385, 0.252988
149 | 0.841969, 0.292933, 0.248564
150 | 0.846709, 0.297559, 0.244113
151 | 0.851384, 0.302260, 0.239636
152 | 0.855992, 0.307038, 0.235133
153 | 0.860533, 0.311892, 0.230606
154 | 0.865006, 0.316822, 0.226055
155 | 0.869409, 0.321827, 0.221482
156 | 0.873741, 0.326906, 0.216886
157 | 0.878001, 0.332060, 0.212268
158 | 0.882188, 0.337287, 0.207628
159 | 0.886302, 0.342586, 0.202968
160 | 0.890341, 0.347957, 0.198286
161 | 0.894305, 0.353399, 0.193584
162 | 0.898192, 0.358911, 0.188860
163 | 0.902003, 0.364492, 0.184116
164 | 0.905735, 0.370140, 0.179350
165 | 0.909390, 0.375856, 0.174563
166 | 0.912966, 0.381636, 0.169755
167 | 0.916462, 0.387481, 0.164924
168 | 0.919879, 0.393389, 0.160070
169 | 0.923215, 0.399359, 0.155193
170 | 0.926470, 0.405389, 0.150292
171 | 0.929644, 0.411479, 0.145367
172 | 0.932737, 0.417627, 0.140417
173 | 0.935747, 0.423831, 0.135440
174 | 0.938675, 0.430091, 0.130438
175 | 0.941521, 0.436405, 0.125409
176 | 0.944285, 0.442772, 0.120354
177 | 0.946965, 0.449191, 0.115272
178 | 0.949562, 0.455660, 0.110164
179 | 0.952075, 0.462178, 0.105031
180 | 0.954506, 0.468744, 0.099874
181 | 0.956852, 0.475356, 0.094695
182 | 0.959114, 0.482014, 0.089499
183 | 0.961293, 0.488716, 0.084289
184 | 0.963387, 0.495462, 0.079073
185 | 0.965397, 0.502249, 0.073859
186 | 0.967322, 0.509078, 0.068659
187 | 0.969163, 0.515946, 0.063488
188 | 0.970919, 0.522853, 0.058367
189 | 0.972590, 0.529798, 0.053324
190 | 0.974176, 0.536780, 0.048392
191 | 0.975677, 0.543798, 0.043618
192 | 0.977092, 0.550850, 0.039050
193 | 0.978422, 0.557937, 0.034931
194 | 0.979666, 0.565057, 0.031409
195 | 0.980824, 0.572209, 0.028508
196 | 0.981895, 0.579392, 0.026250
197 | 0.982881, 0.586606, 0.024661
198 | 0.983779, 0.593849, 0.023770
199 | 0.984591, 0.601122, 0.023606
200 | 0.985315, 0.608422, 0.024202
201 | 0.985952, 0.615750, 0.025592
202 | 0.986502, 0.623105, 0.027814
203 | 0.986964, 0.630485, 0.030908
204 | 0.987337, 0.637890, 0.034916
205 | 0.987622, 0.645320, 0.039886
206 | 0.987819, 0.652773, 0.045581
207 | 0.987926, 0.660250, 0.051750
208 | 0.987945, 0.667748, 0.058329
209 | 0.987874, 0.675267, 0.065257
210 | 0.987714, 0.682807, 0.072489
211 | 0.987464, 0.690366, 0.079990
212 | 0.987124, 0.697944, 0.087731
213 | 0.986694, 0.705540, 0.095694
214 | 0.986175, 0.713153, 0.103863
215 | 0.985566, 0.720782, 0.112229
216 | 0.984865, 0.728427, 0.120785
217 | 0.984075, 0.736087, 0.129527
218 | 0.983196, 0.743758, 0.138453
219 | 0.982228, 0.751442, 0.147565
220 | 0.981173, 0.759135, 0.156863
221 | 0.980032, 0.766837, 0.166353
222 | 0.978806, 0.774545, 0.176037
223 | 0.977497, 0.782258, 0.185923
224 | 0.976108, 0.789974, 0.196018
225 | 0.974638, 0.797692, 0.206332
226 | 0.973088, 0.805409, 0.216877
227 | 0.971468, 0.813122, 0.227658
228 | 0.969783, 0.820825, 0.238686
229 | 0.968041, 0.828515, 0.249972
230 | 0.966243, 0.836191, 0.261534
231 | 0.964394, 0.843848, 0.273391
232 | 0.962517, 0.851476, 0.285546
233 | 0.960626, 0.859069, 0.298010
234 | 0.958720, 0.866624, 0.310820
235 | 0.956834, 0.874129, 0.323974
236 | 0.954997, 0.881569, 0.337475
237 | 0.953215, 0.888942, 0.351369
238 | 0.951546, 0.896226, 0.365627
239 | 0.950018, 0.903409, 0.380271
240 | 0.948683, 0.910473, 0.395289
241 | 0.947594, 0.917399, 0.410665
242 | 0.946809, 0.924168, 0.426373
243 | 0.946392, 0.930761, 0.442367
244 | 0.946403, 0.937159, 0.458592
245 | 0.946903, 0.943348, 0.474970
246 | 0.947937, 0.949318, 0.491426
247 | 0.949545, 0.955063, 0.507860
248 | 0.951740, 0.960587, 0.524203
249 | 0.954529, 0.965896, 0.540361
250 | 0.957896, 0.971003, 0.556275
251 | 0.961812, 0.975924, 0.571925
252 | 0.966249, 0.980678, 0.587206
253 | 0.971162, 0.985282, 0.602154
254 | 0.976511, 0.989753, 0.616760
255 | 0.982257, 0.994109, 0.631017
256 | 0.988362, 0.998364, 0.644924
257 |
--------------------------------------------------------------------------------
/util/magma.csv:
--------------------------------------------------------------------------------
1 | 0.001462, 0.000466, 0.013866
2 | 0.002258, 0.001295, 0.018331
3 | 0.003279, 0.002305, 0.023708
4 | 0.004512, 0.003490, 0.029965
5 | 0.005950, 0.004843, 0.037130
6 | 0.007588, 0.006356, 0.044973
7 | 0.009426, 0.008022, 0.052844
8 | 0.011465, 0.009828, 0.060750
9 | 0.013708, 0.011771, 0.068667
10 | 0.016156, 0.013840, 0.076603
11 | 0.018815, 0.016026, 0.084584
12 | 0.021692, 0.018320, 0.092610
13 | 0.024792, 0.020715, 0.100676
14 | 0.028123, 0.023201, 0.108787
15 | 0.031696, 0.025765, 0.116965
16 | 0.035520, 0.028397, 0.125209
17 | 0.039608, 0.031090, 0.133515
18 | 0.043830, 0.033830, 0.141886
19 | 0.048062, 0.036607, 0.150327
20 | 0.052320, 0.039407, 0.158841
21 | 0.056615, 0.042160, 0.167446
22 | 0.060949, 0.044794, 0.176129
23 | 0.065330, 0.047318, 0.184892
24 | 0.069764, 0.049726, 0.193735
25 | 0.074257, 0.052017, 0.202660
26 | 0.078815, 0.054184, 0.211667
27 | 0.083446, 0.056225, 0.220755
28 | 0.088155, 0.058133, 0.229922
29 | 0.092949, 0.059904, 0.239164
30 | 0.097833, 0.061531, 0.248477
31 | 0.102815, 0.063010, 0.257854
32 | 0.107899, 0.064335, 0.267289
33 | 0.113094, 0.065492, 0.276784
34 | 0.118405, 0.066479, 0.286321
35 | 0.123833, 0.067295, 0.295879
36 | 0.129380, 0.067935, 0.305443
37 | 0.135053, 0.068391, 0.315000
38 | 0.140858, 0.068654, 0.324538
39 | 0.146785, 0.068738, 0.334011
40 | 0.152839, 0.068637, 0.343404
41 | 0.159018, 0.068354, 0.352688
42 | 0.165308, 0.067911, 0.361816
43 | 0.171713, 0.067305, 0.370771
44 | 0.178212, 0.066576, 0.379497
45 | 0.184801, 0.065732, 0.387973
46 | 0.191460, 0.064818, 0.396152
47 | 0.198177, 0.063862, 0.404009
48 | 0.204935, 0.062907, 0.411514
49 | 0.211718, 0.061992, 0.418647
50 | 0.218512, 0.061158, 0.425392
51 | 0.225302, 0.060445, 0.431742
52 | 0.232077, 0.059889, 0.437695
53 | 0.238826, 0.059517, 0.443256
54 | 0.245543, 0.059352, 0.448436
55 | 0.252220, 0.059415, 0.453248
56 | 0.258857, 0.059706, 0.457710
57 | 0.265447, 0.060237, 0.461840
58 | 0.271994, 0.060994, 0.465660
59 | 0.278493, 0.061978, 0.469190
60 | 0.284951, 0.063168, 0.472451
61 | 0.291366, 0.064553, 0.475462
62 | 0.297740, 0.066117, 0.478243
63 | 0.304081, 0.067835, 0.480812
64 | 0.310382, 0.069702, 0.483186
65 | 0.316654, 0.071690, 0.485380
66 | 0.322899, 0.073782, 0.487408
67 | 0.329114, 0.075972, 0.489287
68 | 0.335308, 0.078236, 0.491024
69 | 0.341482, 0.080564, 0.492631
70 | 0.347636, 0.082946, 0.494121
71 | 0.353773, 0.085373, 0.495501
72 | 0.359898, 0.087831, 0.496778
73 | 0.366012, 0.090314, 0.497960
74 | 0.372116, 0.092816, 0.499053
75 | 0.378211, 0.095332, 0.500067
76 | 0.384299, 0.097855, 0.501002
77 | 0.390384, 0.100379, 0.501864
78 | 0.396467, 0.102902, 0.502658
79 | 0.402548, 0.105420, 0.503386
80 | 0.408629, 0.107930, 0.504052
81 | 0.414709, 0.110431, 0.504662
82 | 0.420791, 0.112920, 0.505215
83 | 0.426877, 0.115395, 0.505714
84 | 0.432967, 0.117855, 0.506160
85 | 0.439062, 0.120298, 0.506555
86 | 0.445163, 0.122724, 0.506901
87 | 0.451271, 0.125132, 0.507198
88 | 0.457386, 0.127522, 0.507448
89 | 0.463508, 0.129893, 0.507652
90 | 0.469640, 0.132245, 0.507809
91 | 0.475780, 0.134577, 0.507921
92 | 0.481929, 0.136891, 0.507989
93 | 0.488088, 0.139186, 0.508011
94 | 0.494258, 0.141462, 0.507988
95 | 0.500438, 0.143719, 0.507920
96 | 0.506629, 0.145958, 0.507806
97 | 0.512831, 0.148179, 0.507648
98 | 0.519045, 0.150383, 0.507443
99 | 0.525270, 0.152569, 0.507192
100 | 0.531507, 0.154739, 0.506895
101 | 0.537755, 0.156894, 0.506551
102 | 0.544015, 0.159033, 0.506159
103 | 0.550287, 0.161158, 0.505719
104 | 0.556571, 0.163269, 0.505230
105 | 0.562866, 0.165368, 0.504692
106 | 0.569172, 0.167454, 0.504105
107 | 0.575490, 0.169530, 0.503466
108 | 0.581819, 0.171596, 0.502777
109 | 0.588158, 0.173652, 0.502035
110 | 0.594508, 0.175701, 0.501241
111 | 0.600868, 0.177743, 0.500394
112 | 0.607238, 0.179779, 0.499492
113 | 0.613617, 0.181811, 0.498536
114 | 0.620005, 0.183840, 0.497524
115 | 0.626401, 0.185867, 0.496456
116 | 0.632805, 0.187893, 0.495332
117 | 0.639216, 0.189921, 0.494150
118 | 0.645633, 0.191952, 0.492910
119 | 0.652056, 0.193986, 0.491611
120 | 0.658483, 0.196027, 0.490253
121 | 0.664915, 0.198075, 0.488836
122 | 0.671349, 0.200133, 0.487358
123 | 0.677786, 0.202203, 0.485819
124 | 0.684224, 0.204286, 0.484219
125 | 0.690661, 0.206384, 0.482558
126 | 0.697098, 0.208501, 0.480835
127 | 0.703532, 0.210638, 0.479049
128 | 0.709962, 0.212797, 0.477201
129 | 0.716387, 0.214982, 0.475290
130 | 0.722805, 0.217194, 0.473316
131 | 0.729216, 0.219437, 0.471279
132 | 0.735616, 0.221713, 0.469180
133 | 0.742004, 0.224025, 0.467018
134 | 0.748378, 0.226377, 0.464794
135 | 0.754737, 0.228772, 0.462509
136 | 0.761077, 0.231214, 0.460162
137 | 0.767398, 0.233705, 0.457755
138 | 0.773695, 0.236249, 0.455289
139 | 0.779968, 0.238851, 0.452765
140 | 0.786212, 0.241514, 0.450184
141 | 0.792427, 0.244242, 0.447543
142 | 0.798608, 0.247040, 0.444848
143 | 0.804752, 0.249911, 0.442102
144 | 0.810855, 0.252861, 0.439305
145 | 0.816914, 0.255895, 0.436461
146 | 0.822926, 0.259016, 0.433573
147 | 0.828886, 0.262229, 0.430644
148 | 0.834791, 0.265540, 0.427671
149 | 0.840636, 0.268953, 0.424666
150 | 0.846416, 0.272473, 0.421631
151 | 0.852126, 0.276106, 0.418573
152 | 0.857763, 0.279857, 0.415496
153 | 0.863320, 0.283729, 0.412403
154 | 0.868793, 0.287728, 0.409303
155 | 0.874176, 0.291859, 0.406205
156 | 0.879464, 0.296125, 0.403118
157 | 0.884651, 0.300530, 0.400047
158 | 0.889731, 0.305079, 0.397002
159 | 0.894700, 0.309773, 0.393995
160 | 0.899552, 0.314616, 0.391037
161 | 0.904281, 0.319610, 0.388137
162 | 0.908884, 0.324755, 0.385308
163 | 0.913354, 0.330052, 0.382563
164 | 0.917689, 0.335500, 0.379915
165 | 0.921884, 0.341098, 0.377376
166 | 0.925937, 0.346844, 0.374959
167 | 0.929845, 0.352734, 0.372677
168 | 0.933606, 0.358764, 0.370541
169 | 0.937221, 0.364929, 0.368567
170 | 0.940687, 0.371224, 0.366762
171 | 0.944006, 0.377643, 0.365136
172 | 0.947180, 0.384178, 0.363701
173 | 0.950210, 0.390820, 0.362468
174 | 0.953099, 0.397563, 0.361438
175 | 0.955849, 0.404400, 0.360619
176 | 0.958464, 0.411324, 0.360014
177 | 0.960949, 0.418323, 0.359630
178 | 0.963310, 0.425390, 0.359469
179 | 0.965549, 0.432519, 0.359529
180 | 0.967671, 0.439703, 0.359810
181 | 0.969680, 0.446936, 0.360311
182 | 0.971582, 0.454210, 0.361030
183 | 0.973381, 0.461520, 0.361965
184 | 0.975082, 0.468861, 0.363111
185 | 0.976690, 0.476226, 0.364466
186 | 0.978210, 0.483612, 0.366025
187 | 0.979645, 0.491014, 0.367783
188 | 0.981000, 0.498428, 0.369734
189 | 0.982279, 0.505851, 0.371874
190 | 0.983485, 0.513280, 0.374198
191 | 0.984622, 0.520713, 0.376698
192 | 0.985693, 0.528148, 0.379371
193 | 0.986700, 0.535582, 0.382210
194 | 0.987646, 0.543015, 0.385210
195 | 0.988533, 0.550446, 0.388365
196 | 0.989363, 0.557873, 0.391671
197 | 0.990138, 0.565296, 0.395122
198 | 0.990871, 0.572706, 0.398714
199 | 0.991558, 0.580107, 0.402441
200 | 0.992196, 0.587502, 0.406299
201 | 0.992785, 0.594891, 0.410283
202 | 0.993326, 0.602275, 0.414390
203 | 0.993834, 0.609644, 0.418613
204 | 0.994309, 0.616999, 0.422950
205 | 0.994738, 0.624350, 0.427397
206 | 0.995122, 0.631696, 0.431951
207 | 0.995480, 0.639027, 0.436607
208 | 0.995810, 0.646344, 0.441361
209 | 0.996096, 0.653659, 0.446213
210 | 0.996341, 0.660969, 0.451160
211 | 0.996580, 0.668256, 0.456192
212 | 0.996775, 0.675541, 0.461314
213 | 0.996925, 0.682828, 0.466526
214 | 0.997077, 0.690088, 0.471811
215 | 0.997186, 0.697349, 0.477182
216 | 0.997254, 0.704611, 0.482635
217 | 0.997325, 0.711848, 0.488154
218 | 0.997351, 0.719089, 0.493755
219 | 0.997351, 0.726324, 0.499428
220 | 0.997341, 0.733545, 0.505167
221 | 0.997285, 0.740772, 0.510983
222 | 0.997228, 0.747981, 0.516859
223 | 0.997138, 0.755190, 0.522806
224 | 0.997019, 0.762398, 0.528821
225 | 0.996898, 0.769591, 0.534892
226 | 0.996727, 0.776795, 0.541039
227 | 0.996571, 0.783977, 0.547233
228 | 0.996369, 0.791167, 0.553499
229 | 0.996162, 0.798348, 0.559820
230 | 0.995932, 0.805527, 0.566202
231 | 0.995680, 0.812706, 0.572645
232 | 0.995424, 0.819875, 0.579140
233 | 0.995131, 0.827052, 0.585701
234 | 0.994851, 0.834213, 0.592307
235 | 0.994524, 0.841387, 0.598983
236 | 0.994222, 0.848540, 0.605696
237 | 0.993866, 0.855711, 0.612482
238 | 0.993545, 0.862859, 0.619299
239 | 0.993170, 0.870024, 0.626189
240 | 0.992831, 0.877168, 0.633109
241 | 0.992440, 0.884330, 0.640099
242 | 0.992089, 0.891470, 0.647116
243 | 0.991688, 0.898627, 0.654202
244 | 0.991332, 0.905763, 0.661309
245 | 0.990930, 0.912915, 0.668481
246 | 0.990570, 0.920049, 0.675675
247 | 0.990175, 0.927196, 0.682926
248 | 0.989815, 0.934329, 0.690198
249 | 0.989434, 0.941470, 0.697519
250 | 0.989077, 0.948604, 0.704863
251 | 0.988717, 0.955742, 0.712242
252 | 0.988367, 0.962878, 0.719649
253 | 0.988033, 0.970012, 0.727077
254 | 0.987691, 0.977154, 0.734536
255 | 0.987387, 0.984288, 0.742002
256 | 0.987053, 0.991438, 0.749504
257 |
--------------------------------------------------------------------------------
/util/plasma.csv:
--------------------------------------------------------------------------------
1 | 0.050383, 0.029803, 0.527975
2 | 0.063536, 0.028426, 0.533124
3 | 0.075353, 0.027206, 0.538007
4 | 0.086222, 0.026125, 0.542658
5 | 0.096379, 0.025165, 0.547103
6 | 0.105980, 0.024309, 0.551368
7 | 0.115124, 0.023556, 0.555468
8 | 0.123903, 0.022878, 0.559423
9 | 0.132381, 0.022258, 0.563250
10 | 0.140603, 0.021687, 0.566959
11 | 0.148607, 0.021154, 0.570562
12 | 0.156421, 0.020651, 0.574065
13 | 0.164070, 0.020171, 0.577478
14 | 0.171574, 0.019706, 0.580806
15 | 0.178950, 0.019252, 0.584054
16 | 0.186213, 0.018803, 0.587228
17 | 0.193374, 0.018354, 0.590330
18 | 0.200445, 0.017902, 0.593364
19 | 0.207435, 0.017442, 0.596333
20 | 0.214350, 0.016973, 0.599239
21 | 0.221197, 0.016497, 0.602083
22 | 0.227983, 0.016007, 0.604867
23 | 0.234715, 0.015502, 0.607592
24 | 0.241396, 0.014979, 0.610259
25 | 0.248032, 0.014439, 0.612868
26 | 0.254627, 0.013882, 0.615419
27 | 0.261183, 0.013308, 0.617911
28 | 0.267703, 0.012716, 0.620346
29 | 0.274191, 0.012109, 0.622722
30 | 0.280648, 0.011488, 0.625038
31 | 0.287076, 0.010855, 0.627295
32 | 0.293478, 0.010213, 0.629490
33 | 0.299855, 0.009561, 0.631624
34 | 0.306210, 0.008902, 0.633694
35 | 0.312543, 0.008239, 0.635700
36 | 0.318856, 0.007576, 0.637640
37 | 0.325150, 0.006915, 0.639512
38 | 0.331426, 0.006261, 0.641316
39 | 0.337683, 0.005618, 0.643049
40 | 0.343925, 0.004991, 0.644710
41 | 0.350150, 0.004382, 0.646298
42 | 0.356359, 0.003798, 0.647810
43 | 0.362553, 0.003243, 0.649245
44 | 0.368733, 0.002724, 0.650601
45 | 0.374897, 0.002245, 0.651876
46 | 0.381047, 0.001814, 0.653068
47 | 0.387183, 0.001434, 0.654177
48 | 0.393304, 0.001114, 0.655199
49 | 0.399411, 0.000859, 0.656133
50 | 0.405503, 0.000678, 0.656977
51 | 0.411580, 0.000577, 0.657730
52 | 0.417642, 0.000564, 0.658390
53 | 0.423689, 0.000646, 0.658956
54 | 0.429719, 0.000831, 0.659425
55 | 0.435734, 0.001127, 0.659797
56 | 0.441732, 0.001540, 0.660069
57 | 0.447714, 0.002080, 0.660240
58 | 0.453677, 0.002755, 0.660310
59 | 0.459623, 0.003574, 0.660277
60 | 0.465550, 0.004545, 0.660139
61 | 0.471457, 0.005678, 0.659897
62 | 0.477344, 0.006980, 0.659549
63 | 0.483210, 0.008460, 0.659095
64 | 0.489055, 0.010127, 0.658534
65 | 0.494877, 0.011990, 0.657865
66 | 0.500678, 0.014055, 0.657088
67 | 0.506454, 0.016333, 0.656202
68 | 0.512206, 0.018833, 0.655209
69 | 0.517933, 0.021563, 0.654109
70 | 0.523633, 0.024532, 0.652901
71 | 0.529306, 0.027747, 0.651586
72 | 0.534952, 0.031217, 0.650165
73 | 0.540570, 0.034950, 0.648640
74 | 0.546157, 0.038954, 0.647010
75 | 0.551715, 0.043136, 0.645277
76 | 0.557243, 0.047331, 0.643443
77 | 0.562738, 0.051545, 0.641509
78 | 0.568201, 0.055778, 0.639477
79 | 0.573632, 0.060028, 0.637349
80 | 0.579029, 0.064296, 0.635126
81 | 0.584391, 0.068579, 0.632812
82 | 0.589719, 0.072878, 0.630408
83 | 0.595011, 0.077190, 0.627917
84 | 0.600266, 0.081516, 0.625342
85 | 0.605485, 0.085854, 0.622686
86 | 0.610667, 0.090204, 0.619951
87 | 0.615812, 0.094564, 0.617140
88 | 0.620919, 0.098934, 0.614257
89 | 0.625987, 0.103312, 0.611305
90 | 0.631017, 0.107699, 0.608287
91 | 0.636008, 0.112092, 0.605205
92 | 0.640959, 0.116492, 0.602065
93 | 0.645872, 0.120898, 0.598867
94 | 0.650746, 0.125309, 0.595617
95 | 0.655580, 0.129725, 0.592317
96 | 0.660374, 0.134144, 0.588971
97 | 0.665129, 0.138566, 0.585582
98 | 0.669845, 0.142992, 0.582154
99 | 0.674522, 0.147419, 0.578688
100 | 0.679160, 0.151848, 0.575189
101 | 0.683758, 0.156278, 0.571660
102 | 0.688318, 0.160709, 0.568103
103 | 0.692840, 0.165141, 0.564522
104 | 0.697324, 0.169573, 0.560919
105 | 0.701769, 0.174005, 0.557296
106 | 0.706178, 0.178437, 0.553657
107 | 0.710549, 0.182868, 0.550004
108 | 0.714883, 0.187299, 0.546338
109 | 0.719181, 0.191729, 0.542663
110 | 0.723444, 0.196158, 0.538981
111 | 0.727670, 0.200586, 0.535293
112 | 0.731862, 0.205013, 0.531601
113 | 0.736019, 0.209439, 0.527908
114 | 0.740143, 0.213864, 0.524216
115 | 0.744232, 0.218288, 0.520524
116 | 0.748289, 0.222711, 0.516834
117 | 0.752312, 0.227133, 0.513149
118 | 0.756304, 0.231555, 0.509468
119 | 0.760264, 0.235976, 0.505794
120 | 0.764193, 0.240396, 0.502126
121 | 0.768090, 0.244817, 0.498465
122 | 0.771958, 0.249237, 0.494813
123 | 0.775796, 0.253658, 0.491171
124 | 0.779604, 0.258078, 0.487539
125 | 0.783383, 0.262500, 0.483918
126 | 0.787133, 0.266922, 0.480307
127 | 0.790855, 0.271345, 0.476706
128 | 0.794549, 0.275770, 0.473117
129 | 0.798216, 0.280197, 0.469538
130 | 0.801855, 0.284626, 0.465971
131 | 0.805467, 0.289057, 0.462415
132 | 0.809052, 0.293491, 0.458870
133 | 0.812612, 0.297928, 0.455338
134 | 0.816144, 0.302368, 0.451816
135 | 0.819651, 0.306812, 0.448306
136 | 0.823132, 0.311261, 0.444806
137 | 0.826588, 0.315714, 0.441316
138 | 0.830018, 0.320172, 0.437836
139 | 0.833422, 0.324635, 0.434366
140 | 0.836801, 0.329105, 0.430905
141 | 0.840155, 0.333580, 0.427455
142 | 0.843484, 0.338062, 0.424013
143 | 0.846788, 0.342551, 0.420579
144 | 0.850066, 0.347048, 0.417153
145 | 0.853319, 0.351553, 0.413734
146 | 0.856547, 0.356066, 0.410322
147 | 0.859750, 0.360588, 0.406917
148 | 0.862927, 0.365119, 0.403519
149 | 0.866078, 0.369660, 0.400126
150 | 0.869203, 0.374212, 0.396738
151 | 0.872303, 0.378774, 0.393355
152 | 0.875376, 0.383347, 0.389976
153 | 0.878423, 0.387932, 0.386600
154 | 0.881443, 0.392529, 0.383229
155 | 0.884436, 0.397139, 0.379860
156 | 0.887402, 0.401762, 0.376494
157 | 0.890340, 0.406398, 0.373130
158 | 0.893250, 0.411048, 0.369768
159 | 0.896131, 0.415712, 0.366407
160 | 0.898984, 0.420392, 0.363047
161 | 0.901807, 0.425087, 0.359688
162 | 0.904601, 0.429797, 0.356329
163 | 0.907365, 0.434524, 0.352970
164 | 0.910098, 0.439268, 0.349610
165 | 0.912800, 0.444029, 0.346251
166 | 0.915471, 0.448807, 0.342890
167 | 0.918109, 0.453603, 0.339529
168 | 0.920714, 0.458417, 0.336166
169 | 0.923287, 0.463251, 0.332801
170 | 0.925825, 0.468103, 0.329435
171 | 0.928329, 0.472975, 0.326067
172 | 0.930798, 0.477867, 0.322697
173 | 0.933232, 0.482780, 0.319325
174 | 0.935630, 0.487712, 0.315952
175 | 0.937990, 0.492667, 0.312575
176 | 0.940313, 0.497642, 0.309197
177 | 0.942598, 0.502639, 0.305816
178 | 0.944844, 0.507658, 0.302433
179 | 0.947051, 0.512699, 0.299049
180 | 0.949217, 0.517763, 0.295662
181 | 0.951344, 0.522850, 0.292275
182 | 0.953428, 0.527960, 0.288883
183 | 0.955470, 0.533093, 0.285490
184 | 0.957469, 0.538250, 0.282096
185 | 0.959424, 0.543431, 0.278701
186 | 0.961336, 0.548636, 0.275305
187 | 0.963203, 0.553865, 0.271909
188 | 0.965024, 0.559118, 0.268513
189 | 0.966798, 0.564396, 0.265118
190 | 0.968526, 0.569700, 0.261721
191 | 0.970205, 0.575028, 0.258325
192 | 0.971835, 0.580382, 0.254931
193 | 0.973416, 0.585761, 0.251540
194 | 0.974947, 0.591165, 0.248151
195 | 0.976428, 0.596595, 0.244767
196 | 0.977856, 0.602051, 0.241387
197 | 0.979233, 0.607532, 0.238013
198 | 0.980556, 0.613039, 0.234646
199 | 0.981826, 0.618572, 0.231287
200 | 0.983041, 0.624131, 0.227937
201 | 0.984199, 0.629718, 0.224595
202 | 0.985301, 0.635330, 0.221265
203 | 0.986345, 0.640969, 0.217948
204 | 0.987332, 0.646633, 0.214648
205 | 0.988260, 0.652325, 0.211364
206 | 0.989128, 0.658043, 0.208100
207 | 0.989935, 0.663787, 0.204859
208 | 0.990681, 0.669558, 0.201642
209 | 0.991365, 0.675355, 0.198453
210 | 0.991985, 0.681179, 0.195295
211 | 0.992541, 0.687030, 0.192170
212 | 0.993032, 0.692907, 0.189084
213 | 0.993456, 0.698810, 0.186041
214 | 0.993814, 0.704741, 0.183043
215 | 0.994103, 0.710698, 0.180097
216 | 0.994324, 0.716681, 0.177208
217 | 0.994474, 0.722691, 0.174381
218 | 0.994553, 0.728728, 0.171622
219 | 0.994561, 0.734791, 0.168938
220 | 0.994495, 0.740880, 0.166335
221 | 0.994355, 0.746995, 0.163821
222 | 0.994141, 0.753137, 0.161404
223 | 0.993851, 0.759304, 0.159092
224 | 0.993482, 0.765499, 0.156891
225 | 0.993033, 0.771720, 0.154808
226 | 0.992505, 0.777967, 0.152855
227 | 0.991897, 0.784239, 0.151042
228 | 0.991209, 0.790537, 0.149377
229 | 0.990439, 0.796859, 0.147870
230 | 0.989587, 0.803205, 0.146529
231 | 0.988648, 0.809579, 0.145357
232 | 0.987621, 0.815978, 0.144363
233 | 0.986509, 0.822401, 0.143557
234 | 0.985314, 0.828846, 0.142945
235 | 0.984031, 0.835315, 0.142528
236 | 0.982653, 0.841812, 0.142303
237 | 0.981190, 0.848329, 0.142279
238 | 0.979644, 0.854866, 0.142453
239 | 0.977995, 0.861432, 0.142808
240 | 0.976265, 0.868016, 0.143351
241 | 0.974443, 0.874622, 0.144061
242 | 0.972530, 0.881250, 0.144923
243 | 0.970533, 0.887896, 0.145919
244 | 0.968443, 0.894564, 0.147014
245 | 0.966271, 0.901249, 0.148180
246 | 0.964021, 0.907950, 0.149370
247 | 0.961681, 0.914672, 0.150520
248 | 0.959276, 0.921407, 0.151566
249 | 0.956808, 0.928152, 0.152409
250 | 0.954287, 0.934908, 0.152921
251 | 0.951726, 0.941671, 0.152925
252 | 0.949151, 0.948435, 0.152178
253 | 0.946602, 0.955190, 0.150328
254 | 0.944152, 0.961916, 0.146861
255 | 0.941896, 0.968590, 0.140956
256 | 0.940015, 0.975158, 0.131326
257 |
--------------------------------------------------------------------------------
/util/viridis.csv:
--------------------------------------------------------------------------------
1 | 0.267004, 0.004874, 0.329415
2 | 0.268510, 0.009605, 0.335427
3 | 0.269944, 0.014625, 0.341379
4 | 0.271305, 0.019942, 0.347269
5 | 0.272594, 0.025563, 0.353093
6 | 0.273809, 0.031497, 0.358853
7 | 0.274952, 0.037752, 0.364543
8 | 0.276022, 0.044167, 0.370164
9 | 0.277018, 0.050344, 0.375715
10 | 0.277941, 0.056324, 0.381191
11 | 0.278791, 0.062145, 0.386592
12 | 0.279566, 0.067836, 0.391917
13 | 0.280267, 0.073417, 0.397163
14 | 0.280894, 0.078907, 0.402329
15 | 0.281446, 0.084320, 0.407414
16 | 0.281924, 0.089666, 0.412415
17 | 0.282327, 0.094955, 0.417331
18 | 0.282656, 0.100196, 0.422160
19 | 0.282910, 0.105393, 0.426902
20 | 0.283091, 0.110553, 0.431554
21 | 0.283197, 0.115680, 0.436115
22 | 0.283229, 0.120777, 0.440584
23 | 0.283187, 0.125848, 0.444960
24 | 0.283072, 0.130895, 0.449241
25 | 0.282884, 0.135920, 0.453427
26 | 0.282623, 0.140926, 0.457517
27 | 0.282290, 0.145912, 0.461510
28 | 0.281887, 0.150881, 0.465405
29 | 0.281412, 0.155834, 0.469201
30 | 0.280868, 0.160771, 0.472899
31 | 0.280255, 0.165693, 0.476498
32 | 0.279574, 0.170599, 0.479997
33 | 0.278826, 0.175490, 0.483397
34 | 0.278012, 0.180367, 0.486697
35 | 0.277134, 0.185228, 0.489898
36 | 0.276194, 0.190074, 0.493001
37 | 0.275191, 0.194905, 0.496005
38 | 0.274128, 0.199721, 0.498911
39 | 0.273006, 0.204520, 0.501721
40 | 0.271828, 0.209303, 0.504434
41 | 0.270595, 0.214069, 0.507052
42 | 0.269308, 0.218818, 0.509577
43 | 0.267968, 0.223549, 0.512008
44 | 0.266580, 0.228262, 0.514349
45 | 0.265145, 0.232956, 0.516599
46 | 0.263663, 0.237631, 0.518762
47 | 0.262138, 0.242286, 0.520837
48 | 0.260571, 0.246922, 0.522828
49 | 0.258965, 0.251537, 0.524736
50 | 0.257322, 0.256130, 0.526563
51 | 0.255645, 0.260703, 0.528312
52 | 0.253935, 0.265254, 0.529983
53 | 0.252194, 0.269783, 0.531579
54 | 0.250425, 0.274290, 0.533103
55 | 0.248629, 0.278775, 0.534556
56 | 0.246811, 0.283237, 0.535941
57 | 0.244972, 0.287675, 0.537260
58 | 0.243113, 0.292092, 0.538516
59 | 0.241237, 0.296485, 0.539709
60 | 0.239346, 0.300855, 0.540844
61 | 0.237441, 0.305202, 0.541921
62 | 0.235526, 0.309527, 0.542944
63 | 0.233603, 0.313828, 0.543914
64 | 0.231674, 0.318106, 0.544834
65 | 0.229739, 0.322361, 0.545706
66 | 0.227802, 0.326594, 0.546532
67 | 0.225863, 0.330805, 0.547314
68 | 0.223925, 0.334994, 0.548053
69 | 0.221989, 0.339161, 0.548752
70 | 0.220057, 0.343307, 0.549413
71 | 0.218130, 0.347432, 0.550038
72 | 0.216210, 0.351535, 0.550627
73 | 0.214298, 0.355619, 0.551184
74 | 0.212395, 0.359683, 0.551710
75 | 0.210503, 0.363727, 0.552206
76 | 0.208623, 0.367752, 0.552675
77 | 0.206756, 0.371758, 0.553117
78 | 0.204903, 0.375746, 0.553533
79 | 0.203063, 0.379716, 0.553925
80 | 0.201239, 0.383670, 0.554294
81 | 0.199430, 0.387607, 0.554642
82 | 0.197636, 0.391528, 0.554969
83 | 0.195860, 0.395433, 0.555276
84 | 0.194100, 0.399323, 0.555565
85 | 0.192357, 0.403199, 0.555836
86 | 0.190631, 0.407061, 0.556089
87 | 0.188923, 0.410910, 0.556326
88 | 0.187231, 0.414746, 0.556547
89 | 0.185556, 0.418570, 0.556753
90 | 0.183898, 0.422383, 0.556944
91 | 0.182256, 0.426184, 0.557120
92 | 0.180629, 0.429975, 0.557282
93 | 0.179019, 0.433756, 0.557430
94 | 0.177423, 0.437527, 0.557565
95 | 0.175841, 0.441290, 0.557685
96 | 0.174274, 0.445044, 0.557792
97 | 0.172719, 0.448791, 0.557885
98 | 0.171176, 0.452530, 0.557965
99 | 0.169646, 0.456262, 0.558030
100 | 0.168126, 0.459988, 0.558082
101 | 0.166617, 0.463708, 0.558119
102 | 0.165117, 0.467423, 0.558141
103 | 0.163625, 0.471133, 0.558148
104 | 0.162142, 0.474838, 0.558140
105 | 0.160665, 0.478540, 0.558115
106 | 0.159194, 0.482237, 0.558073
107 | 0.157729, 0.485932, 0.558013
108 | 0.156270, 0.489624, 0.557936
109 | 0.154815, 0.493313, 0.557840
110 | 0.153364, 0.497000, 0.557724
111 | 0.151918, 0.500685, 0.557587
112 | 0.150476, 0.504369, 0.557430
113 | 0.149039, 0.508051, 0.557250
114 | 0.147607, 0.511733, 0.557049
115 | 0.146180, 0.515413, 0.556823
116 | 0.144759, 0.519093, 0.556572
117 | 0.143343, 0.522773, 0.556295
118 | 0.141935, 0.526453, 0.555991
119 | 0.140536, 0.530132, 0.555659
120 | 0.139147, 0.533812, 0.555298
121 | 0.137770, 0.537492, 0.554906
122 | 0.136408, 0.541173, 0.554483
123 | 0.135066, 0.544853, 0.554029
124 | 0.133743, 0.548535, 0.553541
125 | 0.132444, 0.552216, 0.553018
126 | 0.131172, 0.555899, 0.552459
127 | 0.129933, 0.559582, 0.551864
128 | 0.128729, 0.563265, 0.551229
129 | 0.127568, 0.566949, 0.550556
130 | 0.126453, 0.570633, 0.549841
131 | 0.125394, 0.574318, 0.549086
132 | 0.124395, 0.578002, 0.548287
133 | 0.123463, 0.581687, 0.547445
134 | 0.122606, 0.585371, 0.546557
135 | 0.121831, 0.589055, 0.545623
136 | 0.121148, 0.592739, 0.544641
137 | 0.120565, 0.596422, 0.543611
138 | 0.120092, 0.600104, 0.542530
139 | 0.119738, 0.603785, 0.541400
140 | 0.119512, 0.607464, 0.540218
141 | 0.119423, 0.611141, 0.538982
142 | 0.119483, 0.614817, 0.537692
143 | 0.119699, 0.618490, 0.536347
144 | 0.120081, 0.622161, 0.534946
145 | 0.120638, 0.625828, 0.533488
146 | 0.121380, 0.629492, 0.531973
147 | 0.122312, 0.633153, 0.530398
148 | 0.123444, 0.636809, 0.528763
149 | 0.124780, 0.640461, 0.527068
150 | 0.126326, 0.644107, 0.525311
151 | 0.128087, 0.647749, 0.523491
152 | 0.130067, 0.651384, 0.521608
153 | 0.132268, 0.655014, 0.519661
154 | 0.134692, 0.658636, 0.517649
155 | 0.137339, 0.662252, 0.515571
156 | 0.140210, 0.665859, 0.513427
157 | 0.143303, 0.669459, 0.511215
158 | 0.146616, 0.673050, 0.508936
159 | 0.150148, 0.676631, 0.506589
160 | 0.153894, 0.680203, 0.504172
161 | 0.157851, 0.683765, 0.501686
162 | 0.162016, 0.687316, 0.499129
163 | 0.166383, 0.690856, 0.496502
164 | 0.170948, 0.694384, 0.493803
165 | 0.175707, 0.697900, 0.491033
166 | 0.180653, 0.701402, 0.488189
167 | 0.185783, 0.704891, 0.485273
168 | 0.191090, 0.708366, 0.482284
169 | 0.196571, 0.711827, 0.479221
170 | 0.202219, 0.715272, 0.476084
171 | 0.208030, 0.718701, 0.472873
172 | 0.214000, 0.722114, 0.469588
173 | 0.220124, 0.725509, 0.466226
174 | 0.226397, 0.728888, 0.462789
175 | 0.232815, 0.732247, 0.459277
176 | 0.239374, 0.735588, 0.455688
177 | 0.246070, 0.738910, 0.452024
178 | 0.252899, 0.742211, 0.448284
179 | 0.259857, 0.745492, 0.444467
180 | 0.266941, 0.748751, 0.440573
181 | 0.274149, 0.751988, 0.436601
182 | 0.281477, 0.755203, 0.432552
183 | 0.288921, 0.758394, 0.428426
184 | 0.296479, 0.761561, 0.424223
185 | 0.304148, 0.764704, 0.419943
186 | 0.311925, 0.767822, 0.415586
187 | 0.319809, 0.770914, 0.411152
188 | 0.327796, 0.773980, 0.406640
189 | 0.335885, 0.777018, 0.402049
190 | 0.344074, 0.780029, 0.397381
191 | 0.352360, 0.783011, 0.392636
192 | 0.360741, 0.785964, 0.387814
193 | 0.369214, 0.788888, 0.382914
194 | 0.377779, 0.791781, 0.377939
195 | 0.386433, 0.794644, 0.372886
196 | 0.395174, 0.797475, 0.367757
197 | 0.404001, 0.800275, 0.362552
198 | 0.412913, 0.803041, 0.357269
199 | 0.421908, 0.805774, 0.351910
200 | 0.430983, 0.808473, 0.346476
201 | 0.440137, 0.811138, 0.340967
202 | 0.449368, 0.813768, 0.335384
203 | 0.458674, 0.816363, 0.329727
204 | 0.468053, 0.818921, 0.323998
205 | 0.477504, 0.821444, 0.318195
206 | 0.487026, 0.823929, 0.312321
207 | 0.496615, 0.826376, 0.306377
208 | 0.506271, 0.828786, 0.300362
209 | 0.515992, 0.831158, 0.294279
210 | 0.525776, 0.833491, 0.288127
211 | 0.535621, 0.835785, 0.281908
212 | 0.545524, 0.838039, 0.275626
213 | 0.555484, 0.840254, 0.269281
214 | 0.565498, 0.842430, 0.262877
215 | 0.575563, 0.844566, 0.256415
216 | 0.585678, 0.846661, 0.249897
217 | 0.595839, 0.848717, 0.243329
218 | 0.606045, 0.850733, 0.236712
219 | 0.616293, 0.852709, 0.230052
220 | 0.626579, 0.854645, 0.223353
221 | 0.636902, 0.856542, 0.216620
222 | 0.647257, 0.858400, 0.209861
223 | 0.657642, 0.860219, 0.203082
224 | 0.668054, 0.861999, 0.196293
225 | 0.678489, 0.863742, 0.189503
226 | 0.688944, 0.865448, 0.182725
227 | 0.699415, 0.867117, 0.175971
228 | 0.709898, 0.868751, 0.169257
229 | 0.720391, 0.870350, 0.162603
230 | 0.730889, 0.871916, 0.156029
231 | 0.741388, 0.873449, 0.149561
232 | 0.751884, 0.874951, 0.143228
233 | 0.762373, 0.876424, 0.137064
234 | 0.772852, 0.877868, 0.131109
235 | 0.783315, 0.879285, 0.125405
236 | 0.793760, 0.880678, 0.120005
237 | 0.804182, 0.882046, 0.114965
238 | 0.814576, 0.883393, 0.110347
239 | 0.824940, 0.884720, 0.106217
240 | 0.835270, 0.886029, 0.102646
241 | 0.845561, 0.887322, 0.099702
242 | 0.855810, 0.888601, 0.097452
243 | 0.866013, 0.889868, 0.095953
244 | 0.876168, 0.891125, 0.095250
245 | 0.886271, 0.892374, 0.095374
246 | 0.896320, 0.893616, 0.096335
247 | 0.906311, 0.894855, 0.098125
248 | 0.916242, 0.896091, 0.100717
249 | 0.926106, 0.897330, 0.104071
250 | 0.935904, 0.898570, 0.108131
251 | 0.945636, 0.899815, 0.112838
252 | 0.955300, 0.901065, 0.118128
253 | 0.964894, 0.902323, 0.123941
254 | 0.974417, 0.903590, 0.130215
255 | 0.983868, 0.904867, 0.136897
256 | 0.993248, 0.906157, 0.143936
257 |
--------------------------------------------------------------------------------