问题描述
我的深化发展应用程序通过调频信号发送文本。基本上我给用户有机会写一文,并选择起始频率,最终的频率和对位的时间之间的时间转鼓分离和一些其他的选择发送。
I'm developping an application to send a text through chirp signals. Basically I give the user the chance to write a text, and select a start frequency, a final frequency and some other options about time separtion between and duration of the bits to be sent.
在应用程序,我分裂文本字符,将它们转换成ASCII整数,转换这些整数到二进制文件,然后用线性调频信号,给他们(大端),具有5ms的啁啾,从起始频率变为最终的频率(下往上)送1,并最终以起始频率。 (上往下)派0。
In the app I split the text into chars, convert them into ASCII integers, convert those integers into binaries and then send them with chirp signals (in Big Endian), with a 5ms chirp that goes from initial freq to final freq (down to up) to send 1, and from final to initial freq. (up to down) to send 0.
这很简单,它的工作,但$ P $后pssing发送按钮几次,它崩溃,我也得到了logcat的以下错误消息:
It's very simple and it's working, but after pressing the send button a few times, it crash, and I get the following error messages in the logcat:
07-08 15:09:58.036: E/AudioTrack(8747): AudioFlinger could not create track, status: -12
07-08 15:09:58.036: E/AudioTrack-JNI(8747): Error initializing AudioTrack
07-08 15:09:58.036: E/AudioTrack-Java(8747): [ android.media.AudioTrack ] Error code -20 when initializing AudioTrack.
07-08 15:09:58.044: W/dalvikvm(8747): threadid=13: thread exiting with uncaught exception (group=0x40f77930)
07-08 15:09:58.051: E/AndroidRuntime(8747): FATAL EXCEPTION: Thread-445
07-08 15:09:58.051: E/AndroidRuntime(8747): java.lang.IllegalStateException:play() called on uninitialized AudioTrack.
07-08 15:09:58.051: E/AndroidRuntime(8747): at android.media.AudioTrack.play(AudioTrack.java:883)
07-08 15:09:58.051: E/AndroidRuntime(8747): at android.nacho.UltraSoundSender.AudioDevice.<init>(AudioDevice.java:19)
07-08 15:09:58.051: E/AndroidRuntime(8747): at android.nacho.UltraSoundSender.ChirpGenerator.playDOWN(ChirpGenerator.java:104)
07-08 15:09:58.051: E/AndroidRuntime(8747): at android.nacho.UltraSoundSender.UltraSoundSender$1$1.run(UltraSoundSender.java:61)
07-08 15:09:58.051: E/AndroidRuntime(8747): at java.lang.Thread.run(Thread.java:856)
三codeS我使用的是以下几个方面:
The three codes I'm using are the followings:
1°
public class UltraSoundSender extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ultra_sound_sender);
Button btnCode = (Button) findViewById(R.id.btnCode);
btnCode.setOnClickListener(new OnClickListener() {
//@Override
public void onClick(View arg0) {
new Thread( new Runnable( )
{
public void run( )
{
String word= ((EditText)findViewById(R.id.Line)).getText().toString();
int IniFreq=Integer.parseInt(((EditText)findViewById(R.id.IniFreq)).getText().toString());
int FinFreq=Integer.parseInt(((EditText)findViewById(R.id.FinFreq)).getText().toString());
int bitLength=Integer.parseInt(((EditText)findViewById(R.id.bitLength)).getText().toString());
int bitGap=Integer.parseInt(((EditText)findViewById(R.id.bitGap)).getText().toString());
Integer digits[]= new Integer[64];
int NumChar= word.length();
//This split the string in chars
for(int i = 0; i < NumChar ; i++){
digits[i]=(int)word.charAt(i);
}
double impulseDuration = 250; //not negotiable
int Delay=(int) (bitGap-((int)impulseDuration*0.8));
for(int IndexChar= 0; IndexChar< NumChar ; IndexChar++)
{
new ChirpGenerator().playDOWN(IniFreq*1000, FinFreq*1000, impulseDuration, digits[IndexChar], bitLength );
try {
Thread.sleep(Delay); //Time diference since whe generate one bit and the next one
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Thread.currentThread().interrupt();
// enableButton(true);
}
} ).start();
}
});
}
//Enable/disable button
private void enableButton(boolean isEnable)
{
((Button)findViewById(R.id.btnCode)).setEnabled(isEnable);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_ultra_sound_sender, menu);
return true;
}
}
2°
package android.nacho.UltraSoundSender;
public class ChirpGenerator {
private AudioDevice device;
public ChirpGenerator() {
device = new AudioDevice( );
}
/**
*
* @param initialFreq in Hz
* @param finalFreq in Hz
* @param impulseDuration in ms
*/
void playDOWN(int initialFreq, int finalFreq, double impulseDuration, int Code, int LengthBit) {
AudioDevice device = new AudioDevice( );
//int LengthBit=6; //In milliseconds
int LengthBitInSamples = LengthBit*44; //That would means every bit is 5 millisecs length
int NumberOfBits= 8;
int LimitOfInterestingSamples=NumberOfBits*LengthBitInSamples;
double k = (double)(finalFreq - initialFreq) / (LengthBit/1000.0); //This should be the corret one, but works better with 5 milliseconds
float samples[] = new float[1024];
double currentFreq = finalFreq; //Because it goes from up to down
double phase;
double t;
int j = 0;
int CountBits = 0;
int IndexBit=1;
Integer digits[]= new Integer[64];
//int Code = 45;
for(int n=NumberOfBits, m=1; n>0; m++, n--) //To ID from 0 to 7 -> just 8 devices in the network
{
digits[m]=Code%2;
Code/=2;
System.out.println("Valor de digits"+digits[m]);
}
for (int i = 0; i < (int)(impulseDuration/1000.0 * AudioDevice.SAMPLING_RATE); i++, CountBits++) {
if(i>LimitOfInterestingSamples)
{
samples[j++] = 0;
}
else{
if(CountBits>LengthBitInSamples)
{
CountBits=0;
if(IndexBit<NumberOfBits)
IndexBit++;
}
if(digits[IndexBit]==1) //This means 1
{
t = (double)CountBits / (double)AudioDevice.SAMPLING_RATE;
currentFreq = initialFreq + 0.5 * k * t;
phase = 2.0 * Math.PI * (currentFreq) * t;
}
else{ //This means 0
t = (double)CountBits / (double)AudioDevice.SAMPLING_RATE;
currentFreq = finalFreq - 0.5 * k * t;
phase = 2.0 * Math.PI * (currentFreq) * t;
}
samples[j++] = (float)Math.sin(phase);
}
if (j == 1024) {
device.writeSamples( samples );
j = 0;
}
}//for
}
}
3°
package android.nacho.UltraSoundSender;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
public class AudioDevice
{
public static final int SAMPLING_RATE = 44100; //44100;
AudioTrack track;
short[] buffer = new short[1024];
public AudioDevice( )
{
int minSize =AudioTrack.getMinBufferSize( SAMPLING_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT );
track = new AudioTrack( AudioManager.STREAM_MUSIC, SAMPLING_RATE,
AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
minSize, AudioTrack.MODE_STREAM);
track.play();
int nativeSampleRate = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
int sampleRate = track.getSampleRate();
}
public void writeSamples(float[] samples)
{
fillBuffer( samples );
track.write( buffer, 0, samples.length );
}
private void fillBuffer( float[] samples )
{
if( buffer.length < samples.length )
buffer = new short[samples.length];
for( int i = 0; i < samples.length; i++ )
buffer[i] = (short)Math.round(samples[i] * (float)Short.MAX_VALUE);
}
}
谁能告诉我,为什么应用程序崩溃时,我执行了几次?
谢谢
Can anyone tell me why the App crash when I execute it a few times??Thanks
推荐答案
好像你当你用它做的不是关闭您的AudioTrack实例。当你做的鸣叫,你应该关闭并注销您的audioTrack的实例。
it seems like you're not closing your AudioTrack instance when you're done using it. When you're done chirping, you should close and nullify your instance of audioTrack.
这篇关于生成音频后,Android应用程序崩溃信号几次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!