package com.ihunda.android.binauralbeat; /* * @author Giorgio Regni * @contact @GiorgioRegni on Twitter * http://twitter.com/GiorgioRegni * * This file is part of Binaural Beats Therapy or BBT. * * BBT is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * BBT is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with BBT. If not, see <http://www.gnu.org/licenses/>. * * BBT project home is at https://github.com/GiorgioRegni/Binaural-Beats */ import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; public class CanvasVizualizationView extends SurfaceView implements Callback, VizualisationView { protected static final long DRAW_REFRESH_INTERVAL_NS = 1000 * 1000 * 1000 / 16; // # time between refreshes protected static final long DRAW_REFRESH_INTERVAL_MIN_NS = 1000 * 1000 * 1000 / 20; // # time between refreshes private static final String LOGVIZVIEW = "BBT-VIZ"; private SurfaceHolder mSurfaceHolder; private int width; private int height; private CanvasVisualization v; private boolean running; protected float pos; protected float length; private Thread vThread; public CanvasVizualizationView(Context context) { super(context); // register our interest in hearing about changes to our surface mSurfaceHolder = getHolder(); mSurfaceHolder.addCallback(this); setFocusable(true); // make sure we get key events v = null; running = false; } /* Callback invoked when the surface dimensions change. */ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { this.width = width; this.height = height; } public void surfaceCreated(SurfaceHolder holder) { if (vThread == null) { Log.e(LOGVIZVIEW, "SURFACE NEW THREAD"); running = true; vThread = new Thread(vizThread); vThread.start(); } } public void surfaceDestroyed(SurfaceHolder holder) { running = false; boolean retry = true; if (vThread != null) { while (retry) { try { vThread.join(); retry = false; vThread = null; } catch (InterruptedException e) { } } } } public void startVisualization(Visualization v, float length) { drawClear(); if (v == null) return; this.v = (CanvasVisualization) v; this.pos = 0; this.length = length; running = true; if (vThread == null) { Log.e(LOGVIZVIEW, "START VIZ NEW THREAD"); vThread = new Thread(vizThread); vThread.start(); } } public void stopVisualization() { boolean retry = true; this.v = null; running = false; if (vThread != null) { while (retry) { try { vThread.join(); retry = false; vThread = null; } catch (InterruptedException e) { } } } drawClear(); } public void setProgress(float pos) { this.pos = pos; } public void setFrequency(float freq) { if (v != null) v.setFrequency(freq); } void drawMain(float now, float length) { Canvas c = null; try { c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { if (c != null && v != null ) { v.redraw(c, width, height, now, length); } } } finally { // do this in a finally so that if an exception is thrown // during the above, we don't leave the Surface in an // inconsistent state if (c != null) { mSurfaceHolder.unlockCanvasAndPost(c); } } } void drawClear() { Canvas c = null; try { c = mSurfaceHolder.lockCanvas(null); if (c != null) synchronized (mSurfaceHolder) { c.drawColor(Color.BLACK); } } finally { // do this in a finally so that if an exception is thrown // during the above, we don't leave the Surface in an // inconsistent state if (c != null) { mSurfaceHolder.unlockCanvasAndPost(c); } } } private Runnable vizThread = new Runnable() { public void run() { int i = 0; Log.e(LOGVIZVIEW, String.format("START THREAD")); while(running == true) { long now = System.nanoTime(); //Log.e("JENlA", String.format("%d %d %s", now, i, vizThread.toString())); drawMain(pos, length); i++; long elapsed = System.nanoTime() - now; if(elapsed < DRAW_REFRESH_INTERVAL_NS) { try { Thread.sleep((DRAW_REFRESH_INTERVAL_NS - elapsed) / 1000 / 1000, 0); } catch (InterruptedException e) { } } } Log.e(LOGVIZVIEW, String.format("END THREAD redrew %d times", i)); } }; }