kiv.janecekz.ma.TunerFragment.java Source code

Java tutorial

Introduction

Here is the source code for kiv.janecekz.ma.TunerFragment.java

Source

/*
Musicians Assistant
Copyright (C) 2012-2014  Zdenk Jane?ek <jan.zdenek@gmail.com>
    
This program 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
any later version.
    
This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package kiv.janecekz.ma;

import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.widget.ImageView;
import android.widget.NumberPicker;
import android.widget.NumberPicker.OnValueChangeListener;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;

import kiv.janecekz.ma.common.Recorder;
import kiv.janecekz.ma.common.SharedData;
import kiv.janecekz.ma.prefs.SharedPref;
import kiv.janecekz.ma.tuner.AnalyzerAMDF;
import kiv.janecekz.ma.tuner.AnalyzerWave;
import kiv.janecekz.ma.tuner.Classificator;
import kiv.janecekz.ma.tuner.MedianFilter;
import kiv.janecekz.ma.tuner.Tune;

@SuppressLint("NewApi")
public class TunerFragment extends Fragment implements IControlable, Informable {
    private static final int METHOD_AMDF = 0;
    private static final int METHOD_WAVE = 1;

    private Recorder recorder;
    private SharedData sd;
    private AsyncTask<Void, Double, Void> analyzer;
    private Classificator classify;
    private MedianFilter mf;

    private ImageView circle;
    private TextView tunerText;
    private Tune bar;
    private AlphaAnimation inAnim;
    private AlphaAnimation outAnim;
    private NumberPicker refFreq;
    private net.simonvt.numberpicker.NumberPicker refFreqOld;

    private int temp;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.tuner, container, false);
        RelativeLayout space = (RelativeLayout) v.findViewById(R.id.sunspace);
        space.setOnTouchListener(TouchControl.getInstance());

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            refFreqOld = (net.simonvt.numberpicker.NumberPicker) v.findViewById(R.id.refFreq);
            refFreqOld.setMinValue(390);
            refFreqOld.setMaxValue(460);
            refFreqOld.setOnValueChangedListener(new net.simonvt.numberpicker.NumberPicker.OnValueChangeListener() {
                @Override
                public void onValueChange(net.simonvt.numberpicker.NumberPicker picker, int oldVal, int newVal) {
                    classify.changeRef(newVal);
                }
            });
            refFreqOld.setValue(SharedPref.getConcertPitch(getActivity()));
        } else {
            refFreq = (NumberPicker) v.findViewById(R.id.refFreq);
            refFreq.setMinValue(390);
            refFreq.setMaxValue(460);
            refFreq.setOnValueChangedListener(new OnValueChangeListener() {
                @Override
                public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
                    classify.changeRef(newVal);
                }
            });
            refFreq.setValue(SharedPref.getConcertPitch(getActivity()));
        }

        circle = (ImageView) v.findViewById(R.id.circle);
        tunerText = (TextView) v.findViewById(R.id.tuner_text);

        bar = (Tune) v.findViewById(R.id.tune);

        inAnim = TouchControl.getAnimation(TouchControl.ANIMATION_IN, 300);
        outAnim = TouchControl.getAnimation(TouchControl.ANIMATION_OUT, 300);

        return v;
    }

    @Override
    public void onPause() {
        analyzer.cancel(true);
        recorder.stopRecording();
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            SharedPref.setConcertPitch(getActivity(), refFreqOld.getValue());
        } else {
            SharedPref.setConcertPitch(getActivity(), refFreq.getValue());
        }
        super.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();

        // set saved values
        getView().setBackgroundResource(((MainActivity) getActivity()).getBgRes());

        temp = SharedPref.getTemp(getActivity());

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            refFreqOld.setValue(SharedPref.getConcertPitch(getActivity()));
        } else {
            refFreq.setValue(SharedPref.getConcertPitch(getActivity()));
        }

        classify = new Classificator(SharedPref.getConcertPitch(getActivity()));

        mf = new MedianFilter();

        // launch recording and analysis
        sd = new SharedData(1024);
        recorder = new Recorder(sd, 44100);
        recorder.start();

        int method = SharedPref.getAnlMethod(getActivity().getApplicationContext());

        if (method == METHOD_AMDF)
            analyzer = new AnalyzerAMDF(sd, recorder, this);
        else if (method == METHOD_WAVE)
            analyzer = new AnalyzerWave(sd, recorder, this);

        analyzer.execute();
    }

    @Override
    public void onValueChange(TouchControl t, int val) {

    }

    @Override
    public void onToggle(TouchControl t, int state) {
        switch (state) {
        case TouchControl.STATE_BEGIN:
            circle.setVisibility(View.VISIBLE);
            circle.startAnimation(inAnim);
            break;
        case TouchControl.STATE_TOGGLE:
            // not used

            break;
        case TouchControl.STATE_OUT:
            if (!inAnim.hasEnded())
                inAnim.cancel();
            circle.startAnimation(outAnim);
            circle.setVisibility(View.INVISIBLE);
            break;
        default:
            break;
        }
    }

    @Override
    public void onPositionChange(TouchControl t, int x, int y) {
        RelativeLayout.LayoutParams pars = (LayoutParams) circle.getLayoutParams();
        pars.setMargins(x - circle.getWidth() / 2, y - circle.getHeight() / 2, 0, 0);

        circle.setLayoutParams(pars);
    }

    public void postInformation(Double freq) {
        // classify frequency
        mf.addValue(classify.findTone(freq, temp));

        // return median from the list
        Classificator.Result r = mf.getMedian();

        // show the result
        tunerText.setText(String.format("%s\n%.1f Hz", r.getTone(), r.getFreq()));

        float f;
        if (r.getError() >= 0)
            f = (float) (1 - (r.getError() - 1) * (r.getError() - 1));
        else
            f = (float) ((-r.getError() - 1) * (-r.getError() - 1) - 1);

        bar.setVal(f);
    }
}