(using JS)
My English is bad but I’ll try,
I’m doing a small development on Android, I want to record the sounds of my scene and save it to “WAV”
and for this I took the code from this person: gregzo.
#pragma strict
import System.IO; // for FileStream
import System; // for BitConverter and Byte Type
private var bufferSize : int;
private var numBuffers : int;
private var outputRate : int = 44100;
private var fileName : String = "recTest.wav";
private var headerSize : int = 44; //default for uncompressed wav
private var recOutput : boolean;
private var fileStream : FileStream;
function Awake()
{
AudioSettings.outputSampleRate = outputRate;
}
function Start()
{
AudioSettings.GetDSPBufferSize(bufferSize,numBuffers);
}
function Update()
{
if(Input.GetKeyDown("r"))
{
print("rec");
if(recOutput == false)
{
StartWriting(fileName);
recOutput = true;
}
else
{
recOutput = false;
WriteHeader();
print("rec stop");
}
}
}
function StartWriting(name : String)
{
fileStream = new FileStream(name, FileMode.Create);
var emptyByte : byte = new byte();
for(var i : int = 0; i<headerSize; i++) //preparing the header
{
fileStream.WriteByte(emptyByte);
}
}
function OnAudioFilterRead(data : float[], channels : int)
{
if(recOutput)
{
ConvertAndWrite(data); //audio data is interlaced
}
}
function ConvertAndWrite(dataSource : float[])
{
var intData : Int16[] = new Int16[dataSource.length];
//converting in 2 steps : float[] to Int16[], //then Int16[] to Byte[]
var bytesData : Byte[] = new Byte[dataSource.length*2];
//bytesData array is twice the size of
//dataSource array because a float converted in Int16 is 2 bytes.
var rescaleFactor : int = 32767; //to convert float to Int16
for (var i : int = 0; i<dataSource.length;i++)
{
intData[i] = dataSource[i]*rescaleFactor;
var byteArr : Byte[] = new Byte[2];
byteArr = BitConverter.GetBytes(intData[i]);
byteArr.CopyTo(bytesData,i*2);
}
fileStream.Write(bytesData,0,bytesData.length);
}
function WriteHeader()
{
fileStream.Seek(0,SeekOrigin.Begin);
var riff : Byte[] = System.Text.Encoding.UTF8.GetBytes("RIFF");
fileStream.Write(riff,0,4);
var chunkSize : Byte[] = BitConverter.GetBytes(fileStream.Length-8);
fileStream.Write(chunkSize,0,4);
var wave : Byte[] = System.Text.Encoding.UTF8.GetBytes("WAVE");
fileStream.Write(wave,0,4);
var fmt : Byte[] = System.Text.Encoding.UTF8.GetBytes("fmt ");
fileStream.Write(fmt,0,4);
var subChunk1 : Byte[] = BitConverter.GetBytes(16);
fileStream.Write(subChunk1,0,4);
var two : UInt16 = 2;
var one : UInt16 = 1;
var audioFormat : Byte[] = BitConverter.GetBytes(one);
fileStream.Write(audioFormat,0,2);
var numChannels : Byte[] = BitConverter.GetBytes(two);
fileStream.Write(numChannels,0,2);
var sampleRate : Byte[] = BitConverter.GetBytes(outputRate);
fileStream.Write(sampleRate,0,4);
var byteRate : Byte[] = BitConverter.GetBytes(outputRate*4);
// sampleRate * bytesPerSample*number of channels, here 44100*2*2
fileStream.Write(byteRate,0,4);
var four : UInt16 = 4;
var blockAlign : Byte[] = BitConverter.GetBytes(four);
fileStream.Write(blockAlign,0,2);
var sixteen : UInt16 = 16;
var bitsPerSample : Byte[] = BitConverter.GetBytes(sixteen);
fileStream.Write(bitsPerSample,0,2);
var dataString : Byte[] = System.Text.Encoding.UTF8.GetBytes("data");
fileStream.Write(dataString,0,4);
var subChunk2 : Byte[] = BitConverter.GetBytes(fileStream.Length-headerSize);
fileStream.Write(subChunk2,0,4);
fileStream.Close();
}
And I put it in “Android” but the recording sounds very fast and sharp.
The problem is that the sample rate is 44.1Khz in the PC and in my Andorid device is 24kHz.
Then I have to change the value of outputRate:
private var outputRate: int = 44100;
as follows:
private var outputRate: int = 24000;
Besides that I had to make other changes to make to save the WAV file and want to share with you:
1. Set the permission on the “AndroidManifest.xml” to create files in the device memory,
this is done with the following configuration:
Player Settings>Android>Configuration>Write Access>External (SDCard)
2. Change line:
[I]fileStream = new FileStream(name, FileMode.Create);[/I]
And put it this way:
[I]fileStream = FileStream(Application.persistentDataPath + "/" + name,FileMode.Create);[/I]
Here I find my WAV file:
/storage/sdcard0/Android/data/com.company.MyApp/files/recTest.wav
3. Delete this update function:
function Update()
{
if(Input.GetKeyDown("r"))
{
print("rec");
if(recOutput == false)
{
StartWriting(fileName);
recOutput = true;
}
else
{
recOutput = false;
WriteHeader();
print("rec stop");
}
}
}
And replace it with this function OnGUI:
function OnGUI()
{
if(GUI.Button(new Rect(10, 10, 150, 100), NameButton))
{
if(recOutput == false)
{
StartWriting(fileName);
recOutput = true;
print("rec");
NameButton= "Stop";
}
else
{
recOutput = false;
WriteHeader();
print("rec stop");
NameButton= "finished";
}
}
}
Thank you very much to gregzo for sharing your code and solve my problem of sample rate ![]()
![]()
![]()