Gather more stats

Add a button to capture raw start and end callback time (just putting it
in a text buffer so it can be copied), which is useful for making plots.

Also a bunch of commented out code to provoke priority inversion or
sudden increases in load (which exercises the governor), again for the
purpose of probing performance and making plots.
master
Raph Levien 12 years ago
parent 4fcf6adf13
commit 68b44a4a89
  1. 21
      android/res/layout/piano2.xml
  2. BIN
      android/res/raw/drums.sf2
  3. 2
      android/res/values/strings.xml
  4. 14
      android/src/com/google/synthesizer/android/service/SynthesizerService.java
  5. 17
      android/src/com/google/synthesizer/android/stats/JitterStats.java
  6. 29
      android/src/com/google/synthesizer/android/ui/PianoActivity2.java
  7. 5
      cpp/src/android_glue.cc
  8. 4
      cpp/src/fm_core.cc

@ -18,19 +18,15 @@
android:gravity="center_horizontal" /> android:gravity="center_horizontal" />
<TextView <TextView
android:text="" android:text=""
android:id="@+id/emptyLabel"
android:gravity="center_horizontal" /> android:gravity="center_horizontal" />
<TextView <TextView
android:text="" android:text=""
android:id="@+id/emptyLabel"
android:gravity="center_horizontal" /> android:gravity="center_horizontal" />
<TextView <TextView
android:text="" android:text=""
android:id="@+id/emptyLabel"
android:gravity="center_horizontal" /> android:gravity="center_horizontal" />
<TextView <TextView
android:text="" android:text=""
android:id="@+id/emptyLabel"
android:gravity="center_horizontal" /> android:gravity="center_horizontal" />
</TableRow> </TableRow>
<TableRow> <TableRow>
@ -39,13 +35,13 @@
app:value="1.0" app:value="1.0"
app:min="0" app:min="0"
app:max="1" app:max="1"
android:layout_margin="2px" /> android:layout_margin="2dp" />
<com.google.synthesizer.android.widgets.knob.KnobView <com.google.synthesizer.android.widgets.knob.KnobView
android:id="@+id/resonanceKnob" android:id="@+id/resonanceKnob"
app:value="0.0" app:value="0.0"
app:min="0" app:min="0"
app:max="1" app:max="1"
android:layout_margin="2px" /> android:layout_margin="2dp" />
<LinearLayout <LinearLayout
android:orientation="vertical" android:orientation="vertical"
android:layout_span="4" > android:layout_span="4" >
@ -58,8 +54,19 @@
android:id="@+id/status" android:id="@+id/status"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_span="6"
/> />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/capture"
android:text="@string/capture"
/>
<TextView
android:id="@+id/stats"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:textIsSelectable="true"
/>
</LinearLayout> </LinearLayout>
</TableRow> </TableRow>
<TableRow> <TableRow>

Binary file not shown.

@ -77,4 +77,6 @@
<item>Amplification</item> <item>Amplification</item>
<item>Effects</item> <item>Effects</item>
</string-array> </string-array>
<string name="capture">Capture</string>
</resources> </resources>

@ -69,13 +69,13 @@ public class SynthesizerService extends Service {
// For now, cap the sample rate to reduce cpu requirements. // For now, cap the sample rate to reduce cpu requirements.
sampleRateInHz = Math.min(sampleRateInHz, 11025); sampleRateInHz = Math.min(sampleRateInHz, 11025);
SoundFontReader sampleLibrary = null; SoundFontReader sampleLibrary = null;
InputStream sampleLibraryFile = getResources().openRawResource(R.raw.drums); //InputStream sampleLibraryFile = getResources().openRawResource(R.raw.drums);
try { //try {
sampleLibrary = new SoundFontReader(sampleLibraryFile); // sampleLibrary = new SoundFontReader(sampleLibraryFile);
} catch (IOException e) { //} catch (IOException e) {
logger_.log(Level.SEVERE, "Unable to load sample library.", e); // logger_.log(Level.SEVERE, "Unable to load sample library.", e);
sampleLibrary = null; // sampleLibrary = null;
} //}
synthesizer_ = new MultiChannelSynthesizer(CHANNELS, FINGERS, sampleRateInHz, sampleLibrary); synthesizer_ = new MultiChannelSynthesizer(CHANNELS, FINGERS, sampleRateInHz, sampleLibrary);
// Load the presets from a file. // Load the presets from a file.

@ -35,10 +35,27 @@ public class JitterStats {
return "max cb = " + Double.toString(maxCbTime * 1000) + "ms"; return "max cb = " + Double.toString(maxCbTime * 1000) + "ms";
} }
public void setNominalCb(double nominalCb) {
nominalCbPeriod_ = nominalCb;
}
public String reportLong() {
StringBuilder sb = new StringBuilder();
double startTime = startTime_[bufIx_];
for (int i = 0; i < N_STATS; i++) {
double nominalStart = startTime + nominalCbPeriod_ * i;
double thisStart = startTime_[(bufIx_ + i) % N_STATS] - nominalStart;
double thisEnd = endTime_[(bufIx_ + i) % N_STATS] - nominalStart;
sb.append(thisStart + " " + thisEnd + "\n");
}
return sb.toString();
}
static final int N_STATS = 2000; static final int N_STATS = 2000;
double meanCbTime_; double meanCbTime_;
double startTime_[]; double startTime_[];
double endTime_[]; double endTime_[];
double nominalCbPeriod_;
int bufIx_ = 0; int bufIx_ = 0;
} }

@ -37,9 +37,11 @@ import android.os.Handler;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener; import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
@ -74,6 +76,8 @@ public class PianoActivity2 extends Activity {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
getJbMr1Params(params); getJbMr1Params(params);
} }
//params.sampleRate = 44100;
//params.bufferSize = 976;
androidGlue_ = new AndroidGlue(); androidGlue_ = new AndroidGlue();
androidGlue_.start(params.sampleRate, params.bufferSize); androidGlue_.start(params.sampleRate, params.bufferSize);
@ -121,6 +125,7 @@ public class PianoActivity2 extends Activity {
} }
jitterStats_ = new JitterStats(); jitterStats_ = new JitterStats();
jitterStats_.setNominalCb(params.bufferSize / (double)params.sampleRate);
statusHandler_ = new Handler(); statusHandler_ = new Handler();
statusRunnable_ = new Runnable() { statusRunnable_ = new Runnable() {
public void run() { public void run() {
@ -136,6 +141,30 @@ public class PianoActivity2 extends Activity {
} }
}; };
statusRunnable_.run(); statusRunnable_.run();
// Create burst of load -- test code to be removed. Ultimately we'll
// be able to get this kind of functionality by hooking up the sequencer
if (false) {
new Handler().postDelayed(new Runnable() {
public void run() {
int n = 110;
byte[] midi = new byte[n * 3];
for (int i = 0; i < n; i++) {
midi[i * 3] = (byte)0x90;
midi[i * 3 + 1] = (byte)(1 + i);
midi[i * 3 + 2] = 64;
}
androidGlue_.sendMidi(midi);
}
}, 10000);
}
Button captureButton = (Button) findViewById(R.id.capture);
captureButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
TextView stats = (TextView) findViewById(R.id.stats);
stats.setText(jitterStats_.reportLong());
}
});
} }
@Override @Override

@ -89,13 +89,16 @@ extern "C" void BqPlayerCallback(SLAndroidSimpleBufferQueueItf queueItf,
double start_time = ts_to_double(&tp); double start_time = ts_to_double(&tp);
int16_t *buf_ptr = buffer + buffer_size * cur_buffer; int16_t *buf_ptr = buffer + buffer_size * cur_buffer;
synth_unit->GetSamples(buffer_size, buf_ptr); synth_unit->GetSamples(buffer_size, buf_ptr);
char buf[64];
//uint8_t *mem = new uint8_t[1024];
//delete[] mem;
//sprintf(buf, "%.6f", start_time);
clock_gettime(CLOCK_MONOTONIC, &tp); clock_gettime(CLOCK_MONOTONIC, &tp);
double end_time = ts_to_double(&tp); double end_time = ts_to_double(&tp);
SLresult result = (*queueItf)->Enqueue(bq_player_buffer_queue, SLresult result = (*queueItf)->Enqueue(bq_player_buffer_queue,
buf_ptr, buffer_size * 2); buf_ptr, buffer_size * 2);
assert(SL_RESULT_SUCCESS == result); assert(SL_RESULT_SUCCESS == result);
cur_buffer = (cur_buffer + 1) % N_BUFFERS; cur_buffer = (cur_buffer + 1) % N_BUFFERS;
char buf[64];
size_t i = 0; size_t i = 0;
buf[i++] = 't'; buf[i++] = 't';
buf[i++] = 's'; buf[i++] = 's';

@ -18,10 +18,6 @@
#include <iostream> #include <iostream>
#endif #endif
#ifdef __ANDROID_API__
#include <cpu-features.h>
#endif
#include "synth.h" #include "synth.h"
#include "fm_op_kernel.h" #include "fm_op_kernel.h"
#include "fm_core.h" #include "fm_core.h"

Loading…
Cancel
Save