Xenion schreef:Hier vraag je om een byte-array naar een wav-file te schrijven, maar ik zie nergens de specificatie voor stereo 16bit. Het zou goed kunnen, dat je library die byte-array heeft geïnterpreteerd als een mono 8bit en dat zou wel eens funky kunnen klinken.
Hieronder de code waarmee ik het WAV bestand maak (verborgen inhoud). Ik heb de header aangepast naar 16bit dus daar lijkt het probleem niet te zitten
-
Spoiler: [+]
Code: Selecteer alles
public static void createFile(byte[] data, String filepath){
byte[] total = new byte[data.length+44];
byte[] header =wavHeader(data.length);
for(int i=0;i<44;i++){
total[i]=header[i];
}
for(int i=0;i<data.length;i++){
total[i+44]=data[i];
}
try{
FileOutputStream file = new FileOutputStream(filepath);
file.write(total);
file.close();
}catch(IOException e){
System.out.println("Failed to create audio file");
System.out.println("Check if the fail isn't opened elsewhere.");
}
}
public static byte[] wavHeader(long datasize){ //Alle getallen zijn little-endian, woorden big-endian.
byte[] chunkSize=longToByteArray(datasize+36); //De methodes long-int ToByteArray returnen dus little-endian arrays.
byte[] subchunk1Size=longToByteArray(16); //De bits in de bytes zelf zijn big-endian.
byte[] sampleRate=longToByteArray(44100); //
byte[] byteRate=longToByteArray(176400); //
byte[] subchunk2Size=longToByteArray(datasize); //
byte[] formatType=intToByteArray(1); //1=pcm,6=mulaw,7=alaw
byte[] numChannels=intToByteArray(2); //
byte[] blockAlign=intToByteArray(4); //(bitsPerSample*numChannels)/8
byte[] bitsPerSample=intToByteArray(16);
byte[] header= new byte[44];
header[0]='R';
header[1]='I';
header[2]='F';
header[3]='F';
header[4]=chunkSize[0];
header[5]=chunkSize[1];
header[6]=chunkSize[2];
header[7]=chunkSize[3];
header[8]='W';
header[9]='A';
header[10]='V';
header[11]='E';
header[12]='f';
header[13]='m';
header[14]='t';
header[15]=' ';
header[16]=subchunk1Size[0];
header[17]=subchunk1Size[1];
header[18]=subchunk1Size[2];
header[19]=subchunk1Size[3];
header[20]=formatType[0];
header[21]=formatType[1];
header[22]=numChannels[0];
header[23]=numChannels[1];
header[24]=sampleRate[0];
header[25]=sampleRate[1];
header[26]=sampleRate[2];
header[27]=sampleRate[3];
header[28]=byteRate[0];
header[29]=byteRate[1];
header[30]=byteRate[2];
header[31]=byteRate[3];
header[32]=blockAlign[0];
header[33]=blockAlign[1];
header[34]=bitsPerSample[0];
header[35]=bitsPerSample[1];
header[36]='d';
header[37]='a';
header[38]='t';
header[39]='a';
header[40]=subchunk2Size[0];
header[41]=subchunk2Size[1];
header[42]=subchunk2Size[2];
header[43]=subchunk2Size[3];
return header;
}
Xenion schreef:Kijk eens met een extern programma (MATLAB, Audacity, ...) naar de gegenereerde wav file.
Goeie tip! Met behulp van Audacity krijg ik volgende golf:
- sinus16bit 876 keer bekeken
Twee kanalen, frequentie is goed maar de golf duidelijk verkeerd, is de data van 16 bit wav signed? Want nu heb ik het unsigned geprogrammeerd, daar zit de fout misschien.
Wel raar dat de 8bit golf dan, op dezelfde wijze gemaakt, wél mooi klopt:
- sine8bit 876 keer bekeken
Of ligt het ergens anders aan?
EDIT:
Verder zou ik ook het interleaven van de twee kanalen iets properder aanpakken. Zorg dat je de twee kanalen als aparte lijsten hebt en schrijf dan een functie om ze te interleaven en de-interleaven.
Zou er inderdaad beter uitzien maar gaat de code dan niet twee keer zo traag gaan (twee keer zoveel assignaties)? Ik wil het ook relatief snel laten lopen op mijn kleine laptop en die is wat traag.
Je leest maar niet verder want je, je voelt het begin van wanhoop.