added spectrum view to present spectrogram

pull/6/head
Ahmet Inan 2015-01-15 00:32:39 +01:00
rodzic 8b3d4bc191
commit 1c3f90aef0
9 zmienionych plików z 72 dodań i 37 usunięć

Wyświetl plik

@ -30,6 +30,7 @@ public class Decoder {
private final MainActivity activity;
private final ImageView image;
private final SpectrumView spectrum;
private final SpectrumView spectrogram;
private final VUMeterView meter;
private final AudioRecord audio;
private final int audioSource = MediaRecorder.AudioSource.MIC;
@ -39,6 +40,7 @@ public class Decoder {
private final short[] audioBuffer;
private final int[] pixelBuffer;
private final int[] spectrumBuffer;
private final int[] spectrogramBuffer;
private final int[] currentMode;
private final int[] savedBuffer;
private final int[] savedWidth;
@ -49,6 +51,7 @@ public class Decoder {
private final Allocation rsDecoderAudioBuffer;
private final Allocation rsDecoderPixelBuffer;
private final Allocation rsDecoderSpectrumBuffer;
private final Allocation rsDecoderSpectrogramBuffer;
private final Allocation rsDecoderValueBuffer;
private final Allocation rsDecoderCurrentMode;
private final Allocation rsDecoderSavedBuffer;
@ -78,6 +81,7 @@ public class Decoder {
image.drawCanvas();
if(enableAnalyzer) {
spectrum.drawCanvas();
spectrogram.drawCanvas();
meter.drawCanvas();
}
}
@ -87,13 +91,15 @@ public class Decoder {
}
};
public Decoder(MainActivity activity, SpectrumView spectrum, ImageView image, VUMeterView meter) {
public Decoder(MainActivity activity, SpectrumView spectrum, SpectrumView spectrogram,ImageView image, VUMeterView meter) {
this.image = image;
this.spectrogram = spectrogram;
this.spectrum = spectrum;
this.meter = meter;
this.activity = activity;
pixelBuffer = new int[image.bitmap.getWidth() * image.bitmap.getHeight()];
spectrumBuffer = new int[spectrum.bitmap.getWidth() * spectrum.bitmap.getHeight()];
spectrogramBuffer = new int[spectrogram.bitmap.getWidth() * spectrogram.bitmap.getHeight()];
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
int bufferSizeInSamples = bufferSizeInBytes / 2;
@ -118,6 +124,7 @@ public class Decoder {
rsDecoderValueBuffer = Allocation.createSized(rs, Element.U8(rs), valueBufferLength, Allocation.USAGE_SCRIPT);
rsDecoderPixelBuffer = Allocation.createSized(rs, Element.I32(rs), pixelBuffer.length, Allocation.USAGE_SHARED | Allocation.USAGE_SCRIPT);
rsDecoderSpectrumBuffer = Allocation.createSized(rs, Element.I32(rs), spectrumBuffer.length, Allocation.USAGE_SHARED | Allocation.USAGE_SCRIPT);
rsDecoderSpectrogramBuffer = Allocation.createSized(rs, Element.I32(rs), spectrogramBuffer.length, Allocation.USAGE_SHARED | Allocation.USAGE_SCRIPT);
rsDecoderCurrentMode = Allocation.createSized(rs, Element.I32(rs), 1, Allocation.USAGE_SHARED | Allocation.USAGE_SCRIPT);
rsDecoderSavedWidth = Allocation.createSized(rs, Element.I32(rs), 1, Allocation.USAGE_SHARED | Allocation.USAGE_SCRIPT);
rsDecoderSavedHeight = Allocation.createSized(rs, Element.I32(rs), 1, Allocation.USAGE_SHARED | Allocation.USAGE_SCRIPT);
@ -128,6 +135,7 @@ public class Decoder {
rsDecoder.bind_value_buffer(rsDecoderValueBuffer);
rsDecoder.bind_pixel_buffer(rsDecoderPixelBuffer);
rsDecoder.bind_spectrum_buffer(rsDecoderSpectrumBuffer);
rsDecoder.bind_spectrogram_buffer(rsDecoderSpectrogramBuffer);
rsDecoder.bind_current_mode(rsDecoderCurrentMode);
rsDecoder.bind_saved_width(rsDecoderSavedWidth);
rsDecoder.bind_saved_height(rsDecoderSavedHeight);
@ -135,7 +143,8 @@ public class Decoder {
rsDecoder.bind_saved_buffer(rsDecoderSavedBuffer);
rsDecoder.invoke_initialize(sampleRate, valueBufferLength,
image.bitmap.getWidth(), image.bitmap.getHeight(),
spectrum.bitmap.getWidth(), spectrum.bitmap.getHeight());
spectrum.bitmap.getWidth(), spectrum.bitmap.getHeight(),
spectrogram.bitmap.getWidth(), spectrogram.bitmap.getHeight());
thread.start();
}
@ -261,6 +270,8 @@ public class Decoder {
if (enableAnalyzer) {
rsDecoderSpectrumBuffer.copyTo(spectrumBuffer);
spectrum.bitmap.setPixels(spectrumBuffer, 0, spectrum.bitmap.getWidth(), 0, 0, spectrum.bitmap.getWidth(), spectrum.bitmap.getHeight());
rsDecoderSpectrogramBuffer.copyTo(spectrogramBuffer);
spectrogram.bitmap.setPixels(spectrogramBuffer, 0, spectrogram.bitmap.getWidth(), 0, 0, spectrogram.bitmap.getWidth(), spectrogram.bitmap.getHeight());
}
}
}

Wyświetl plik

@ -123,6 +123,7 @@ public class MainActivity extends Activity {
changeLayoutOrientation(getResources().getConfiguration());
decoder = new Decoder(this,
(SpectrumView)findViewById(R.id.spectrum),
(SpectrumView)findViewById(R.id.spectrogram),
(ImageView)findViewById(R.id.image),
(VUMeterView)findViewById(R.id.meter)
);

Wyświetl plik

@ -37,7 +37,7 @@ public class SpectrumView extends SurfaceView implements SurfaceHolder.Callback
holder = getHolder();
holder.addCallback(this);
paint = new Paint(Paint.FILTER_BITMAP_FLAG);
bitmap = Bitmap.createBitmap(256, 32, Bitmap.Config.ARGB_8888);
bitmap = Bitmap.createBitmap(256, 64, Bitmap.Config.ARGB_8888);
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
@ -76,17 +76,12 @@ public class SpectrumView extends SurfaceView implements SurfaceHolder.Callback
}
void drawBitmap(Canvas canvas) {
float scale;
if (bitmap.getWidth() * canvasHeight < canvasWidth * bitmap.getHeight())
scale = (float)canvasHeight / bitmap.getHeight();
else
scale = (float)canvasWidth / bitmap.getWidth();
float px = (canvasWidth - scale * bitmap.getWidth()) / 2.0f;
float py = (canvasHeight - scale * bitmap.getHeight()) / 2.0f;
canvas.drawColor(Color.BLACK);
canvas.save();
canvas.scale(scale, scale, px, py);
canvas.drawBitmap(bitmap, px, py, paint);
float sx = (float)canvasWidth / bitmap.getWidth();
float sy = (float)canvasHeight / bitmap.getHeight();
canvas.scale(sx, sy, 0, 0);
canvas.drawBitmap(bitmap, 0, 0, paint);
canvas.restore();
}
}

Wyświetl plik

@ -4,10 +4,6 @@
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:keepScreenOn="true"
tools:context=".MainActivity"
android:orientation="vertical">
@ -24,22 +20,28 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="10"
android:weightSum="10">
android:layout_weight="10">
<xdsopl.robot36.SpectrumView
android:id="@+id/spectrum"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:contentDescription="@string/spectrum_view" />
android:contentDescription="@string/spectrum_view"
android:layout_weight="100" />
<xdsopl.robot36.SpectrumView
android:id="@+id/spectrogram"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/spectrogram_view"
android:layout_weight="100" />
<xdsopl.robot36.VUMeterView
android:id="@+id/meter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="9"
android:contentDescription="@string/meter_view" />
android:contentDescription="@string/meter_view"
android:layout_weight="190" />
</LinearLayout>
</LinearLayout>

Wyświetl plik

@ -20,6 +20,7 @@
<string name="action_toggle_scaling">Toggle Scaling</string>
<string name="decoder_view">Decoder View</string>
<string name="spectrum_view">Spectrum View</string>
<string name="spectrogram_view">Spectrogram View</string>
<string name="meter_view">VU Meter View</string>
</resources>

Wyświetl plik

@ -21,6 +21,7 @@ short *audio_buffer;
uchar *value_buffer;
uchar4 *pixel_buffer;
uchar4 *spectrum_buffer;
uchar4 *spectrogram_buffer;
uchar4 *saved_buffer;
int *saved_width;
int *saved_height;

Wyświetl plik

@ -22,7 +22,7 @@ limitations under the License.
#include "modes.rsh"
#include "stft.rsh"
void initialize(float rate, int length, int iw, int ih, int sw, int sh)
void initialize(float rate, int length, int iw, int ih, int sw, int sh, int sgw, int sgh)
{
sample_rate = rate;
buffer_length = length;
@ -33,7 +33,7 @@ void initialize(float rate, int length, int iw, int ih, int sw, int sh)
for (int i = 0; i < iw * ih; ++i)
pixel_buffer[i] = 0;
init_analyzer(sw, sh);
init_analyzer(sw, sh, sgw, sgh);
automatic_mode_detection = 1;
debug_mode = 0;

Wyświetl plik

@ -37,6 +37,7 @@ static int buffer_cleared;
static int bitmap_width, bitmap_height;
static int maximum_width, maximum_height;
static int spectrum_width, spectrum_height;
static int spectrogram_width, spectrogram_height;
static int sync_length, sync_counter, vpos, hpos;
static int seperator_counter, seperator_length;
static int u_sep_begin, u_sep_end, v_sep_begin, v_sep_end;

Wyświetl plik

@ -35,28 +35,42 @@ static inline uchar4 rainbow(float v)
static void freq_marker(int freq)
{
int i = (radix2_N * freq + sample_rate / 2) / sample_rate;
spectrum_buffer[i] = rgb(255, 255, 255);
int sgi = (spectrogram_width * freq + sample_rate / 4) / (sample_rate / 2);
spectrogram_buffer[sgi] |= rgb(64, 64, 64);
int si = (spectrum_width * freq + sample_rate / 4) / (sample_rate / 2);
for (int j = 0; j < spectrum_height; ++j)
spectrum_buffer[spectrum_width * j + si] |= rgb(64, 64, 64);
}
static void show_rainbow()
{
for (int j = 0; j < spectrum_height; ++j)
for (int i = 0; i < spectrum_width; ++i)
spectrum_buffer[spectrum_width * j + i] = rainbow((float)i / spectrum_width);
for (int j = 0; j < spectrogram_height; ++j)
for (int i = 0; i < spectrogram_width; ++i)
spectrogram_buffer[spectrogram_width * j + i] = rainbow((float)i / spectrogram_width);
}
static void clear_spectrum()
{
for (int i = 0; i < spectrum_height * spectrum_width; ++i)
spectrum_buffer[i] = 0;
for (int i = 0; i < spectrogram_height * spectrogram_width; ++i)
spectrogram_buffer[i] = 0;
}
static void init_analyzer(int sw, int sh)
static void fade_spectrum()
{
for (int i = 0; i < spectrum_height * spectrum_width; ++i)
spectrum_buffer[i] = 0xff000000 | (0x00fefefe & (int)spectrum_buffer[i]) >> 1;
}
static void init_analyzer(int sw, int sh, int sgw, int sgh)
{
disable_analyzer = 0;
spectrum_width = sw;
spectrum_height = sh;
spectrogram_width = sgw;
spectrogram_height = sgh;
show_rainbow();
}
@ -108,15 +122,24 @@ static void spectrum_analyzer(int amplitude)
radix2(output, input, radix2_N, 1, 0);
for (int i = 0; i < radix2_N; ++i)
input[i] = 0.0f;
for (int j = spectrum_height - 1; 0 < j; --j)
for (int i = 0; i < spectrum_width; ++i)
spectrum_buffer[spectrum_width * j + i] = spectrum_buffer[spectrum_width * (j-1) + i];
for (int i = 0; i < spectrum_width; ++i) {
int b = (i * (radix2_N / 2)) / spectrum_width;
float power = clamp(pown(cabs(output[b]) / 127.0f, 2), 0.0f, 1.0f);
for (int j = spectrogram_height - 1; 0 < j; --j)
for (int i = 0; i < spectrogram_width; ++i)
spectrogram_buffer[spectrogram_width * j + i] = spectrogram_buffer[spectrogram_width * (j-1) + i];
for (int i = 0; i < spectrogram_width; ++i) {
int b = (i * (radix2_N / 2)) / spectrogram_width;
float power = min(pown(cabs(output[b]) / 127.0f, 2), 1.0f);
float dB = 10.0f * log10(max(0.000001f, power));
float v = clamp((60.0f + dB) / 60.0f, 0.0f, 1.0f);
spectrum_buffer[i] = rainbow(v);
spectrogram_buffer[i] = rainbow(v);
}
fade_spectrum();
for (int b = 0; b < radix2_N / 2; ++b) {
float power = min(pown(cabs(output[b]) / 127.0f, 2), 1.0f);
float dB = 10.0f * log10(max(0.000001f, power));
float v = clamp((60.0f + dB) / 60.0f, 0.0f, 1.0f);
int i = (b * spectrum_width) / (radix2_N / 2);
int j = (spectrum_height - 1) - (spectrum_height - 1) * v;
spectrum_buffer[spectrum_width * j + i] = rgb(255, 255, 255);
}
freq_marker(1100 * M);
freq_marker(1300 * M);