2016-02-24 4 views
0

Je fais une application audio sur Android et j'ai une génération simple de trois types d'ondes sonores - Sine, Sawtooth et Square.Générer du son sur Android avec OpenSL ES

La génération d'ondes est correcte. J'ai imprimé le résultat et ça a l'air bien. Mais le son est bizarre. Voici ce que j'ai enregistré. Il en est de même pour la dent de scie et le carré, mais quand je joue avec un A en dents de scie, le son est normal.

Est-ce que quelqu'un sait ce qui ne va pas? Si j'augmenter la taille du tampon, puis est plus longue, mais toujours le même problème

code pour générer une onde sinusoïdale:

play(JNIEnv* env, jclass clazz, jint which, jint count, jdouble freqOfTone) 
{ 
    unsigned i; 
    int j = 0; 
    double sampleRate = SAMPLERATE/freqOfTone; 
    switch (which) { 
case SINE: 
     for (i = 0; i < TONE_FRAMES; ++i) { 
      toneBuffer[i] = sin(2.0*M_PI * i/sampleRate) * 32768;     
     } 
     nextBuffer = createResampledBuf(SINE, SL_SAMPLINGRATE_8, &nextSize); 
     if(!nextBuffer) { 
      nextBuffer = (short*) toneBuffer; 
      nextSize = sizeof(toneBuffer); 
     } 
     break; 
    } 
    nextCount = count; 
    if (nextSize > 0) { 
     SLresult result; 
     result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize); 
     if (SL_RESULT_SUCCESS != result) { 
      bqPlayerRecorderBusy = 1; 
      return JNI_FALSE; 
     } 
    } 

    return JNI_TRUE; 
} 

Répondre

0

Vous n'êtes pas imprimer quoi que ce soit tout en générant la vague?

Mais aussi le problème principal est votre boucle de synthèse. Je vais deviner les clics que vous entendez est parce que vous sauter des échantillons (vous incrémenter i deux fois, dans votre boucle et dans votre bloc de synthèse Il devrait être cela pour éviter les clics:.

for (i = 0; i < SIZE_OF_BUFFER; i++) { 
     toneBuffer[i] = sin(2.0*M_PI * i/(44100/freqOfTone)) * 32768; 
} 

Mais Je vous recommande de travailler avec des phases, pour moi, il fait juste plus de sens dans un processus de traitement du signal

float generateSineWave(float freq) { 
    // Get phase, then get sample 
    phase = 2 * M_PI * freq/44100 + prev_phase; 
    sample = sin(phase); 

    // wrap phase 
    if (phase > (2 * M_PI)) phase -= (2 * M_PI); 

    prev_phase = phase 

    return sample; 
} 

void yourSynthesisLoop() { 
    for (int i = 0; i < SIZE_OF_BUFFER; i++) { 
     toneBuffer[i] = generateSineWave(freqOfTone) * 32768; 
    } 
} 
+0

Je l'ai copié mal avec cette double incrémentation, désolé .. J'ai utilisé votre code et encore il clique .. mais certains tons l'ont plus calme. Je vais poster plus de code dans le premier post – Syntey

+0

@Syntey hm J'ai cela en cours d'exécution dans mon code et je n'ai aucun clic, comment installez-vous opensl dans votre code? Est-ce que ça sonne toujours exactement pareil? Et encore une fois si vous imprimez quoi que ce soit (ou n'importe quel processus en cours) pendant qu'il génère la forme d'onde, vous obtiendrez des clics car ces fonctions ralentiront votre bloc de génération de forme d'onde. AUSSI - assurez-vous d'initialiser prev_phase à 0 et comme une variable statique, vous pouvez obtenir des clics si ceux-ci ne sont pas configurés correctement –

+0

J'utilise un projet audio natif et j'ai récemment édité le premier post, où j'ai toute la fonction. Oui, je l'ai initialisé à 0 – Syntey

0

Essayez d'utiliser à court type de données au lieu de deux à partir du noyau. OpenSLEL il se transforme en court, donc il y a de toute façon peut être la perte de données ou le bruit ajouté.Pour une bonne qualité également utiliser un taux d'échantillonnage plus élevé