Unable to merge wav files - c#

Iam trying to merge two .wav files into another file. but I could see only first file's data in the created file.
but the newly created file occupies the space which is equals the sum of the size of the source files.
foreach (string sourceFile in fileNamesList)
{
FileStream file= File.Open(sourceFile, FileMode.Open);
FileStream outFile = File.Open(output, FileMode.Append,FileAccess.Write);
byte[] buffer = new byte[file.Length];
int read;
if ((read=file.Read(buffer, 0, (int)file.Length))>0)
{
outFile.Write(buffer, 0, read);
}
file.Close();
file.Dispose();
outFile.Close();
outFile.Dispose();
}
thanks

You can't just concatenate two WAV files because they have a header which defines the format, number of channels, sample rate, length etc.
You will need to read and parse the header file for each separate WAV file and then write a new header to a new file with the correct data and then append the data contents from each WAV file.
You will not easily be able to concatenate two WAV files which have different sample rates or number of channels, but otherwise it's not too hard (once you've worked out the header format).
See here for details about the header format:
https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
http://en.wikipedia.org/wiki/WAV
Perhaps the easiest way will to be to use a third party tool such as Naudio to do this, as described here:
How to join 2 or more .WAV files together programatically?

Related

Append content of file to existing file

How can I append the content of a file (any file extension) to an existing file with the same extension?
I have tried this
System.IO.File.AppendAllLines(dest_path, System.IO.File.ReadAllLines(fi));
but this works only for the .txt files
I understand that you want to concatenate a set of files together, like the DOS command copy /b a.pdf + b.pdf both.pdf - Reading all the bytes of N number of files and appending them all to a single file.
using (var stream = new FileStream(pathOfFileToAppendTo, FileMode.Append))
{
foreach(var pathOfFileToAppend in ...) {
var bytes = File.ReadAllBytes(pathOfFileToAppend);
stream.Write(bytes, 0, bytes.Length);
}
}
If the files you want to append are very large, you might need a streaming approach instead of reading them all into memory with ReadAllBytes. The ... is some array/list/enumerable of string filenames like you might get from Directory.GetFiles but it can be any set of filepaths.

How to convert audio wav file to Mp3 file Xamarin forms

In my app I am recording voice using AudioRecorder as given in the following site, Audio Recorder it is working but it produce large size WAV file.
For example : If I record audio for 1 minute it takes 4MB to 5MB. So that I want to convert the wave file into MP3 file to reduce the size of the file. Please help me to compress the wav file ,give some example. Thanks in advance.
I never tried converting files before so i looked up on
some threads that might be helpful to you.
One is converting wav to mp3 which require file conversion into a byte[]
public byte[] ConvertToMp3(Uri uri)
{
using (var client = new WebClient())
{
var file = client.DownloadData(uri);
var target = new WaveFormat(8000, 16, 1);
using (var outPutStream = new MemoryStream())
using (var waveStream = new WaveFileReader(new MemoryStream(file)))
using (var conversionStream = new WaveFormatConversionStream(target, waveStream))
using (var writer = new LameMP3FileWriter(outPutStream, conversionStream.WaveFormat, 32, null))
{
conversionStream.CopyTo(writer);
return outPutStream.ToArray();
}
}
}
however on this method he is using a third party service which downloads the
wav file and then to be called on that method but this does not guaranty if the file size will be reduced.
however i have check that you can compress wav files using a library called zlib.
just decompress it whenever u need it.
Please check the link below:
How to convert wav file to mp3 in memory?
Reducing WAV sound file size, without losing quality

Receiving "Not a WAVE file - no RIFF header" when creating wave stream from mp3 conversion stream

I'm trying to convert a mp3 into a wave stream using NAudio. Unfortunately I receive the error Not a WAVE file - no RIFF header on the third line when creating the wave reader.
var mp3Reader = new Mp3FileReader(mp3FileLocation);
var pcmStream = WaveFormatConversionStream.CreatePcmStream(mp3Reader);
var waveReader = new WaveFileReader(pcmStream)
Shouldn't these streams work together properly? My goal is to combine several mp3s and wavs into a single stream for both playing and saving to disc( as a wav).
I'm going to preface this with a note that I've never used NAudio. Having said that, there's a guide to concatenating audio on their Github site.
Having looked at the API, you can't use Mp3FileReader directly as it doesn't implement ISampleProvider. However, you can use AudioFileReader instead.
Assuming you have an IEnumerable<string> (aka List or array) of the filenames you want to join named files:
var sampleList = new List<ISampleProvider>();
foreach(string file in files)
{
sampleList.add(new AudioFileReader(file));
}
WaveFileWriter.CreateWaveFile16("outfilenamegoeshere.wav", new ConcatenatingSampleProvider(sampleList));
you don't need the second and third lines. Mp3FileReader will convert to PCM for you and you can play it directly with a player like WaveOutEvent. To actually produce a WAV file on disk, pass it into WaveFileWriter.CreateWaveFile
using(var reader = new Mp3FileReader(mp3FileLocation))
{
WaveFileWriter.CreateWaveFile(reader);
}

zipping memory stream in silverlight

im using the SLsharpziplip to try to compress a byte[] before sending it on the network to a server. the byte[] contains jpeg data which is already compressed by the jpeg encoder.
you may ask , if jpeg already compress the image, why do i need to compress it more, well because i tried it and it worked.
here is what happened:
I wrote the bytes in the byte[] to a txt file , the size of the txt file is ~5k , i compressed it with winzip and the result file was ~2k , so thats about 50% reduction in the file size. however , when i try to do it with the byte[] and use the slsharziplip to compress the byte[] , the reduction in size is minimal.
here is the code i used:
MemoryStream msCompressed = new MemoryStream();
GZipOutputStream gzCompressed = new GZipOutputStream(msCompressed);
gzCompressed.SetLevel(9);
// allframes is a byte array.
gzCompressed.Write(allframes, 0, allframes.Length);
gzCompressed.Finish();
gzCompressed.IsStreamOwner = false;
gzCompressed.Close();
// i used byte[] compresseddata = msCompressed.ToArray() but i thought i'll try this too.
msCompressed.Seek(0, SeekOrigin.Begin);
byte[] compresseddata = new byte[msCompressed.Length];
msCompressed.Read(compresseddata, 0, compresseddata.Length);
==================================================================================
from debugging the code, i can see that the difference of size between allframes.Length and compresseddata.lenght is minimal. but if that same data is written to a text file and zipped with winzip its size is reduced by 50%.
this is how i write the same data to a txt file:
TextWriter tw = new StreamWriter(MainPage.fs); // fs is a filestream.
foreach (byte b in allframes )
{
tw.Write(b);
}
===============================================================================
am i doing something wrong?! am i misunderstanding something!!
thanks up front :)
You are not comparing like with like.
There is no point in compressing JPEG image data as it is compressed already. Writing it out to a text file won't give you the same file size as writing it to a binary file.
Probably not, I would imagine WinZip has a superior zip algorithm to SLSharpZipLib. You can try varying the compression ratio but other than that, I would try different Silverlight compatible zip libraries.
JPEG as you've correctly pointed out is already a highly compressed file type, so finding a compression algorithm that can find further redundancy is going to be difficult.
Best regards,

How to put three files into one in c#?

I'm trying to make a map for a game that I'm planning to create. The map should have two data files, and a picture file.
I want to put them together, to form a single file, and I only want to use the default libraries.
How can I do this, and still be able to separate them later?
A solution would be compression, but I couldn't find a way to compress multiple files using the gzipstreamer class.
You could use SharpZipLib to create a ZIP file.
Did you consider embedding the files as resources in the assembly (or in a separate assembly?)
A lot depends on the reasons why you want to group them.
Compression will cost time and CPU power.
I think you should consider embedding the resources in the assembly as Erno suggests.
But if you really want to pack them into a single file, you could do so by simply writing the length of each stream before the stream itself. You could then read the length byte and afterwards return the next length bytes as a Stream. Reading/writing with ugly methods below. The target stream could eventually be gzipped. Note that the naive methods below reads and writes the entire string to a single buffer and assumes that no file is larger than int.MaxValue.
But I would not recommend using just the standard libraries.
static void Append(Stream source, Stream target)
{
BinaryWriter writer = new BinaryWriter(target);
BinaryReader reader = new BinaryReader(source);
writer.Write((long)source.Length);
byte[] buffer = new byte[1024];
int read;
do
{
read = reader.Read(buffer, 0, buffer.Length);
writer.Write(buffer, 0, read);
}
while (read > 0);
writer.Flush();
}
static Stream ReadNextStream(Stream packed)
{
BinaryReader reader = new BinaryReader(packed);
int streamLength = (int)reader.ReadInt64();
MemoryStream result = new MemoryStream();
byte[] buffer = new byte[streamLength];
reader.Read(buffer, 0, buffer.Length);
BinaryWriter writer = new BinaryWriter(result);
writer.Write(buffer, 0, buffer.Length);
writer.Flush();
result.Seek(0, SeekOrigin.Begin);
return result;
}
Gzip compression only works on one file (it only ever has). You could try ZIP, 7-ZIP or some other archive format that allows multiple files. Alternately you can TAR the files together first, which was common practice for the compression scheme Gzip was invented to replace.
I had a simiar question a while ago here about saving 2 XML files in one file.
See my answer with code.
"I ended up writing my own Stream, which can be thought of as a multistream. It allows you to treat one stream as multiple streams in succession. i.e. pass a multistream to an xml parser (or anything else) and it'll read up to a marker, which says 'this is the end of the stream'. If you then pass that same stream to another xml parser, it'll read from that marker, to the next one or EOF"
Your basic usage would be:
Writing:
Open File Stream
Create MultiStream passing in File Stream in constructor
Write data file to multistream
Call write end of stream marker on multistream
Write 2nd data file to multistream
Call write end of stream marker on multistream
Save picture to multistream
Close multistream
Close file stream
Reading:
Open File Stream
Create MultiStream passing in File Stream in constructor
Read data file
Call advance to next stream on multistream
Read 2nd data file
Call advance to next stream on multistream
Read image (Image.FromStream() etc.)
Close multistream
Close file stream

Categories