2010-04-25 5 views
8

Je tente de porter une application qui lit les fichiers musicaux de chiptunes (NSF, SPC, etc.) de Java SE vers Android. L'API Android semble manquer des classes multimédias javax que cette application utilise pour produire du son PCM brut. L'analogue le plus proche que j'ai trouvé dans l'API est AudioTrack et j'ai donc lutté avec ça. Cependant, lorsque j'essaie d'exécuter un de mes fichiers musicaux sur mon port en cours, tout ce que je récupère est statique. Mon soupçon est que c'est l'AudioTrack que j'ai configuré qui est en faute. J'ai essayé plusieurs constructeurs différents, mais tout produit simplement statique à la fin.Difficulté à porter le code de sortie PCM brut de Java vers Android AudioTrack API

La configuration Dataline dans le code original est quelque chose comme:

AudioFormat audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
       44100, 16, 2, 4, 44100, true); 
DataLine.Info lineInfo = new DataLine.Info(SourceDataLine.class, audioFormat); 
DataLine line = (SourceDataLine)AudioSystem.getLine(lineInfo); 

Le constructeur J'utilise est en ce moment:

AudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
     44100, 
     AudioFormat.CHANNEL_CONFIGURATION_STEREO, 
     AudioFormat.ENCODING_PCM_16BIT, 
     AudioTrack.getMinBufferSize(44100, 
       AudioFormat.CHANNEL_CONFIGURATION_STEREO, 
       AudioFormat.ENCODING_PCM_16BIT), 
     AudioTrack.MODE_STREAM); 

J'ai remplacé les constantes et les variables dans les afin qu'ils J'ai l'intention de donner un sens aussi concis que possible, mais ma question fondamentale est de savoir s'il y a des problèmes évidents dans les hypothèses que j'ai faites lorsque je passe d'un format à l'autre.

+0

Même si vous devenez statique, avez-vous vérifié si la longueur de la piste est correcte? – nvuono

+0

Les fichiers musicaux en question n'ont pas vraiment de longueur de piste définitive. C'est-à-dire, ils sont sous la forme de code pour un DSP qui continue à jouer une boucle jusqu'à ce qu'on leur dise d'arrêter. – alexanderfb

Répondre

7

J'ai donc eu un peu de temps pour approfondir cette question aujourd'hui, et je pense que je l'ai clouée. La déclaration AudioFormat dans le premier exemple de code ci-dessus a le paramètre big endian défini sur "true", mais l'AudioTrack Android s'attend à ce que les données PCM soient au format little endian.

J'ai donc écrit une petite boucle rapide pour tester mon intuition comme ceci:

for(int i = 0; i + LEN_PCM_SAMPLE_BYTES < LEN_PCM_BUFFER; i += LEN_PCM_SAMPLE_BYTES) { 
    // Really rude endian conversion. 
    byte bytTemp = a_bytBuffer[i]; 
    a_bytBuffer[i] = a_bytBuffer[i + 1]; 
    a_bytBuffer[i + 1] = bytTemp; 
} 

Fondamentalement, cette boucle flips les octets de chaque (16 bits) échantillon dans le tampon. Cela fonctionne très bien, sauf que c'est un peu saccadé car c'est terriblement inefficace. J'ai essayé d'utiliser un ByteBuffer mais cela ne semble pas renverser les octets dans les échantillons individuels.

Je vais trouver quelque chose d'encore mieux à l'avenir, mais le problème de base ici est résolu. J'espère que quelqu'un d'autre trouve cela utile!

+0

Étiez-vous capable de comprendre quelque chose pour le clapot? – StackOverflowed

Questions connexes