kopia lustrzana https://github.com/xdsopl/robot36
added spectrum view to present spectrogram
rodzic
8b3d4bc191
commit
1c3f90aef0
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Ładowanie…
Reference in New Issue