Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android DC音频输出_Java_Android_Audio_Robotics - Fatal编程技术网

Java Android DC音频输出

Java Android DC音频输出,java,android,audio,robotics,Java,Android,Audio,Robotics,我想把一个可控的直流电压输出到安卓设备的音频插孔。我目前的解决方案是创建一个1秒的数组,其中包含要输出波形的PCM信息(在这种情况下是一条平面线) 问题是每秒钟都会出现一个小故障,输出电压瞬间降至零伏。我相信这是在创建音频资源实例时发生的 您可以看到音频是在自己的线程中处理的。我将在另一个线程中更改生成的SND数组 有没有更顺畅的方法?我有一种感觉,这是我该走的路,但我无法控制它 private class OutDACrunnable implements Runnable {

我想把一个可控的直流电压输出到安卓设备的音频插孔。我目前的解决方案是创建一个1秒的数组,其中包含要输出波形的PCM信息(在这种情况下是一条平面线)

问题是每秒钟都会出现一个小故障,输出电压瞬间降至零伏。我相信这是在创建音频资源实例时发生的

您可以看到音频是在自己的线程中处理的。我将在另一个线程中更改生成的SND数组

有没有更顺畅的方法?我有一种感觉,这是我该走的路,但我无法控制它

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
私有类无法运行
实现可运行{
公开募捐{
而(!完成){
audioTrack=新的audioTrack(AudioManager.STREAM_MUSIC,
音频格式采样器。通道输出立体声,
AudioFormat.ENCODING_PCM_16位,生成SND.length,
音频跟踪模式(静态);
audioTrack.write(generatedSnd,0,generatedSnd.length);
如果(audioManager.isWiredHeadsetOn()){}//请稍后使用
音轨播放();
//等待播放完成
int x=0;
做{
如果(音频轨==null){
x=numSamples;
}否则{
x=audioTrack.getPlaybackHeadPosition();
}
}而(x

谢谢。

不幸的是,您无法从音频插孔输出直流电。音频I/o设计用于传递不断变化的信号,一般来说高于20 Hz。如果你尝试输出DC,你会得到更像脉冲的东西,这听起来就像你得到的一样。

在Bjorn提供了关于写阻塞的提示之后,我调整了我的代码。所以,基本上,我每15毫秒向它扔20毫秒的样本。一旦缓冲区满了,它就会丢弃,所以我也制作了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");
    }
audioTrack=新的audioTrack(AudioManager.STREAM\u音乐、,
音频格式采样器。通道输出立体声,
AudioFormat.ENCODING_PCM_16位,生成SND.length,
音频跟踪模式(音频流);
音轨播放();
私有类无法运行
实现可运行{
公开募捐{
而(!完成){
playTone();
试一试{
睡眠((int)(750*duration));
}捕捉(中断异常e){
Log.e(MyTag,“OutDACrunnable:+e.toString());
}
}
}
}//OutDACrunbable
void playTone(){
//Log.d(MyTag,“playTone:start”);
audioTrack.write(generatedSnd,0,generatedSnd.length);
如果(audioManager.isWiredHeadsetOn()){}//请稍后使用
//Log.d(MyTag,“playTone:done”);
}//playTone
公共静态电压(双amp1,双amp2){
//Log.d(MyTag,“genTone:start”);
//转换为16位pcm声音阵列
//假设样本缓冲区已标准化。
int-idx=0;
对于(int i=0;i>>8);
val=(短)((amp2*32767));
generatedSnd[idx++]=(字节)(val&0x00ff);
生成的snd[idx++]=(字节)((val&0xff00)>>>8);
}
//Log.d(MyTag,“genTone:done”);
}

当我想的时候,我就把GenTone称为,我想输出两个DCs…

虽然这是一个普遍的问题(即,它可能根据给定设备的硬件设计而工作或不工作),但这里提到的时间间隔看起来更像是一个软件问题。事实上,再看看问题和代码,我认为你是对的。不过,我认为这是一个需要考虑的设计问题。这无疑是一个可移植性的问题,尽管可能是大多数移动耳机AMPS现在没有AC耦合(有时也会在同一条线路上调试串行通道-不确定它们是否通过AMP)。不过,这可能是一个可以解决的问题,也许可以通过使用交流输出和整流/滤波。我会考虑使用频率-电压转换器,并消除“体积”依赖性。或者甚至调制信号到一个简单的微控制器。@Bjorn从硬件的角度来看,我担心会出现这种情况:在音频上输出DC是没有意义的!然而,我的Galaxy Tab 2的音频似乎能够很好地将直流电保持在200欧姆的负载中(类似于一套耳机)。我看到的“光点”是1Hz,这是我每秒刷新设备手柄时所期望的频率。如果我增加缓冲区大小,我可以保持DC的时间越来越长。谢谢你回复我。@Chris,是的,频率是另一种可能性。输出将进入微控制器的ADC,如果我能做DC(我很高兴我能用我选择的设备做DC),微代码将变得更简单。非常感谢。如果你想连续播放,只要有一个带有循环的线程,它可以将中等大小的缓冲区写入audioTrack。如果您怀疑跳频,请尝试发送一个可听见的正弦波并收听(选择一个频率,以便在缓冲区中获得整数个周期,这样,如果缓冲处理得当,将不会出现故障)。您可能还想尝试使用audacity等程序从pc上录制。通过使用音频测试频率,您还可以将软件问题与可能的交流耦合的一般问题区分开来