I have a circuit that sends me microphone data as bytes.I save these bytes into .txt file and reading them using FileStream Circuit's frequency is 16khz.
My problem is when I try to convert those bytes to wav, it gives me a meaningless result. Also my record time is not matched with wav file duration.
WaveFormat waveFormat = new WaveFormat(16000,8,1);
using (WaveFileWriter writer = new WaveFileWriter(tempFile, waveFormat))
{
writer.Write(audioBuffer, 0, audioBuffer.Length);
}
What is the data structure for a wav file? Should I convert them Hex or float or something else?
It's very common to record 16 bit rather than 8 bit, so I'd recommend trying this first:
new WaveFormat(16000,16,1);
Once you get the bit depth right, you should hear recognizable sound, although the pitch will be wrong if you have the wrong sample rate or channel count.
Related
I'm sorry that it's kind of hard to put this concept into the question title, maybe somebody could help, thanks!
I was able to get the "byte-wised" waveform watching this video.
Turned the whole WAV file into a byte array, now my question is:
How could I get the corresponding time from the certain index of the byte array!?
For example, b[3520] corresponding to 0.013s!?
I had thought about maybe I could divide the total timespan of the WAV file by the total length of the bit array, then I would know how much time each byte occupy.
But I was sketchy about the accuracy, is there any more accurate way to do such a thing!?
Much appreciated.
I would try using WaveFormat.BitsPerSample and WaveFormat.SampleRate.
eg. BitsPerSample = 32 => 4bytes WaveFormat.SampleRate = 44100 => 4*44100bytes/sec
I don't know if this way will be more accurate.
I want to be able to get audio data from an MP3 file with NAudio, average out the data in the left and right channels to create one dataset and then resample the averaged 44.1KHz audio data to 8Khz but I am having trouble understanding how data is represented in an NAudio Wavestream.
If I had 1 sec worth of MP3 audio, then how many bytes would I have in the WaveStream? By looking at a few code samples it seems one sample is 4 bytes and audio is sampled at 44100Hz and we have 2 different channels, so would that mean we would have (44100 * 4 * 2) bytes in the wavestream, is that right?
Which of the following 3 streams - AStream,PCM and inputStream - should I use to get audio data from? And how to I access left and right channel data separately?
var AStream = new MP3FileReader(myFilePath);
var PCM = new WaveConversionStream.Createpcm(AStream);
var inputStream = new WaveChannel32(new BlockAlignStream(PCM));
I have been thinking of converting the WaveStream using the WaveFormatConversionStream but the code below throws a NAudio.MmException with a message saying "AcmNotPossible calling Acmstreamopen".
var targetFormat = new WaveFormat(8000,1);
var resampled = new WaveFormatConversionStream(targetFormat, inputStream);
The above code doesn't even work if targetFormat is equal to inputStream's format, so I don't know what I am doing wrong here.
//Still throws NAudio.MmException
var resampled = new WaveFormatConversionStream(inputStream.WaveFormat, inputStream);
Other Info: VS2012, WPF, NAudio 1.6.
You seem to have copied a code sample that belongs to a much earlier version of NAudio. The Mp3FileReader class will emit 16 bit samples, and uses the ACM MP3 frame decompressor by default. If you'd prefer your samples directly in floating point, then you can make use of the AudioFileReader.
Resampling 44.1kHz straight down to 8kHz is not a particularly good idea, as you'd end up with a lot of aliasing, so a low pass filter would ideally be applied first. Left and right channels are stored interleaved, so you get a left sample, followed by a right sample, and so on.
NAudio.Wave.WaveChannel32 wave = new NAudio.Wave.WaveChannel32(new NAudio.Wave.WaveFileReader(open.FileName));
byte[] mainBuffer = new byte[wave.Length];
wave.Read(mainBuffer, 0, mainBuffer.Length);
I want to do some calculations and plot the waveform of a wav file using NAudio and ZedGraph. However when file is too large (greater than 100 megabyte) wave.Read(mainBuffer, 0, mainBuffer.Length);throws out of memory exception. How can i solve this issue? Pls can anyone help me?
I changed my code i will write here as soon as possible.
I would recommend against reading the whole file in one go. Read a few seconds at a time, calculate the peak values for your waveform plot and then move on to the next few seconds.
I am currently trying to write an Audio Player in C#. I am using BASS library to deal with playing music but now i have small problem with getting length of the song.
Well i have read BASS doc and found a way:
"All" i need to do is
int stream = Bass.BASS_StreamCreateFile(filepath,....);
int length = Bass.BASS_ChannelBytes2Seconds(stream, Bass.BASS_ChannelGetLength(stream));
And in most of cases i get valid length of song. And here the problem starts. As far as i know the stream creation operation is quite expensive (correct me if i am mistaken) and creating a stream only to get length of the song looks a little silly.
So my question is: Is there any other way to get it without creating steam file (not being so expensive). I will be thinking later about reading id3 tags. Is creating that stream "evil that must be done no matter what" and even if i would try to get it with other library it would do exactly the same thing?
You can use the Microsoft.WindowsAPICodePack.Shell:
using Microsoft.WindowsAPICodePack.Shell;
Then code like so:
string file = "myfile.mp3"
ShellFile so = ShellFile.FromFilePath(file);
double 100nanoseconds;
double.TryParse(so.Properties.System.Media.Duration.Value.ToString(), out 100nanoseconds);
There is a code project that could help you as well
I have a file that exists within a text and a binary image, I need to read from 0 to 30 position the text in question, and the position on 31 would be the image in binary format.
What are the steps that I have to follow to proceed with that problem?
Currently, I am trying to read it using FileStream, and then I move the FileStream var to one BinaryReader as shown below:
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)
BinaryReader br = new BinaryReader(fs)
From there forward, I'm lost.
UPDATE
Alright, so I Can read my file now.
Until the position 30 is my 30 string, from position 30 is the bit string Which is Actually an image.
I wonder how do I read the bytes from position 30 and then save the images!
Does anyone have any ideas?
Follow an example from my file to you have some ideia:
£ˆ‰¢#‰¢#¢–”…#•…¦#„£################################.-///%<<??#[K}#k{M÷]kðñôôô}ù~øòLKóôòÿg
Note that even the # # # is my string and from that the picture would be one byte.
Expanding on Roger's answer a bit, with some code.
A string is always encoded in some format, and to read it you need to know that encoding (especially when using binary reader). In many cases, it's plain ASCII and you can use Encoding.ASCII.GetString to parse it if you get unexpected results (weird characters etc.) then try another encoding.
To parse the image you need to use an image parser. .NET has several as part of their GUI namespaces. In the sample below I'm using the one from System.Drawing (windows forms) but similar ones exists in WPF and there are many third party libraries out there.
using (var reader = new BinaryReader(File.Open(someFile, FileMode.Open))
{
// assuming your string is in plain ASCII encoding:
var myString = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(30));
// The rest of the bytes is image data, use an image library to process it
var myImage = System.Drawing.Image.FromStream(reader.BaseStream);
}
Now MSDN has a caution about using the BaseStream in conjunction with BinaryReader but I believe in the above case you should be safe since you're not using the stream after the image. But keep an eye out for problems. If it fails, you can always read the bytes into a new byte[] and create a new MemoryStream from those bytes.
EDIT:
You indicated in your comment your string is EBCDIC which unfortunately means you cannot use any of the built in Encodings to decode it. A quick google search revealed a post by Jon Skeet on a EBCDIC .NET Encoding class that may get you started. It will essentially give you ebcdicEncoding.GetString(...);
You can use FileStream to open and read from the file. If you read the first 30 bytes into a buffer you can then convert that to a string using "string Encoding.ASCII.GetString(byte[] buffer, int offset, int length)".