CScore MediaFoundationEncoder MP3 Encoder Output Stream Empty - c#

I'm trying to capture an audio stream in CScore and save it in various encodings and to various locations. One of my intended output encodings is MP3 via the MediaFoundationEncoder APIs.
I am able to successfully encode to MP3 when saving to a local file path. However, if I try to write to a memory stream the memory stream completes writing with a 0 length.
What is wrong with this implementation?
Working Local Storage
var fileName = "c:\audio.mp3";
using (var encoder = MediaFoundationEncoder.CreateMP3Encoder(waveFormat, fileName, waveFormat.BytesPerSecond))
{
byte[] buffer = new byte[waveFormat.BytesPerSecond];
int read;
while ((read = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
encoder.Write(buffer, 0, read);
}
}
Non-working Memory Stream
using (var outputStream = new MemoryStream())
{
var encoder = MediaFoundationEncoder.CreateMP3Encoder(waveFormat, outputStream, waveFormat.BytesPerSecond);
var buffer = new byte[waveFormat.BytesPerSecond];
int read;
while ((read = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
encoder.Write(buffer, 0, read);
}
log.Debug("MP3 File Size: " + outputStream.Length); // <-- Returns as 0
}

You have to dispose the encoder after write, this completes the output stream.
public static byte[] EncodeBytes(byte[] bytes, WaveFormat waveFormat)
{
var outputStream = new MemoryStream();
var encoder = MediaFoundationEncoder.CreateMP3Encoder(waveFormat, outputStream, waveFormat.BytesPerSecond);
var buffer = new byte[waveFormat.BytesPerSecond];
var inputStream = new MemoryStream(bytes);
int read;
while ((read = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
encoder.Write(buffer, 0, read);
}
encoder.Dispose();
return outputStream.ToArray();
}

Related

How to read an .lcf file which is in asset folder in Xamarin

I have loaded .lcf file in Assets folder and I set build action as Content. I get an exception which says that file cannot be found.
This is how I read .lcf file from assets folder and store it in a byte array:
byte[] buf = System.IO.File.ReadAllBytes("custom.lcf");
Use AssetManager to read files from Assets
byte[] buffer = new byte[16*1024];
byte[] data;
AssetManager assets = this.Assets;
using (Stream input = assets.Open ("custom.lcf")) {
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
data = ms.ToArray();
}
}

HTTP Response Stream to file in c#

I want to write my http response to a file but my file is always empty. Why?
using (Stream outputfile = File.OpenWrite(objecttype + ".txt"))
{
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = context.Response.OutputStream.Read(buffer, 0, buffer.Length)) > 0)
{
outputfile.Write(buffer, 0, bytesRead);
}
outputfile.Flush();
outputfile.Close();
}

Memory stream is not expandable

I'm attempting to read an email attachment and I'm getting a "Memory Stream is not expandable" error. I researched this some and most of the solutions seemed related to determining the size of the buffer dynamically, but I'm already doing that. I'm not very experienced with memory streams, so I'd like to know WHY this is a problem. Thanks.
foreach (MailMessage m in messages)
{
byte[] myBuffer = null;
if (m.Attachments.Count > 0)
{
//myBuffer = new byte[25 * 1024]; old way
myBuffer = new byte[m.Attachments[0].ContentStream.Length];
int read;
while ((read = m.Attachments[0].ContentStream.Read(myBuffer, 0, myBuffer.Length)) > 0)
{
// error occurs on executing next statement
m.Attachments[0].ContentStream.Write(myBuffer, 0, read);
}
... more unrelated code ...
If you create a MemoryStream over a pre-allocated byte array, it can't expand (ie. get longer than the size you specified when you started). Instead, why not just use:
using (var ms = new MemoryStream())
{
// Do your thing, for example:
m.Attachments[0].ContentStream.CopyTo(ms);
return ms.ToArray(); // This gives you the byte array you want.
}
You need to replace the line
m.Attachments[0].ContentStream.Write(myBuffer, 0, read);
with a line that writes to a previously created MemoryStream, e.g.
foreach (MailMessage m in messages)
{
byte[] myBuffer = null;
if (m.Attachments.Count > 0)
{
//myBuffer = new byte[25 * 1024]; old way
myBuffer = new byte[m.Attachments[0].ContentStream.Length];
int read;
MemoryStream ms = new MemoryStream();
while ((read = m.Attachments[0].ContentStream.Read(myBuffer, 0, myBuffer.Length)) > 0)
{
ms.Write(myBuffer, 0, read);
}

decompress a .gz file using GZipStream

I have several .gz files, and I want to decompress them one by one.
I have writen a simple code using GzipStream in C#, but got failed. I wonder a correct and useful method to achieve what I want. Thanks a lot.
private string Extrgz(string infile)
{
string dir = Path.GetDirectoryName(infile);
string decompressionFileName = dir + Path.GetFileNameWithoutExtension(infile) + "_decompression.bin";
using (GZipStream instream = new GZipStream(File.OpenRead(infile), CompressionMode.Compress))// ArgumentException...
{
using (FileStream outputStream = new FileStream(decompressionFileName, FileMode.Append, FileAccess.Write))
{
int bufferSize = 8192, bytesRead = 0;
byte[] buffer = new byte[bufferSize];
while ((bytesRead = instream.Read(buffer, 0, bufferSize)) > 0)
{
outputStream.Write(buffer, 0, bytesRead);
}
}
}
return decompressionFileName;
}
You need to decompress but you set CompressionMode.Compress, replace it with CompressionMode.Decompress.
Example here.
Here:
public static void DeCompressFile(string CompressedFile, string DeCompressedFile)
{
byte[] buffer = new byte[1024 * 1024];
using (System.IO.FileStream fstrmCompressedFile = System.IO.File.OpenRead(CompressedFile)) // fi.OpenRead())
{
using (System.IO.FileStream fstrmDecompressedFile = System.IO.File.Create(DeCompressedFile))
{
using (System.IO.Compression.GZipStream strmUncompress = new System.IO.Compression.GZipStream(fstrmCompressedFile,
System.IO.Compression.CompressionMode.Decompress))
{
int numRead = strmUncompress.Read(buffer, 0, buffer.Length);
while (numRead != 0)
{
fstrmDecompressedFile.Write(buffer, 0, numRead);
fstrmDecompressedFile.Flush();
numRead = strmUncompress.Read(buffer, 0, buffer.Length);
} // Whend
//int numRead = 0;
//while ((numRead = strmUncompress.Read(buffer, 0, buffer.Length)) != 0)
//{
// fstrmDecompressedFile.Write(buffer, 0, numRead);
// fstrmDecompressedFile.Flush();
//} // Whend
strmUncompress.Close();
} // End Using System.IO.Compression.GZipStream strmUncompress
fstrmDecompressedFile.Flush();
fstrmDecompressedFile.Close();
} // End Using System.IO.FileStream fstrmCompressedFile
fstrmCompressedFile.Close();
} // End Using System.IO.FileStream fstrmCompressedFile
} // End Sub DeCompressFile
// http://www.dotnetperls.com/decompress
public static byte[] Decompress(byte[] gzip)
{
byte[] baRetVal = null;
using (System.IO.MemoryStream ByteStream = new System.IO.MemoryStream(gzip))
{
// Create a GZIP stream with decompression mode.
// ... Then create a buffer and write into while reading from the GZIP stream.
using (System.IO.Compression.GZipStream stream = new System.IO.Compression.GZipStream(ByteStream
, System.IO.Compression.CompressionMode.Decompress))
{
const int size = 4096;
byte[] buffer = new byte[size];
using (System.IO.MemoryStream memory = new System.IO.MemoryStream())
{
int count = 0;
count = stream.Read(buffer, 0, size);
while (count > 0)
{
memory.Write(buffer, 0, count);
memory.Flush();
count = stream.Read(buffer, 0, size);
}
baRetVal = memory.ToArray();
memory.Close();
}
stream.Close();
} // End Using System.IO.Compression.GZipStream stream
ByteStream.Close();
} // End Using System.IO.MemoryStream ByteStream
return baRetVal;
} // End Sub Decompress

ZLib decompression

I am trying to compress data using the zlib .net library. Regardless of the content of the uncompressed string I only seem to get two bytes of data in the raw[].
{
string uncompressed = "1234567890";
byte[] data = UTF8Encoding.Default.GetBytes(uncompressed);
MemoryStream input = new MemoryStream(data);
MemoryStream output = new MemoryStream();
Stream outZStream = new ZOutputStream(output,zlibConst.Z_DEFAULT_COMPRESSION);
CopyStream(input, outZStream);
output.Seek(0, SeekOrigin.Begin);
byte[] raw = output.ToArray();
string compressed = Convert.ToBase64String(raw);
}
public void CopyStream(System.IO.Stream input, System.IO.Stream output)
{
byte[] buffer = new byte[2000];
int len;
while ((len = input.Read(buffer, 0, 2000)) > 0)
{
output.Write(buffer, 0, len);
}
output.Flush();
}
The problem here is that the ZOutputStream actually writes some of the information into the stream in the finish() method (which is called by Close). The Close method also closes the base stream, so that is not much use in this situation.
Changing the code to the following should work:
{
string uncompressed = "1234567890";
byte[] data = UTF8Encoding.Default.GetBytes(uncompressed);
MemoryStream input = new MemoryStream(data);
MemoryStream output = new MemoryStream();
ZOutputStream outZStream = new ZOutputStream(output,zlibConst.Z_DEFAULT_COMPRESSION);
CopyStream(input, outZStream);
outZStream.finish();
output.Seek(0, SeekOrigin.Begin);
byte[] raw = output.ToArray();
string compressed = Convert.ToBase64String(raw);
}
public void CopyStream(System.IO.Stream input, System.IO.Stream output)
{
byte[] buffer = new byte[2000];
int len;
while ((len = input.Read(buffer, 0, 2000)) > 0)
{
output.Write(buffer, 0, len);
}
output.Flush();
}

Categories

Resources