0

Android デバイスのオーディオ ジャックから制御可能な DC 電圧を出力したいと考えています。私の現在の解決策は、出力される波形の PCM 情報を含む 1 秒の配列を作成することです (この場合はフラットライン)。

問題は、毎秒、出力が瞬間的にゼロボルトに低下するグリッチがあることです。これは、オーディオ リソース インスタンスが作成された時点で発生していると思います。

オーディオが独自のスレッドで処理されていることがわかります。別のスレッドで generatedSnd 配列を変更します。

これを行うよりスムーズな方法はありますか?ストリーミングはやるべきことだとは思いますが、頭に浮かびません。

private class OutDACrunnable
    implements Runnable {

    public void run() {
        while (! done) {

        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                sampleRate, AudioFormat. CHANNEL_OUT_STEREO,
                AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length,
                AudioTrack.MODE_STATIC);

        audioTrack.write(generatedSnd, 0, generatedSnd.length);

        if (audioManager.isWiredHeadsetOn()) { } // use this later

        audioTrack.play();

        // wait until playback is complete
        int x = 0;
        do {
            if (audioTrack == null) {
                x = numSamples;
            } else {
                x = audioTrack.getPlaybackHeadPosition(); 
            }
        } while (x < numSamples);

        if (audioTrack != null) audioTrack.release();

        }
    }

} // OutDACrunbable

ありがとう。

4

2 に答える 2

0

必要に応じて書き込みをブロックすることについて Bjorn からヒントを得た後、コードを微調整しました。したがって、基本的には、15ms ごとに 20ms のサンプルを投げます。バッファがいっぱいになると破棄するので、バッファも20msにしました。このようにして、私の要求に最新の状態を保ち、ブリップはありません...

        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                sampleRate, AudioFormat. CHANNEL_OUT_STEREO,
                AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length,
                AudioTrack.MODE_STREAM);

        audioTrack.play();

    private class OutDACrunnable
        implements Runnable {

        public void run() {
            while (! done) {
                playTone();
                try {
                    Thread.sleep((int) (750 * duration));
                } catch (InterruptedException e) {
                    Log.e(MyTag, "OutDACrunnable: " + e.toString());
                }
            }
        }

    } // OutDACrunbable

    void playTone() {

    //      Log.d(MyTag, "playTone: start");

            audioTrack.write(generatedSnd, 0, generatedSnd.length);

            if (audioManager.isWiredHeadsetOn()) { } // use this later

    //      Log.d(MyTag, "playTone: done");

    } // playTone

    public static void genTone(double amp1, double amp2) {

//      Log.d(MyTag, "genTone: start");

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

        }
//      Log.d(MyTag, "genTone: done");
    }

そして、出力したい2つのDCを使用して、必要に応じてGenToneを呼び出すだけです...

于 2013-06-06T22:16:33.817 に答える
0

残念ながら、オーディオ ジャックから DC を出力することはできません。オーディオ I/O は、変化する信号を通過させるように設計されており、一般的には 20 Hz を超えています。DCを出力しようとすると、パルスのようなものが得られます。これは、得られているように聞こえます。

于 2013-06-06T13:37:14.480 に答える