#java #android #puredata
#java #Android #puredata
Вопрос:
Я следил за этой библиотекой.
Ошибки в кодировании не было. Но когда я играл на своем телефоне, красная полоса вообще не двигалась. Не могли бы вы объяснить, что не так?
Я действительно новичок, и был бы признателен, если бы вы могли легко объяснить.
манифестирует
<?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>
сборка 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 amp;amp; 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="En(6th String)" >
</Button>
<Button
android:id="@ id/a_button"
android:text="An(5th String)" >
</Button>
<Button
android:id="@ id/d_button"
android:text="Dn(4th String)" >
</Button>
</TableRow>
<TableRow android:layout_width="fill_parent" >
<Button
android:id="@ id/g_button"
android:text="Gn(3rd String)" >
</Button>
<Button
android:id="@ id/b_button"
android:text="Bn(2nd String)" >
</Button>
<Button
android:id="@ id/ee_button"
android:text="En(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;
Комментарии:
1. Привет и добро пожаловать в SO. Первое, что нужно сделать, это скопировать ваш код в отдельный проект и обрезать пример кода, который воспроизводит вашу проблему, и опубликовать только абсолютный минимальный образец кода, в котором все еще есть ошибка. Это поможет не только нам, но и вам сосредоточиться на реальной проблеме. Скорее всего, вы не только поймете проблему, но и сами придумаете решение.
2. @StarShine спасибо, что поприветствовали меня 🙂 Я копирую коды один за другим и устраняю все ошибки. Но потом это не сработало, когда я открыл приложение. Так что я действительно не знаю, что не так, поскольку нет сообщения об ошибке, в котором указывалось бы, какие части неисправны. Вот почему я поместил все коды сюда.
3. @WoojuSpace вы решили это? Я заставляю его работать в kitkat, но не в последних версиях Android даже со всеми разрешениями.
4. @RGS Нет, я не смог это решить. На самом деле, я пока сдался.