关于“使用 Android 播放任意音调”

Posted

技术标签:

【中文标题】关于“使用 Android 播放任意音调”【英文标题】:about "Playing an arbitrary tone with Android" 【发布时间】:2013-07-03 04:33:47 【问题描述】:

找不到关于 Steve Pomeroy 发布的“使用 android 播放任意音调”的问题,因此开始发帖 here。

是否有任何代码需要添加到 xml 文件中? 无法让 sim 发出声音。

public class PlaySound extends Activity 
    // originally from http://marblemice.blogspot.com/2010/04/generate-and-play-tone-in-android.html
    // and modified by Steve Pomeroy <steve@staticfree.info>
    private final int duration = 3; // seconds
    private final int sampleRate = 8000;
    private final int numSamples = duration * sampleRate;
    private final double sample[] = new double[numSamples];
    private final double freqOfTone = 440; // hz

private final byte generatedSnd[] = new byte[2 * numSamples];

Handler handler = new Handler();

@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);


@Override
protected void onResume() 
    super.onResume();

    // Use a new tread as this can take a while
    final Thread thread = new Thread(new Runnable() 
        public void run() 
            genTone();
            handler.post(new Runnable() 

                public void run() 
                    playSound();
                
            );
        
    );
    thread.start();


void genTone()
    // fill out the array
    for (int i = 0; i < numSamples; ++i) 
        sample[i] = Math.sin(2 * Math.PI * i / (sampleRate/freqOfTone));
    

    // 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);

    


void playSound()
    final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
            sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO,
            AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length,
            AudioTrack.MODE_STATIC);
    audioTrack.write(generatedSnd, 0, generatedSnd.length);
    audioTrack.play();


有没有类似的东西:

activity android:soundEffectsEnabled="true" 

uses-permission android:name="android.permission.WRITE_SETTINGS"

需要添加上面的代码才能在eclipse等模拟器中发出声音吗?

我添加了活动 android:soundEffectsEnabled="true" 和使用权限 android:name="android.permission.WRITE_SETTINGS"/,但仍然不会发出声音。

以为是声音的持续时间,因为当持续时间设置为 10 而不是 1 时,它会发出哔声,但很短。但是,在第三次运行之后,会抛出一个 inflateException。

持续时间超过 500 会导致内存不足错误,这就是异常。但是100的持续时间仍然只会发出很短的哔声,大麦能听到,鼠标点击的声音更大。

超过 250 的持续时间是记忆的拥抱。

持续时间为 10 的点击时间与持续时间为 250 的时间一样长。 generatedSnd.length 为 10 与 generateSnd.length 为 15k 一样长 已将 freqOfTone 从 100 更改为 55000。

还是不知道怎么让声音变长。

【问题讨论】:

【参考方案1】:

添加

    int x = 0;
    // Montior playback to find when done
    do
                                                         
         if (audioTrack != null) 
             x = audioTrack.getPlaybackHeadPosition(); 
         else 
             x = numSamples;            
    
    while (x<numSamples);

    // Track play done. Release track.
    if (audioTrack != null) audioTrack.release();

之后 audioTrack.play(); 在第一次运行后停止短按。

现在我必须找出为什么当我更改 freqOfTone 时它​​不起作用。

【讨论】:

以上是关于关于“使用 Android 播放任意音调”的主要内容,如果未能解决你的问题,请参考以下文章

关于避免模糊查询索引时效问题

关于mapper.xml中做类似if else的判断

关于 Android View Touch 事件

ANDR-PERF tryGetService 失败; SELinux

C++Philosophy

关于四则运算新版本声明