Je travaille avec Android, essayant de faire en sorte que mon application AudioTrack joue un fichier Windows .wav (Tada.wav). Franchement, ça ne devrait pas être si difficile, mais j'entends beaucoup de choses étranges. Le fichier est enregistré sur la mini carte SD de mon téléphone et la lecture du contenu ne semble pas poser de problème, mais lorsque je lis le fichier (avec les paramètres, je ne suis que TRÈS SUR), je reçois quelques secondes de bruit blanc. avant que le son semble se résoudre en quelque chose qui peut être juste.
J'ai enregistré et reproduit avec succès ma propre voix au téléphone. J'ai créé un fichier .pcm conformément aux instructions données dans cet exemple:
http://emeadev.blogspot.com/2009/09/raw-audio-manipulation-in-Android.html
(sans le masquage en arrière) ...
Quelqu'un a-t-il des suggestions ou une connaissance d'un exemple sur le Web pour lire un fichier .wav sur un Android?
Merci, R.
Je suis tombé sur la réponse (franchement, en essayant & ^ @! Je ne pensais pas que cela fonctionnerait), au cas où quelqu'un serait intéressé ... Dans mon code d'origine (dérivé de l'exemple du lien dans le message d'origine), les données sont lues à partir du fichier comme suit:
InputStream is = new FileInputStream (file);
BufferedInputStream bis = new BufferedInputStream (is, 8000);
DataInputStream dis = new DataInputStream (bis); // Create a DataInputStream to read the audio data from the saved file
int i = 0; // Read the file into the "music" array
while (dis.available() > 0)
{
music[i] = dis.readShort(); // This assignment does not reverse the order
i++;
}
dis.close(); // Close the input stream
Dans cette version, music [] est un tableau de SHORTS. Donc, la méthode readShort () semble avoir un sens ici, puisque les données sont en PCM 16 bits ... Cependant, sur Android, cela semble être le problème. J'ai changé ce code comme suit:
music=new byte[(int) file.length()];//size & length of the file
InputStream is = new FileInputStream (file);
BufferedInputStream bis = new BufferedInputStream (is, 8000);
DataInputStream dis = new DataInputStream (bis); // Create a DataInputStream to read the audio data from the saved file
int i = 0; // Read the file into the "music" array
while (dis.available() > 0)
{
music[i] = dis.readByte(); // This assignment does not reverse the order
i++;
}
dis.close(); // Close the input stream
Dans cette version, music [] est un tableau de BYTES. Je dis toujours à AudioTrack que ce sont des données PCM 16 bits, et mon Android ne semble pas avoir de problème pour écrire un tableau d'octets dans un AudioTrack ainsi configuré ... Quoi qu'il en soit, ça sonne bien, alors les autres veulent jouer des sons Windows sur leur Android, pour une raison quelconque, c'est la solution. Ah, Endianness ......
R.
J'ai trouvé beaucoup de réponses longues à cette question. Ma solution finale, qui compte tenu de tout le copier-coller, n’est guère mienne, se résume à:
public boolean play() {
int i = 0;
byte[] music = null;
InputStream is = mContext.getResources().openRawResource(R.raw.noise);
at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
minBufferSize, AudioTrack.MODE_STREAM);
try{
music = new byte[512];
at.play();
while((i = is.read(music)) != -1)
at.write(music, 0, i);
} catch (IOException e) {
e.printStackTrace();
}
at.stop();
at.release();
return STOPPED;
}
STOPPED est juste un "vrai" renvoyé comme un signal pour réinitialiser le bouton pause/lecture. Et dans l'initialiseur de classe:
public Mp3Track(Context context) {
mContext = context;
minBufferSize = AudioTrack.getMinBufferSize(44100,
AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
}
Le contexte est juste "ceci" dans l'activité d'appel. Vous pouvez utiliser un FileInputStream sur la carte SD, etc. Mes fichiers sont en res/raw
Sautez-vous les 44 premiers octets du fichier avant de vider le reste des données du fichier dans la mémoire tampon? Les 44 premiers octets constituent l'en-tête WAVE et ils ressemblent à du bruit aléatoire si vous essayez de les lire.
Aussi, êtes-vous sûr de créer AudioTrack avec les mêmes propriétés que le WAVE que vous essayez de jouer (taux d'échantillonnage, débit binaire, nombre de canaux, etc.)? Windows vous fournit effectivement ces informations dans la page Propriétés du fichier:
Comme dit par Aaron C , vous devez sauter les 44 octets initiaux ou (comme je le préfère) lire les 44 premiers octets qui sont l’en-tête WAVE. De cette façon, vous savez combien de canaux, de bits par échantillon, de longueur, etc. le WAVE contient.
Ici vous pouvez trouver une bonne implémentation d’un analyseur/rédacteur d’en-tête WAVE.
S'il vous plaît ne perpétuez pas de code d'analyse terrible. L’analyse WAV est simple à implémenter http://soundfile.sapp.org/doc/WaveFormat/ Et vous vous en remercierez en analysant des éléments tels que le taux d’échantillonnage , la profondeur de bits et le nombre de canaux.
De plus, x86 et ARM (au moins par défaut) sont tous deux de petite taille, de sorte que les fichiers WAV natifs doivent être corrects, sans aucune réorganisation.
Exemple de fichier wav:
http://www.mauvecloud.net/sounds/pcm1644m.wav
Exemple de code:
public class AudioTrackPlayer {
Context mContext;
int minBufferSize;
AudioTrack at;
boolean STOPPED;
public AudioTrackPlayer(Context context) {
Log.d("------","init");
mContext = context;
minBufferSize = AudioTrack.getMinBufferSize(44100,
AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
}
public boolean play() {
Log.d("------","play");
int i = 0;
byte[] music = null;
InputStream is = mContext.getResources().openRawResource(R.raw.pcm1644m);
at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
minBufferSize, AudioTrack.MODE_STREAM);
try {
music = new byte[512];
at.play();
while ((i = is.read(music)) != -1)
at.write(music, 0, i);
} catch (IOException e) {
e.printStackTrace();
}
at.stop();
at.release();
return STOPPED;
}
}