2015-09-13 2 views
1

Je crée des sons dans mon programme Java. Il existe donc un certain nombre de modules d'oscillateurs qui produisent les échantillons dont j'ai besoin pour pouvoir jouer plus d'une tonalité à la fois. Ces échantillons sont ajoutés et joués. Si je sélectionne une faible amplitude, par ex. 100, tout fonctionne très bien (normalisée dans Audacity):Java - Générer des sons avec des amplitudes différentes donne des tons différents

Sinus

Mais si je sélectionne une amplitude supérieure, dans ce cas Short.MAX_VALUE, le ton créé ressemble et sonne étrange:

Sinus2

Les échantillons sont créés ici (source: http://www.wolinlabs.com/blog/java.sine.wave.html):

short value; 
    if (type == TYPE_SINE) 
    { 
     cycleIncrease = frequency/parent.getSamplingRate(); 
     value = (short) (amplitude * Math.sin(2 * Math.PI * cyclePosition)); 
     cyclePosition += cycleIncrease; 
     if (cyclePosition > 1) 
      cyclePosition -= 1; 
     return value; 
    } 

Avec sa ondes wtooth j'ai le même problème:

else if (type == TYPE_SAW) 
    { 
     cycleIncrease = frequency/parent.getSamplingRate(); 
     double doubleValue = cyclePosition - Math.floor(cyclePosition); 
     cyclePosition += cycleIncrease; 
     value = (short) (amplitude * doubleValue); 
     if (cyclePosition > 1) 
      cyclePosition -= 1; 
     return value; 
    } 

amplitude a la valeur je l'ai mentionné ci-dessus, donc dans ces deux cas 100 et Short.MAX_VALUE.

Les échantillons sont additionnés de cette façon, où sum est l'échantillon de sortie et value est l'échantillon calculé (0 si aucune tonalité est jouée):

int n = 0; 
    int sum = 0; 

    for (Wire inputWire:inputWires) 
    { 
     short value = inputWire.getNextSample(); 
     if (value != 0) 
     { 
      n += 1; 
     } 
     sum += value; 
     x++; 
    } 

    if (n != 0) 
     sum = sum/n; 

J'ai aussi assuré qu'il ya juste la un échantillon d'un oscillateur si un seul son est joué, donc sum = value. Mais je ne comprends pas pourquoi différentes tonalités sont créées pour des amplitudes différentes avec le même code, alors pourquoi cela se passe-t-il?

J'ai aussi une deuxième question: Si je termine la lecture d'un sinusoïde avec une faible amplitude, je peux entendre un bruit court, qui ressemble à ceci:

noise

D'où vient et comment puis-je le réparer?

Nous vous remercions de votre aide!

Répondre

1

Question 1:

Il semble que vous pouvez envelopper la forme d'onde:

if (cyclePosition > 1) 
    cyclePosition -= 1; // You are reducing the amplitude by half? (goes from 1 to -1) 

C'est là une coupure devrait se produire:

// For example... 
if (cyclePosition > 1) 
    cyclePosition = 1 
if (cyclePosition < -1) 
    cyclePosition = -1 

L'audio peut sembler mauvais, mais c'est ce qui arrive normalement quand l'Amplitude est trop grande.

Peut-être essayer d'échelle l'amplitude pour tenir toujours dans des limites:

scale = 1/highestAmplitude; 
foreach (point in wavePoints) 
{ 
    point *= scale; 
} 
// or something similar 

Question 2:

Assurez-vous que la fin onde sinusoïdale à 0 Amplitude

1

Vérifiez que le sampleSizeInBits de votre AudioFormat comports avec votre choisi amplitude. Si ce n'est pas le cas, vous pouvez constater un effet "wrap-around" lors de la multiplication par amplitude. Pour référence, ce example met à l'échelle la taille de l'échantillon à huit bits représentant une valeur d'octet signée dans la plage -128..127.

AudioFormat af = new AudioFormat(Note.SAMPLE_RATE, 8, 1, true, true); 
… 
sin[i] = (byte)(Math.sin(angle) * 127f);