AIDE第4个程序代码简谱播放器


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    android:gravity="center">

    <EditText
        android:id="@+id/edit_text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:hint="输入字符 1"
        android:textSize="18sp"/>

    <EditText
        android:id="@+id/edit_text2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:hint="输入字符 2"
        android:textSize="18sp"/>

    <EditText
        android:id="@+id/speed_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:hint="输入速度(毫秒)"
        android:inputType="number"
        android:textSize="18sp"/>

    <Button
        android:id="@+id/play_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Play"
        android:textSize="20sp"
        android:background="@color/teal_700"
        android:textColor="@android:color/white"
        android:padding="12dp"
        android:layout_gravity="center"/>

</LinearLayout>





package com.a.app;
/*
    手机编程王APP & AIDE编译器联合出品
    官方微信2133688724
    微信公众号:手机编程APP
    官网:www.shoujibiancheng.com
*/


import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioTrack;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;

class ToneInfo {
    int frequency;
    int duration;

    public ToneInfo(int frequency, int duration) {
        this.frequency = frequency;
        this.duration = duration;
    }
}

public class MainActivity extends AppCompatActivity {

    private EditText editText1, editText2, speedInput;
    private Button playButton;
    private boolean isPlaying = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText1 = findViewById(R.id.edit_text1);
        editText2 = findViewById(R.id.edit_text2);
        speedInput = findViewById(R.id.speed_input);
        playButton = findViewById(R.id.play_button);

        playButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!isPlaying) {
                    isPlaying = true;

                    // Get input strings from the edit texts
                    String input1 = editText1.getText().toString();
                    String input2 = editText2.getText().toString();
                    String speedStr = speedInput.getText().toString();
                    int speed = TextUtils.isEmpty(speedStr)? 500 : Integer.parseInt(speedStr);

                    // Separate inputs into arrays of characters
                    char[] inputChars1 = input1.toCharArray();
                    char[] inputChars2 = input2.toCharArray();

                    // Determine the maximum number of iterations needed for both inputs
                    int maxLength = Math.max(inputChars1.length, inputChars2.length);

                    // Run the playback in a separate thread
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            for (int i = 0; i < maxLength; i++) {

                                // If we still have characters left in input1, play the corresponding beep tone
                                if (i < inputChars1.length) {
                                    char c = inputChars1[i];
                                    ToneInfo toneInfo = getToneType(c, i + 1 < inputChars1.length? inputChars1[i + 1] : '\0');
                                    if (toneInfo.frequency != 0) {
                                        playTone(toneInfo.frequency, toneInfo.duration);
                                        if (toneInfo.frequency != 0 && i + 1 < inputChars1.length && (inputChars1[i + 1] == '+' || inputChars1[i + 1] == '-')) {
                                            i++; // 跳过高音或低音标识
                                        }
                                    }
                                }

                                // If we still have characters left in input2, play the corresponding beep tone
                                if (i < inputChars2.length) {
                                    char c = inputChars2[i];
                                    ToneInfo toneInfo = getToneType(c, i + 1 < inputChars2.length? inputChars2[i + 1] : '\0');
                                    if (toneInfo.frequency != 0) {
                                        playTone(toneInfo.frequency, toneInfo.duration);
                                        if (toneInfo.frequency != 0 && i + 1 < inputChars2.length && (inputChars2[i + 1] == '+' || inputChars2[i + 1] == '-')) {
                                            i++; // 跳过高音或低音标识
                                        }
                                    }
                                }

                                // Wait for the specified speed between each tone sequence
                                try {
                                    Thread.sleep(speed);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }

                            // Signal that the playback has finished
                            isPlaying = false;

                            // Update the UI on the main thread
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    playButton.setText("Play");
                                }
                            });
                        }
                    }).start();

                    // Update the UI to show that playback is in progress
                    playButton.setText("Stop");
                } else {
                    // Stop the playback
                    isPlaying = false;
                    playButton.setText("Play");
                }
            }
        });
    }

    private void playTone(int frequency, int duration) {
        int sampleRate = 44100;
        int numSamples = duration * sampleRate / 1000;
        double[] sample = new double[numSamples];
        byte[] generatedSnd = new byte[2 * numSamples];

        for (int i = 0; i < numSamples; ++i) {
            sample[i] = Math.sin(2 * Math.PI * i / (sampleRate / frequency));
        }

        // convert to 16 bit pcm sound array
        // assumes the sample buffer is normalised.
        int idx = 0;
        for (final double dVal : sample) {
            // scale to maximum amplitude
            final short val = (short) ((dVal * 32767));
            // in 16 bit wav PCM, first byte is the low order byte
            generatedSnd[idx++] = (byte) (val & 0x00ff);
            generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
        }

        AudioAttributes audioAttributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_MEDIA)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build();

        AudioFormat audioFormat = new AudioFormat.Builder()
                .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
                .setSampleRate(sampleRate)
                .setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
                .build();

        AudioTrack audioTrack = new AudioTrack(audioAttributes, audioFormat,
                generatedSnd.length, AudioTrack.MODE_STATIC, 0);
        audioTrack.write(generatedSnd, 0, generatedSnd.length);
        audioTrack.play();

        // 等待音频播放完成
        while (audioTrack.getPlaybackHeadPosition() < numSamples) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // 释放 AudioTrack 资源
        audioTrack.stop();
        audioTrack.release();
    }

    /**
     * Map the given character to the corresponding beep tone type
     * @param c the character to map
     * @param modifier 高音或低音标识
     * @return the beep tone type, or -1 if the character is invalid
     */
    private ToneInfo getToneType(char c, char modifier) {
        int baseFrequency = 0;
        int duration = 300;

        switch (c) {
            case '1':
                baseFrequency = 261;
                break;
            case '2':
                baseFrequency = 293;
                break;
            case '3':
                baseFrequency = 329;
                break;
            case '4':
                baseFrequency = 349;
                break;
            case '5':
                baseFrequency = 392;
                break;
            case '6':
                baseFrequency = 440;
                break;
            case '7':
                baseFrequency = 493;
                break;
            case '-':
                baseFrequency = 0;
                break;
            default:
                baseFrequency = 0;
                duration = 0;
                break;
        }

        if (modifier == '*') {
            baseFrequency *= 2; // 高音,频率翻倍
        } else if (modifier == '.') {
            baseFrequency /= 2; // 低音,频率减半
        }

        return new ToneInfo(baseFrequency, duration);
    }
}














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EasySoft易软

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值