0

I followed this library.

There was no error in coding. But when I played on my phone, the red bar doesn't move at all. Could you explain what's wrong?

I am really a beginner that I would appreciate it if you can explain easily.

Red bar doesn't move at all.

manifests

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.GuitarTuner">

    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/tuner"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/tuner"
        android:supportsRtl="true"
        android:theme="@style/Theme.Design.NoActionBar">
        <activity android:name="com.example.GuitarTuner.GuitarTunerActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

build gradle

plugins {
    id 'com.android.application'
}

android {
    compileSdkVersion 29
    buildToolsVersion "30.0.2"

    defaultConfig {
        applicationId "com.example.Guitar1"
        minSdkVersion 24
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'org.puredata.android:pd-core:1.2.1-rc1'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

GuitarTunerActivity

package com.example.GuitarTuner;

import java.io.File;
import java.io.IOException;

import org.puredata.android.io.AudioParameters;
import org.puredata.android.service.PdService;
import org.puredata.android.utils.PdUiDispatcher;
import org.puredata.core.PdBase;
import org.puredata.core.PdListener;
import org.puredata.core.utils.IoUtils;

import com.example.GuitarTuner.R;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class GuitarTunerActivity extends Activity implements OnClickListener {

    private static final String TAG = "GuitarTuner";
    private PdUiDispatcher dispatcher;

    private Button eButton;
    private Button aButton;
    private Button dButton;
    private Button gButton;
    private Button bButton;
    private Button eeButton;
    private TextView pitchLabel;
    private PitchView pitchView;

    private PdService pdService = null;

    private final ServiceConnection pdConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            pdService = ((PdService.PdBinder)service).getService();
            try {
                initPd();
                loadPatch();
            } catch (IOException e) {
                Log.e(TAG, e.toString());
                finish();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // this method will never be called
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initGui();
        initSystemServices();
        bindService(new Intent(this, PdService.class), pdConnection, BIND_AUTO_CREATE);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unbindService(pdConnection);
    }

    private void initGui() {
        setContentView(R.layout.activity_main);
        eButton = (Button) findViewById(R.id.e_button);
        eButton.setOnClickListener(this);
        aButton = (Button) findViewById(R.id.a_button);
        aButton.setOnClickListener(this);
        dButton = (Button) findViewById(R.id.d_button);
        dButton.setOnClickListener(this);
        gButton = (Button) findViewById(R.id.g_button);
        gButton.setOnClickListener(this);
        bButton = (Button) findViewById(R.id.b_button);
        bButton.setOnClickListener(this);
        eeButton = (Button) findViewById(R.id.ee_button);
        eeButton.setOnClickListener(this);
        pitchLabel = (TextView) findViewById(R.id.pitch_label);
        pitchView = (PitchView) findViewById(R.id.pitch_view);
        pitchView.setCenterPitch(45);
        pitchLabel.setText("A-String");
    }

    private void  initPd() throws IOException {
        // Configure the audio glue
        AudioParameters.init(this);
        int sampleRate = AudioParameters.suggestSampleRate();
        pdService.initAudio(sampleRate, 1, 2, 10.0f);
        start();

        // Create and install the dispatcher
        dispatcher = new PdUiDispatcher();
        PdBase.setReceiver(dispatcher);
        dispatcher.addListener("pitch", new PdListener.Adapter() {
            @Override
            public void receiveFloat(String source, final float x) {
                pitchView.setCurrentPitch(x);
            }
        });
    }

    private void start() {
        if (!pdService.isRunning()) {
            Intent intent = new Intent(GuitarTunerActivity.this,
                    GuitarTunerActivity.class);
            pdService.startAudio(intent, R.drawable.icon,
                    "GuitarTuner", "Return to GuitarTuner.");
        }
    }

    private void loadPatch() throws IOException {
        File dir = getFilesDir();
        IoUtils.extractZipResource(
                getResources().openRawResource(R.raw.tuner), dir, true);
        File patchFile = new File(dir, "tuner.pd");
        PdBase.openPatch(patchFile.getAbsolutePath());
    }

    private void initSystemServices() {
        TelephonyManager telephonyManager =
                (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        telephonyManager.listen(new PhoneStateListener() {
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                if (pdService == null) return;
                if (state == TelephonyManager.CALL_STATE_IDLE) {
                    start(); } else {
                    pdService.stopAudio(); }
            }
        }, PhoneStateListener.LISTEN_CALL_STATE);
    }

    private void triggerNote(int n) {
        PdBase.sendFloat("midinote", n);
        PdBase.sendBang("trigger");
        pitchView.setCenterPitch(n);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.e_button:
                triggerNote(40); // E (low) is MIDI note 40.
                pitchLabel.setText("E-String");
                break;
            case R.id.a_button:
                triggerNote(45); // A is MIDI note 45.
                pitchLabel.setText("A-String");
                break;
            case R.id.d_button:
                triggerNote(50); // D is MIDI note 50.
                pitchLabel.setText("D-String");
                break;
            case R.id.g_button:
                triggerNote(55); // G is MIDI note 55.
                pitchLabel.setText("G-String");
                break;
            case R.id.b_button:
                triggerNote(59); // B is MIDI note 59.
                pitchLabel.setText("B-String");
                break;
            case R.id.ee_button:
                triggerNote(64); // E (high) is MIDI note 64.
                pitchLabel.setText("E-String");
                break;
        }
    }
}

PitchView

package com.example.GuitarTuner;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class PitchView extends View {

    private float centerPitch, currentPitch;
    private int width, height;
    private final Paint paint = new Paint();

    public PitchView(Context context) {
        super(context);
    }

    public PitchView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public PitchView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setCenterPitch(float centerPitch) {
        this.centerPitch = centerPitch;
        invalidate();
    }

    public void setCurrentPitch(float currentPitch) {
        this.currentPitch = currentPitch;
        invalidate();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        float halfWidth = width / 2;
        paint.setStrokeWidth(6.0f);
        paint.setColor(Color.GREEN);
        canvas.drawLine(halfWidth, 0, halfWidth, height, paint);

        float dx = (currentPitch - centerPitch) / 2;
        if (-1 < dx && dx < 1) {
            paint.setStrokeWidth(2.0f);
            paint.setColor(Color.BLUE);
        } else {
            paint.setStrokeWidth(8.0f);
            paint.setColor(Color.RED);
            dx = (dx < 0) ? -1 : 1;
        }
        double phi = dx * Math.PI / 4;
        canvas.drawLine(halfWidth, height,
                halfWidth + (float)Math.sin(phi) * height * 0.9f,
                height - (float)Math.cos(phi) * height * 0.9f, paint);
    }
}

activity_main

<?xml version="1.0" encoding="utf-8"?>

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:shrinkColumns="*"
    android:stretchColumns="*" >

    <TableRow android:layout_width="fill_parent" >

        <TextView
            android:id="@+id/titleView"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_span="3"
            android:padding="20px"
            android:text="GuitarTuner"
            android:textAppearance="?android:attr/textAppearanceLarge" >
        </TextView>
    </TableRow>

    <TableRow android:layout_width="fill_parent" >

        <Button
            android:id="@+id/e_button"
            android:text="E\n(6th String)" >
        </Button>

        <Button
            android:id="@+id/a_button"
            android:text="A\n(5th String)" >
        </Button>

        <Button
            android:id="@+id/d_button"
            android:text="D\n(4th String)" >
        </Button>
    </TableRow>

    <TableRow android:layout_width="fill_parent" >

        <Button
            android:id="@+id/g_button"
            android:text="G\n(3rd String)" >
        </Button>

        <Button
            android:id="@+id/b_button"
            android:text="B\n(2nd String)" >
        </Button>

        <Button
            android:id="@+id/ee_button"
            android:text="E\n(1st String)" >
        </Button>
    </TableRow>

    <TableRow android:layout_width="fill_parent" >

        <TextView
            android:id="@+id/pitch_label"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_span="3"
            android:gravity="center"
            android:padding="20px"
            android:text="0.0" >
        </TextView>
    </TableRow>

    <TableRow android:layout_width="fill_parent" >

        <com.example.GuitarTuner.PitchView
            android:id="@+id/pitch_view"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_span="3" >
        </com.example.GuitarTuner.PitchView>

    </TableRow>



</TableLayout>

tuner.pd

#N canvas 584 146 450 300 10;
#X obj 354 125 adc~;
#X floatatom 354 169 5 0 0 1 s:pitch - pitch;
#X obj 49 25 bng 15 250 50 0 empty trigger r:trigger 17 7 0 10 -262144
-1 -1;
#X msg 49 45 1 10 \, 0 1000 10;
#X obj 49 67 vline~;
#X obj 49 89 *~;
#X obj 49 111 dac~;
#X floatatom 192 22 5 0 0 1 r:midinote midinote -;
#X obj 192 41 mtof;
#X obj 192 63 osc~ 220;
#X obj 354 147 fiddle~ 2048;
#X connect 0 0 10 0;
#X connect 2 0 3 0;
#X connect 3 0 4 0;
#X connect 4 0 5 0;
#X connect 5 0 6 0;
#X connect 5 0 6 1;
#X connect 7 0 8 0;
#X connect 8 0 9 0;
#X connect 9 0 5 1;
#X connect 10 0 1 0;
Federico klez Culloca
  • 26,308
  • 17
  • 56
  • 95
cloud
  • 77
  • 6
  • Hi and welcome to SO. The first thing to do is to copy your code to a separate project and trim down the example code that reproduces your problem, and post only the absolute minimal code sample that still has the bug. It will help not only help us but also you to focus on the real problem. Chances are you'll not only understand the problem but also come up with a solution yourself. – StarShine Dec 23 '20 at 09:40
  • @StarShine thank you for welcoming me :) I copy codes one by one and solved all the errors. But then it doesn't work when I opened the app. So I really don't know what is wrong as there is no error message saying which parts are wrong. That's why I put all codes here. – cloud Dec 23 '20 at 21:35
  • @WoojuSpace did you solve it? I make it work in kitkat, but not in recent android versions even with all permissions. – RGS Jan 23 '21 at 19:18
  • @RGS No I couldn't solve it. Actually, I gave up for now. – cloud Jan 25 '21 at 03:09

0 Answers0