How can I save a byte array of audio data using NAudio? - c#

I have a byte array of audio data that is supposedly in 8-bit uLaw format. However, when I try and save it to a wav file, the file is just static. Below is how I am trying to save the byte array. What am I doing wrong?
var ulawFormat = WaveFormat.CreateMuLawFormat(8000, 1);
using (WaveFileWriter w=new WaveFileWriter(AssemblyDirectory + #"\..\..\..\TestAudio\output.wav", ulawFormat))
{
foreach(var kwa in knownWorkingAudio)
{
byte[] data = kwa.Value;
w.Write(data, 0, data.Length);
}
w.Flush();
}

The code sample looks correct. I suspect the audio is not in the format you think its in.

Related

Convert mp4 file to byte array and string

I working on project to upload files into firebase real-time database using firesharp in WinForm c#.
I searched a lot to understand how to do this.
I know about the option to write File.ReadAllBytes(), but I want to run the app on weak PC, with 4 GB ram, and he is very slow.
I succeeded to upload an image, it's work good.
I find something about Stram option, but I don't know how to do it with converting to String.
Sorry about my English.
You can convert the file to binary, and the binary can be saved as arrays and strings.
//Read file to byte array
FileStream stream = File.OpenRead(#"c:\path\to\your\file\here.txt");
byte[] fileBytes= new byte[stream.Length];
stream.Read(fileBytes, 0, fileBytes.Length);
stream.Close();
//Begins the process of writing the byte array back to a file
using (Stream file = File.OpenWrite(#"c:\path\to\your\file\here.txt"))
{
file.Write(fileBytes, 0, fileBytes.Length);
}
https://www.codeproject.com/Questions/636646/Csharp-file-to-Byte-Array-and-Byte-Array-to-File
FileStream st = new FileStream(#"C:\2.jpg", FileMode.Open);
byte[] buffer = new byte[st.Length];
st.Read(buffer, 0, (int)st.Length);
st.Close();
Console.ReadLine();
https://social.msdn.microsoft.com/Forums/en-US/648bd8b2-74ec-4054-9c68-68190b600971/how-to-convert-a-file-to-binary?forum=csharplanguage

Byte array read from a file and byte array converted from string read from same file differs

If i read byte array from a file and write it using below code
byte[] bytes = File.ReadAllBytes(filePath);
File.WriteAllBytes(filePath, byteArr);
works perfectly fine.I can open and view the written file properly.
But if i read file contents into a string and then convert it to byte array using below function
string s = File.ReadAllText(filePath);
var byteArr = System.Text.Encoding.UTF8.GetBytes(s);
the size of byte array is more than the previous array read directly from file and the values are also different, hence if i write the file using this array the cannot be read when opened
Note:- File is utf-8 encoded
i found out that using below code
using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8, true))
{
reader.Peek(); // you need this!
var encoding = reader.CurrentEncoding;
}
Unable to understand why both the array differs??
I was using the below attached image for converting and then writing
With
using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8, true))
{
reader.Peek(); // you need this!
var encoding = reader.CurrentEncoding;
}
your var encoding will just echo the Encoding.UTF8 parameter. You are deceiving yourself there.
A binary file just has no text encoding.
Need to save a file may be anything an image or a text
Then just use ReadAllBytes/WriteAllBytes. A text file is always also a byte[], but not all file types are text. You would need Base64 encoding first and that just adds to the size.
The safest way to convert byte arrays to strings is indeed encoding it in something like base64.
Like:
string s= Convert.ToBase64String(bytes);
byte[] bytes = Convert.FromBase64String(s);

how to concatenate 2 wave files in Stream? [duplicate]

This question already has answers here:
How to write NAudio WaveStream to a Memory Stream?
(2 answers)
Closed 7 years ago.
I worked on this answer for my problem.
I want that 2 wave files that get of database with byte array type concatenate together and play then dispose it!
this is my code:
public static void Play()
{
List<byte[]> audio = dal.SelectSound("خدمات", "احیاء");
byte[] sound = new byte[audio[0].Length + audio[1].Length];
Stream outputSound = Concatenate(sound, audio);
try
{
WaveFileReader wavFileReader = new WaveFileReader(outputSound);
var waveOut = new WaveOut(); // or WaveOutEvent()
waveOut.Init(wavFileReader);
waveOut.Play();
}
catch (Exception ex)
{
Logs.ErrorLogEntry(ex);
}
}
public static Stream Concatenate(byte[] outputFile, List<byte[]> sourceFiles)
{
byte[] buffer = new byte[1024];
Stream streamWriter = new MemoryStream(outputFile);
try
{
foreach (byte[] sourceFile in sourceFiles)
{
Stream streamReader = new MemoryStream(sourceFile);
using (WaveFileReader reader = new WaveFileReader(streamReader))
{
int read;
while ((read = reader.Read(buffer, 0, buffer.Length)) > 0)
{
streamWriter.Write(buffer, 0, read);
}
}
}
}
return streamWriter;
}
but I get this error:
Not a WAVE file - no RIFF header
after execute this line:
WaveFileReader wavFileReader = new WaveFileReader(outputSound);
Thanks in advance.
WAV files are not simply an array of bytes, each WAV file has a 44-byte header (the RIFF header) to tell any software how to play it back. Among other things, this header contains information about the length of the file, so in concatenating two WAV files the way you're doing it, you'll end up with two big problems. Firstly, the first WAV file will still have its old header at the start, which will tell your software that the file shorter than it actually is, and secondly, the header of the second WAV file will be stuck in middle of your new file, which will probably sound very strange if you play it back!
So when you're concatenating your files, you'll need to do the following:
Remove the first 44 bytes of each file
Concatenate the two byte
arrays
Create a new header according to the RIFF header specification
Put this header at the
front of your concatenated byte arrays
Call WaveFileReader wavFileReader = new
WaveFileReader(outputSound);

Append WAV Header in NAudio

I am trying to convert audio MP3 files to WAV with a standard rate (48 KHz, 16 bits, 2 channels) by opening with "MediaFoundationReaderRT" and specifying the standard settings in it.
After the file is converted to PCM WAV, when I try to play the WAV file, it gives corrupt output:
Option 1 -
WaveStream activeStream = new MediaFoundationReaderRT([Open "MyFile.mp3"]);
WaveChannel32 waveformInputStream = new WaveChannel32(activeStream);
waveformInputStream.Sample += inputStream_Sample;
I noticed that if I read the audio data into a memory stream (wherein it appends the WAV header via "WaveFileWriter"), then things work fine:
Option 2 -
WaveStream activeStream = new MediaFoundationReaderRT([Open "MyFile.mp3"]);
MemoryStream memStr = new MemoryStream();
byte[] audioData = new byte[activeStream.Length];
int bytesRead = activeStream.Read(audioData, 0, audioData.Length);
memStr.Write(audioData, 0, bytesRead);
WaveFileWriter.CreateWaveFile(memStr, audioData);
RawSourceWaveStream rawSrcWavStr = new RawSourceWaveStream(activeStream,
new WaveFormat(48000, 16, 2));
WaveChannel32 waveformInputStream = new WaveChannel32(rawSrcWavStr);
waveformInputStream.Sample += inputStream_Sample;
However, reading the whole audio into memory is time-consuming. Hence I am looking at "Option 1" as noted above.
I am trying to figure out as to what exactly is the issue. Is it that the WAV header is missing which is causing the problem?
Is there a way in "Option 1" where I can append the WAV header to the "current playing" sample data, instead of converting the whole audio data into memory stream and then appending the header?
I'm not quite sure why you need either of those options. Converting an MP3 file to WAV is quite simple with NAudio:
using(var reader = new MediaFoundationReader("input.mp3"))
{
WaveFileWriter.CreateWaveFile("output.wav", reader);
}
And if you don't need to create a WAV file, then your job is already done - MediaFoundationReader already returns PCM from it's Read method so you can play it directly.

NAudio Convert Byte Array to Wav

I looked into NAudio classes but couldn't see a class that converts byte array to WAV file. If there is no class like this, how can I convert byte array to WAV file using NAudio?
I want to send a text to RS232 as bytes, then I will get back those bytes into a byte[] buffer. After getting back data I want to save them as a WAV file using NAudio.
I tried to use WaveBuffer class but I think I am trying a wrong way.
This blog post explains how to use the WaveFileWriter class for this purpose:
byte[] testSequence = new byte[] { 0x1, 0x2, 0xFF, 0xFE };
using (WaveFileWriter writer = new WaveFileWriter(fileName, waveFormat))
{
writer.WriteData(testSequence, 0, testSequence.Length);
}

Categories

Resources