Android: Génération d'onde sinusoïdale
Je suis en train d'utiliser AudioTrack pour générer des signaux sinusoïdaux, carrés, et les vagues en dents de scie. Cependant, l'audio c'est la création ne ressemble pas à une onde sinusoïdale pure, mais comme il a une sorte de d'autres vagues superposées. Comment puis-je obtenir le pure d'onde sinusoïdale comme dans le deuxième exemple de code, en utilisant la méthode dans mon premier exemple? Depuis le haut exemple ne se déplace autour de l'arithmétique utilisée dans la deuxième, ne devraient-ils pas produire à l'identique de l'onde?
@Override
protected Void doInBackground(Void... foo) {
short[] buffer = new short[1024];
this.track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
float samples[] = new float[1024];
this.track.play();
while (true) {
for (int i = 0; i < samples.length; i++) {
samples[i] = (float) Math.sin( (float)i * ((float)(2*Math.PI) * frequency / 44100)); //the part that makes this a sine wave....
buffer[i] = (short) (samples[i] * Short.MAX_VALUE);
}
this.track.write( buffer, 0, samples.length ); //write to the audio buffer.... and start all over again!
}
}
Remarque: Cela ne donne-moi une onde sinusoïdale pure:
@Override
protected Void doInBackground(Void... foo) {
short[] buffer = new short[1024];
this.track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
float increment = (float)(2*Math.PI) * frequency / 44100; //angular increment for each sample
float angle = 0;
float samples[] = new float[1024];
this.track.play();
while (true) {
for (int i = 0; i < samples.length; i++) {
samples[i] = (float) Math.sin(angle); //the part that makes this a sine wave....
buffer[i] = (short) (samples[i] * Short.MAX_VALUE);
angle += increment;
}
this.track.write( buffer, 0, samples.length ); //write to the audio buffer.... and start all over again!
}
}
Grâce à Martijn: Le problème est que l'onde est se couper entre les longueurs d'onde dans la mémoire tampon. L'augmentation de la taille de la mémoire tampon permet de résoudre le problème dans le deuxième exemple. Il semble que les Mathématiques.PI * 2 arithmétique a été la plus intense de la boucle, donc le déplacement d'une valeur à une variable externe qui est calculé uniquement une fois résout tout.
source d'informationauteur K. Barresi
Vous devez vous connecter pour publier un commentaire.
Essayer d'optimiser votre code par
Pourquoi? Parce que je soupçonne de la mémoire tampon à la prise à long à préparer, ce qui provoque un décalage entre les deux tampon pousse de gros, ce qui pourrait être à l'origine du bruit.
La seule différence que je peux voir dans tes deux exemples de code, c'est que l'équation dans votre premier exemple contient un entier (
I
), et, par conséquent, vous êtes certainement entier (pas de virgule flottante) de l'arithmétique. Ce serait la cause d'une staircasing effet, l'ajout d'harmoniques indésirables à votre forme d'onde.Je pense que si vous avez tout simplement jeté
I
à flotter dans votre équation, il va produire une onde sinusoïdale pure.Aucun de ces anwers résout le problème. La longueur de la mémoire tampon doit être un multiple de la fréquence d'échantillonnage, ou au moins la durée d'une rotation. Nous allons casser des tonnes de variables pour montrer que nous comprenons les choses:
Alors vous pouvez multiplier cette
bytesPerRotation
par quoi que ce soit, il ne changera pas d'un fait: il n'y aura pas de glitch dans le son.