Diskuze: správné nastavení loopu / opakování metody ANDROID
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.


Matúš Olejník:10.5.2018 11:53
Ak implementuješ SensorEventListener tak v metóde onSensorChanged(SensorEvent event) môžeš nastaviť že ak sa ti údaje z akcelerometra zmenili tak zavolaj startAudio() s novými údajmi.
Asi to nebude také jednoduché, ale za vyskúšanie nič nedáš
Díky za odpověď,
problém je, že musím zavolat celou metodu onTouchListener s ACTION.DOWN a tam
mi to padá (ještě jsem neměl čas na debug, ale myslím že bude problém
listener v listeneru). Pokud do SensorEventListener dám jen
setAudio(frekvence);, kde nastavuji frekvenci, tak to
frekvenci mění, ale přidává jí k už vytvořenému loopu základní
frekvence, takže s každým pohybem se přidá nová frekvence a hrají
zároveň.
setAudio vypadá takhle:
public void setSinus(int frekvence) {
sampleCount = (int) ((float) SAMPLE_RATE / frekvence);
short ssample[] = new short[sampleCount];
int amplitude = 32767;
double twoPi = 8. * Math.atan(1.);
double phase = 0.0;
for (int i = 0; i < sampleCount; i++) {
ssample[i] = (short) (amplitude * Math.sin(phase));
phase += twoPi * frekvence / SAMPLE_RATE;
}
siaudioTrack.write(ssample, 0, sampleCount);
}
Matúš Olejník:11.5.2018 17:03
Nedala by sa poslať celá aktivita?
Prípadne v ontouchlisteneri ak je event down nastav pomocnú premennú ktorá indikuje že je (napr.) button stlačený a v senzor listeneri budeš meniť frekvenciu len ak je premenná true. A nemôžeš v senzor listeneri zavolať stop audio a následne štart s novou frekvenciou? Či bolo by veľmi počuť pauzu?
+20 Zkušeností

celá aktivita vypadá asi takhle
public class fullscreen_start extends Activity implements SensorEventListener {
private Button melodieB;
private Switch bezDrzeni;
// private int frekvence = 500;
start start = new start();
@SuppressLint("StaticFieldLeak")
public static Context context_start;
private SensorManager mSensorManager;
private Sensor mAccelerometer;
@SuppressLint("ClickableViewAccessibility")
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen_start);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
assert mSensorManager != null;
mAccelerometer = mSensorManager.getDefaultSensor
(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL,
SensorManager.SENSOR_STATUS_ACCURACY_HIGH);
fullscreen_start.context_start = getApplicationContext();
melodieB = findViewById(R.id.bmelodie);
bezDrzeni = findViewById(R.id.switch_melodie);
button_generator();
switch_melodie();
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
int konecnafrekvence;
@Override
@SuppressLint("SetTextI18n")
public void onSensorChanged(SensorEvent event) {
//float x = event.values[0];
float y = event.values[1];
//float z = event.values[2];
double pet = 10.0 / 18;
double yy = (y / pet);
int yyy = (int) yy;
double mocnina1 = Math.pow(2, yyy);
double odmocnina1 = (Math.pow(mocnina1, (1.0 / 12)));
double senzorFreq = 440 * odmocnina1;
konecnafrekvence = (int) Math.round(senzorFreq);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@SuppressLint("ClickableViewAccessibility")
private void button_generator() {
melodieb.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (tvarsignalu.spinnerHL == null) {
start.setSinus(konecnafrekvence);
start.startsinus();
} else {
switch (tvarsignalu.spinnerHL.getSelectedItem().toString()) {
case "sinus":
System.out.println("pred play\n");
start.setSinus(konecnafrekvence);
start.startsinus();
case "čtverec":
start.setSquare(konecnafrekvence);
start.startsquare();
System.out.println("za setwave\n");
}
}
return true;
case MotionEvent.ACTION_UP:
start.stop();
return true;
}
return false;
}
});
}
private void switch_melodie() {
System.out.println(bezDrzeni);
bezDrzeni.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
System.out.println(bezdrzeni);
if (bezDrzeni.isChecked()) {
if (tvarsignalu.spinnerhl == null) {
start.setSinus(konecnafrekvence);
start.startsinus();
} else {
switch (tvarsignalu.spinnerhl.getSelectedItem().toString()) {
case "sinus":
System.out.println("pred play\n");
start.setSinus(konecnafrekvence);
start.startsinus();
case "čtverec":
start.setSquare(konecnafrekvence);
start.startsquare();
System.out.println("za setwave\n");
}
}
} else {
start.stop();
}
}
});
}
}
a zdroják pro classu kde definuji vlny vypadá asi takhle
public class start {
private final int SAMPLE_RATE = 44100;
private AudioTrack siaudioTrack;
private AudioTrack sqaudioTrack;
private int sampleCount;
private int sampleCountq;
public start() {
int buffsize = AudioTrack.getMinBufferSize
(SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
siaudioTrack = new AudioTrack
(AudioManager.STREAM_MUSIC, SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, buffsize, AudioTrack.MODE_STATIC);
sqaudioTrack = new AudioTrack
(AudioManager.STREAM_MUSIC, SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, buffsize, AudioTrack.MODE_STATIC);
}
public void setSinus(int frekvence) {
sampleCount = (int) ((float) SAMPLE_RATE / frekvence);
short ssample[] = new short[sampleCount];
int amplitude = 32767;
double twoPi = 8. * Math.atan(1.);
double phase = 0.0;
for (int i = 0; i < sampleCount; i++) {
ssample[i] = (short) (amplitude * Math.sin(phase));
phase += twoPi * frekvence / SAMPLE_RATE;
}
siaudioTrack.write(ssample, 0, sampleCount);
}
public void setSquare(int frekvence) {
sampleCountq = (int) ((float) SAMPLE_RATE / frekvence);
short sample[] = new short[sampleCountq];
int amplitude = 32767;
double phase = 0.0;
double twoPi = 8. * Math.atan(1.);
for (int i = 0; i < sampleCountq; i++) {
sample[i] = (short) (amplitude * Math.sin(phase));
if (sample[i] > 0.0) {
sample[i] = 32767;
}
if (sample[i] < 0.0) {
sample[i] = -32767;
}
phase += twoPi * frekvence / SAMPLE_RATE;
}
sqaudioTrack.write(sample, 0, sampleCountq);
}
public void startsinus() {
siaudioTrack.reloadStaticData();
siaudioTrack.setLoopPoints(0, sampleCount, -1);
siaudioTrack.play();
}
public void startsquare() {
sqaudioTrack.reloadStaticData();
sqaudioTrack.setLoopPoints(0, sampleCountq, -1);
sqaudioTrack.play();
}
public void stop() {
siaudioTrack.stop();
siaudioTrack.flush();
}
}
v senzorListeneru právě .stop použít nemůžu, protože jak se ta
activity načítá, tak to spadne s chybou, protože nemá ještě co
zastavovat.
jsem v tomhle nový, takže se ještě moc neorientuji, díky za pomoc.
Zobrazeno 5 zpráv z 5.