How to get sound data sample value in c# - c#

I need to get the sample values of sound data of a WAV file so that by using those sample values i need to get the amplitude values of that sound data in every second.
Important: Is there any way to get audio data sample values using Naudio library or wmp library?
I am getting the sample values in this way:
byte[] data = File.ReadAllBytes(File_textBox.Text);
var samples=new int[data.Length];
int x = 0;
for (int i = 44; i <data.Length; i += 2)
{
samples[x] = BitConverter.ToInt16(data, i);
x++;
}
But I am getting negative values more like (-326260). so is this right or wrong?
I mean can a sample value be negative or not and if it is correct then what does it mean a sound or silence?

NAudio can do this for you, it's in the library (I think it's the WaveStream or WaveReader class, or something similar). I can recommend it's use, if it's not too much overhead.
If you want to roll-your-own, and want to deal with arbitrary wave files, you'll have to read up on the WAV file format, and analyze the header yourself.
Although in general a WAV file contains 16bit samples, it doesn't have to, and depending on the exact format, they might be stored in little endian or big endian.
The header contains information about sample rate, number of channels, bits per sample, bytes per sample and such like, which allow you to do the actual math to get exactly one sample.

Related

NAudio - beginners questions - running on 20ms buffer of audio file

Doing my first steps in Audio prog and using NAudio, I'm trying to have a simple app that grabs a WAV file and getting 20ms of audio data each time till EOF. However I'm getting a bit confused with the buffer arrays and probably conversions.
Is there a simple way someone can post in here?
Moreover I got confused with the following:
When using AudioFileReader readertest = new AudioFileReader(fileName) I'm getting different metadata like bitrate of 32 and length of ~700000.
However, when using the NAudio - WaveFileReader file1 = new WaveFileReader(fileName) I'm getting half values for the same audio file (bitrate = 16, length = ~350000). Also the encoding for the first is "IEEEFloat" while the latter is "PCM". Any explanations...?
Thanks v much!
AudioFileReader is a wrapper around WaveFileReader (and supports several other file types), and auto-converts to IEEE float for you. If you want to read the audio directly into a byte array in whatever format it is in the WAV file, then you should just use WaveFileReader.

C# values differ from MATLAB values

I am working on a project with audio files. I read a file and parse it. I compare my parsed values with other sources and everything seems fine. (FYI : wav file with 16 bits per sample, 44.100 Hz and 7211 sample points.)
Since my every data point is defined with 16 bits I expect my value range as [-65536, +65536]. I get -4765 as minimum and 5190 as maximum from the values I read.
But when I perform the same operation in MATLAB I get -0.07270813 and 0.079193115 respectively. This is not a big problem because it seems that MATLAB seems normalizing my values within range [-1, +1]. When I plot I get the same figure.
But when I take FFT from both applications (I am using Lomont FFT) result differ greatly and I am not sure what is wrong with my code. Lomont seems fine but the results are inconsistent.
Is this difference normal, or should I use another algorithm for this spesific operation. Can anyone suggest a better FFT algorithm (I already tried NAudio, Exocortex etc) in C# to get compliant result with MATLAB. (I suppose that their result are correct.) or any advice or suggestions on this difference?
My plots :
MATLAB plots:

Create wave file from a string

Solved, thanks. It's base64 and this works.
System.Convert.FromBase64String(columns[6]);
Thanks again.
I got a TSV file, and inside this file there're audio stored as original string and related wave info. One wave and its info per line. What I need to do is to read each line, get the audio, and save them as separated wave files.
One sample of wave string is like this:
UklGRpgiAABXQVZFZm10ICwAAACUAgEAgD4AAPAKAAA4AAAAGgABAA8AKACOAgEAgD4AANAHAAAoAAAAAgBAAWRhdGFYIgAAQMQKQPQTQTQSQTQSQTQUQYNBVBNBJBJBJBNBJBRBRKFEE0EkE0FEFEE0FEFUFQAAAAAAAAAAAADACOmRY92lbj7+7kGhMFC3V9I3qMyjX2G8vAclkKFxUlD26mS+1qCRMV4OuVCxXf/IxrFBj///9sAG0iRqqUOIIRKT/4vqBtdWJF6pI/mWgPFx6JlUIFUPm6gofbyf93hJ6NCbgja88uTflydp///
And I tried to read this line and use:
byte[] waveContext = Encoding.Default.GetBytes(columns[6]);
File.WriteAllBytes(waveFullPath, waveContext);
But the output file contains just the same string.
Does anybody got ideas on how to handle this?
Many thanks.
Looks like a base 64 encoded string.
byte[] waveBytes = System.Convert.FromBase64String(base64EncodedData);
Don't know how to build up a wave file. This may help you: MSDN: Creating wav files in C#. (10secs lookup with Google.)
There is no such thing as "audio stored as original string".
Audio data is binary data usually (these days) two channels à 16Bits interleaved
prepended by a short (binary) header which contains number of channels and sampling rate.
Read about "RIFF WAV" file format.

Raise wave file volume with NAudio

I am an audio noob
I am looking to embed audio in an html page by passing the data as a string such as
< Audio src="data:audio/wav;base64,AA....." />
doing that works, but I need to raise the volume. I tried working with NAudio but it seems like it does some conversion and it will no longer play. This is the code I use to raise the volume:
public string ConvertToString(Stream audioStream)
{
audioStream.Seek(0,SeekOrigin.Begin);
byte[] bytes = new byte[audioStream.Length];
audioStream.Read(bytes,0,(int)audioStream.Length);
audioStream.Seek(0,SeekOrigin.Begin);
return Convert.ToBase64String(bytes);
}
var fReader = new WaveFileReader(strm);
var chan32 = new WaveChannel32(fReader,50.0F,0F);
var ouputString = "data:audio/wav;base64," + ConvertToString(chan32);
but when I put outputString into an audio tag it fails to play. What type of transformation does NAudio do, and how can I get it ton give me the audio stream in such a way that I can serialize it and the browser will be able to play it?
Or for another suggestion: if NAudio to heavyweight for something as simple as raising the volume what's a better option for me?
I'm no expert in embedding WAV files in web pages (and to be honest it doesn't seem like a good idea - WAV is one of the most inefficient ways of delivering sound to a web page), but I'd expect that the entier WAV file, including headers needs to be encoded. You are just writing out the sample data. So with NAudio you'd need to use a WaveFileWriter writing into a MemoryStream or a temporary file to create a volume adjusted WAV file that can be written to your page.
There are two additional problems with your code. One is that you have gone to 32 bit floating point, making the WAV file format even more inefficent (doubling the size of the original file). You need to use the Wave32To16Stream to go back to 16 bit before creating the WAV file. The second is that you are multiplying each sample by 50. This will almost certainly horribly distort the signal. Clipping can very easily occur when amplifying a WAV file, and it depends on how much headroom there is in the original recording. Often dynamic range compression is a better option than simply increasing the volume.

edit specific pixels in an in buffer for a raw data image file

I have written a raw binary image file into a buffer which is an Int16[] and I need to edit the specific data points by multiplying them by a specific scalar. Is there any efficient way to access the information and be able to manipulate the data there?
Though it isn't much I have a shell written that then writes the buffer back out into a binary file after the editing has been done and then saves it:
public void correctColor()
{
//TODO: Write a loop to read each value in the buffer
// and multiply by the appropriate scalar.
writeBinaryFile(this.outFile, this.pixelBuffer);
}
Any tips or suggested resources would be great.
It's not obvious to me what the nature of the transformation you're trying to do is or what the problem with doing it might be.
On the surface of it, if what you have is really pixels of color (as opposed to palette indexes), something like this should work:
for(int i = 0; i < this.pixelBuffer.Length; i++)
this.pixelBuffer[i] *= 42;

Categories