Windows Phone Encoding and Decoding audio using NSpeex. Having issue with decoding? - c#

I am trying to encode a recorded audio using Nspeex and then transfer it over internet and decode on the other end. I am doing all this in Windows Phone 7/8. To encode and decode I am using following code. But while decoding I am not getting the result back correctly which I can play again. Can anyone provide me with encoding and decoding code which runs on WP7/8 recorded audio:
private static Microphone mic = Microphone.Default;
private static byte[] EncodeSpeech(byte[] buf, int len)
{
BandMode mode = GetBandMode(mic.SampleRate);
SpeexEncoder encoder = new SpeexEncoder(mode);
// set encoding quality to lowest (which will generate the smallest size in the fastest time)
encoder.Quality = 1;
int inDataSize = len / 2;
// convert to short array
short[] data = new short[inDataSize];
int sampleIndex = 0;
for (int index = 0; index < len; index += 2, sampleIndex++)
{
data[sampleIndex] = BitConverter.ToInt16(buf, index);
}
// note: the number of samples per frame must be a multiple of encoder.FrameSize
inDataSize = inDataSize - inDataSize % encoder.FrameSize;
var encodedData = new byte[len];
int encodedBytes = encoder.Encode(data, 0, inDataSize, encodedData, 0, len);
if (encodedBytes != 0)
{
// each chunk is laid out as follows:
// | 4-byte total chunk size | 4-byte encoded buffer size | <encoded-bytes> |
byte[] inDataSizeBuf = BitConverter.GetBytes(inDataSize);
byte[] sizeBuf = BitConverter.GetBytes(encodedBytes + inDataSizeBuf.Length);
byte[] returnBuf = new byte[encodedBytes + sizeBuf.Length + inDataSizeBuf.Length];
sizeBuf.CopyTo(returnBuf, 0);
inDataSizeBuf.CopyTo(returnBuf, sizeBuf.Length);
Array.Copy(encodedData, 0, returnBuf, sizeBuf.Length + inDataSizeBuf.Length, encodedBytes);
return returnBuf;
}
else
return buf;
}
private byte[] DecodeSpeech(byte[] buf)
{
BandMode mode = GetBandMode(mic.SampleRate);
SpeexDecoder decoder = new SpeexDecoder(mode);
byte[] inDataSizeBuf = new byte[4];
byte[] sizeBuf = new byte[4];
byte[] encodedBuf = new byte[buf.Length - 8];
Array.Copy(buf, 0, sizeBuf, 0, 4);
Array.Copy(buf, 4, inDataSizeBuf, 0, 4);
Array.Copy(buf, 8, encodedBuf, 0, buf.Length - 8);
int inDataSize = BitConverter.ToInt32(inDataSizeBuf, 0);
int size = BitConverter.ToInt32(sizeBuf, 0);
short[] decodedBuf = new short[inDataSize];
int decodedSize = decoder.Decode(encodedBuf, 0, encodedBuf.Length, decodedBuf, 0, false);
byte[] returnBuf = new byte[inDataSize * 2];
for (int index = 0; index < decodedBuf.Length; index++)
{
byte[] temp = BitConverter.GetBytes(decodedBuf[index]);
Array.Copy(temp, 0, returnBuf, index * 2, 2);
}
return returnBuf;
}
private static BandMode GetBandMode(int sampleRate)
{
if (sampleRate <= 8000)
return BandMode.Narrow;
if (sampleRate <= 16000)
return BandMode.Wide;
return BandMode.UltraWide;
}

I think your problem may be that you are newing up a new SpeexEncoder every time you want to encode audio. You should try making that a member for your class and re-use it.
I looked at the code for Nspeex I noticed that SpeexEncoder uses NbEncoder for the narrow band. In that class it looks like it keeps a history of some previous audio data in order perform the encoding. This should mean that the output for different instances of encoders would not go together.
private static Microphone mic = Microphone.Default;
private static SpeexEncoder encoder = CreateEncoder();
private static SpeexEncoder CreateEncoder()
{
BandMode mode = GetBandMode(mic.SampleRate);
SpeexEncoder encoder = new SpeexEncoder(mode);
// set encoding quality to lowest (which will generate the smallest size in the fastest time)
encoder.Quality = 1;
return encoder;
}
private static byte[] EncodeSpeech(byte[] buf, int len)
{
int inDataSize = len / 2;
...

Related

TCP packets lost

I transfer a video stream from one c# app to another. When I set the frame rate high I don't get the right data after some time.
//Receiver
Socket s;
IPAddress ipAd = IPAddress.Parse("127.0.0.1");
var ip = IPAddress.Any;
myList = new TcpListener(ipAd, 8001);
myList.Start();
s = myList.AcceptSocket();
while (runThread)
{
int buffertype = -1; MemoryStream img = null; int size = 0; int
pos = 0;
try
{
// length of frame
byte[] lengthb = new byte[32];
int k = s.Receive(lengthb, SocketFlags.None);
size = BitConverter.ToInt32(lengthb, 0);
pos = 0;
byte[] lengthframe = new byte[size];
// chunking of data
int chunksize = 100;
while (pos < size - chunksize)
{
int rec = s.Receive(lengthframe, pos, chunksize, SocketFlags.None);
pos += rec;
}
s.Receive(lengthframe, pos, size - pos, SocketFlags.None);
img = new MemoryStream(lengthframe);
}
}
// Other app: Sender (all is send)
MemoryStream ms = new MemoryStream();
img.CopyTo(ms);
byte[] ba = ms.ToArray();
var buffer = BitConverter.GetBytes(ba.Length);
stm.Write(buffer, 0, buffer.Length);
stm.Write(ba, 0, ba.Length);
How can I be safe that all packages are received?
sender:
stm.Write(buffer, 0, buffer.Length);
receiver:
byte[] lengthb = new byte[32];
int k = s.Receive(lengthb, SocketFlags.None);
are you sure buffer.Length type is 32 bytes long (256 bits)? I suppose it's rather 4 or 8 bytes long. So you're potentially receiving 32 bytes buffer which includes your length field in the beggining and the rest is a part of your encoded video stream. Then you throw away that part. Doesn't sound good.

how to get PCM data from stereo channel mp3 using Naudio in C#

I am new to Naudio and using it to get PCM data from Mp3 files, this is my code to take PCM from mono-channel file, but don't know how to do it with stereo channel file
code:
Mp3FileReader file = new Mp3FileReader(op.FileName);
int _Bytes = (int)file.Length;
byte[] Buffer = new byte[_Bytes];
file.Read(Buffer, 0, (int)_Bytes);
for (int i = 0; i < Buffer.Length - 2; i += 2)
{
byte[] Sample_Byte = new byte[2];
Sample_Byte[0] = Buffer[i + 1];
Sample_Byte[1] = Buffer[i + 2];
Int16 _ConvertedSample = BitConverter.ToInt16(Sample_Byte, 0);
}
How can I get PCM from stereo channel Mp3 file?
In a stereo file, the samples are interleaved: one left channel sample followed by one right channel etc. So in your loop you could go through four bytes at a time to read out the samples.
Also there are some bugs in your code. You should use return value of Read, not the size of the buffer, and you have an off by one error in the code to access the samples. Also, no need to copy into a temporary buffer.
Something like this should work for you:
var file = new Mp3FileReader(fileName);
int _Bytes = (int)file.Length;
byte[] Buffer = new byte[_Bytes];
int read = file.Read(Buffer, 0, (int)_Bytes);
for (int i = 0; i < read; i += 4)
{
Int16 leftSample = BitConverter.ToInt16(Buffer, i);
Int16 rightSample = BitConverter.ToInt16(Buffer, i + 2);
}

Playing a RTP stream to PC speakers

I'm using UdpClient to get a RTP stream from phone calls through Avaya DMCC sdk. I would like to play this stream through the computer's speakers. After a lot of searching I've only been able to find solutions that require saving to a file and then playing the file but I need to play the stream through the speakers without saving to a file. I'd like to send audio to the speakers as I receive it.
public void StartClient()
{
// Create new UDP client. The IP end point tells us which IP is sending the data
client = new UdpClient(port);
endPoint = new IPEndPoint(System.Net.IPAddress.Any, port);
selectedCodec = new MuLawChatCodec();
waveOut = new WaveOut();
waveProvider = new BufferedWaveProvider(selectedCodec.RecordFormat);
waveOut.Init(waveProvider);
waveOut.Play();
listening = true;
listenerThread = new Thread(ReceiveCallback);
listenerThread.Start();
}
private void ReceiveCallback()
{
// Begin looking for the next packet
while (listening)
{
// Receive packet
byte[] packet = client.Receive(ref endPoint);
// Packet header
int version = GetRTPValue(packet, 0, 1);
int padding = GetRTPValue(packet, 2, 2);
int extension = GetRTPValue(packet, 3, 3);
int csrcCount = GetRTPValue(packet, 4, 7);
int marker = GetRTPValue(packet, 8, 8);
int payloadType = GetRTPValue(packet, 9, 15);
int sequenceNum = GetRTPValue(packet, 16, 31);
int timestamp = GetRTPValue(packet, 32, 63);
int ssrcId = GetRTPValue(packet, 64, 95);
int csrcid = (csrcCount == 0) ? -1 : GetRTPValue(packet, 96, 95 + 32 * (csrcCount));
int extHeader = (csrcCount == 0) ? -1 : GetRTPValue(packet, 128 + (32 * csrcCount), 127 + (32 * csrcCount));
int payloadIndex = csrcCount == 0 ? 96 : 128 + 32 * csrcCount;
int payload = GetRTPValue(packet, payloadIndex, packet.Length);
byte[] Payload = new byte[packet.Length - payloadIndex];
Buffer.BlockCopy(packet, payloadIndex, Payload, 0, packet.Length - payloadIndex);
byte[] decoded = selectedCodec.Decode(Payload, 0, Payload.Length);
}
}
private int GetRTPValue(byte[] packet, int startBit, int endBit)
{
int result = 0;
// Number of bits in value
int length = endBit - startBit + 1;
// Values in RTP header are big endian, so need to do these conversions
for (int i = startBit; i <= endBit; i++)
{
int byteIndex = i / 8;
int bitShift = 7 - (i % 8);
result += ((packet[byteIndex] >> bitShift) & 1) * (int)Math.Pow(2, length - i + startBit - 1);
}
return result;
}
I now successfully have audio from the call being played over the speakers by adding a byte[] containing just the payload to NAudio's BufferedWaveProvider
There's a demo of how to play audio received over the network included with the NAudio source code (see Network Chat Demo in the NAudioDemo project). Basically use an AcmStream to decode the audio, and then put it into a BufferedWaveProvider which the soundcard is playing from.

How to split a wav file on WP8?

Is there a way to split a wav file in C# WP8? I'd like to save a sample of a wav file, starting at, for example, 00:30 and ending at 00:40.
Maybe using some kind of stream or buffer, but then I'd have to know when to start/finish copying the stream to another wav file.
How can I do this?
on my blog I posted about this, starting with this post (http://csharp-tricks-en.blogspot.de/2011/03/read-in-wave-files.html) aboud reading a wave file with the next 2 posts building up on this .. hope that helps!
Best
Oliver
Since a wav file's header can vary from 44 (standard) to over 100 bytes, you'll need to first determine the exact size of the header and also read important meta information before you can start chopping up your wav file(s).
So you need to know the following meta data about your wav file(s),
Sample rate,
Bit depth,
Channel count,
Audio data format (whether samples are PCM or Floating-Point)
Header size.
Before continuing, I'd recommend reading the format of a wav file header first so you'll have a better idea of what the code is doing.
So first we need to get our meta info,
private void ReadMetaData(FileStream stream, out bool isFloatinfPoint, out int channelCount, out int sampleRate, out int bitDepth, out int headerSize)
{
var headerBytes = new byte[200];
// Read header bytes.
stream.Position = 0;
stream.Read(headerBytes, 0, 200);
headerSize = new string(Encoding.ASCII.GetChars(headerBytes)).IndexOf("data") + 8;
isFloatinfPoint = BitConverter.ToUInt16(new byte[] { headerBytes[20], headerBytes[21] }, 0) == 3 ? true : false;
channelCount = BitConverter.ToUInt16(new byte[] { headerBytes[22] , headerBytes[23] }, 0);
sampleRate = (int)BitConverter.ToUInt32(new byte[] { headerBytes[24], headerBytes[25], headerBytes[26], headerBytes[27] }, 0);
bitDepth = BitConverter.ToUInt16(new byte[] { headerBytes[34], headerBytes[35] }, 0);
}
Once we have this data we can then calculate where we need to start and stop reading our file. To calculate the start and end indexes we do,
var startIndex = (int)(start.TotalSeconds * sampleRate * byteDepth * channelCount);
var endIndex = (int)(end.TotalSeconds * sampleRate * byteDepth * channelCount);
start & end would be a TimeSpan indicating when to start and stop cropping.
We can now read the bytes from our file using our newly calculated info, if you're using a FileStream you would do the following,
var newBytes = new byte[endIndex - startIndex];
myStream.Position = headerSize + startIndex; // Add headerSize to position to make sure we don't read the header.
myStream.Read(newBytes, 0, newBytes.Length);
The all you have to do is write a wav header to the destination file along with the newly extracted audio. So, putting this altogether you should end up with something like this,
private void CropWavFile(string inputFilePath, string outputFilePath, TimeSpan start, TimeSpan end)
{
var stream = new FileStream(inputFilePath, FileMode.Open);
var newStream = new FileStream(outputFilePath, FileMode.OpenOrCreate);
var isFloatingPoint = false;
var sampleRate = 0;
var bitDepth = 0;
var channelCount = 0;
var headerSize = 0;
// Get meta info
ReadMetaData(stream, out isFloatingPoint, out channelCount, out sampleRate, out bitDepth, out headerSize);
// Calculate where we need to start and stop reading.
var startIndex = (int)(start.TotalSeconds * sampleRate * (bitDepth / 8) * channelCount);
var endIndex = (int)(end.TotalSeconds * sampleRate * (bitDepth / 8) * channelCount);
var bytesCount = endIndex - startIndex;
var newBytes = new byte[bytesCount];
// Read audio data.
stream.Position = startIndex + headerSize;
stream.Read(newBytes, 0, bytesCount);
// Write the wav header and our newly extracted audio to the new wav file.
WriteMetaData(newStream, isFloatingPoint, (ushort)channelCount, (ushort)bitDepth, sampleRate, newBytes.Length / (bitDepth / 8));
newStream.Write(newBytes, 0, newBytes.Length);
stream.Dispose();
newStream.Dispose();
}
private void WriteMetaData(FileStream stream, bool isFloatingPoint, ushort channels, ushort bitDepth, int sampleRate, int totalSampleCount)
{
stream.Position = 0;
// RIFF header.
// Chunk ID.
stream.Write(Encoding.ASCII.GetBytes("RIFF"), 0, 4);
// Chunk size.
stream.Write(BitConverter.GetBytes(((bitDepth / 8) * totalSampleCount) + 36), 0, 4);
// Format.
stream.Write(Encoding.ASCII.GetBytes("WAVE"), 0, 4);
// Sub-chunk 1.
// Sub-chunk 1 ID.
stream.Write(Encoding.ASCII.GetBytes("fmt "), 0, 4);
// Sub-chunk 1 size.
stream.Write(BitConverter.GetBytes(16), 0, 4);
// Audio format (floating point (3) or PCM (1)). Any other format indicates compression.
stream.Write(BitConverter.GetBytes((ushort)(isFloatingPoint ? 3 : 1)), 0, 2);
// Channels.
stream.Write(BitConverter.GetBytes(channels), 0, 2);
// Sample rate.
stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);
// Bytes rate.
stream.Write(BitConverter.GetBytes(sampleRate * channels * (bitDepth / 8)), 0, 4);
// Block align.
stream.Write(BitConverter.GetBytes((ushort)channels * (bitDepth / 8)), 0, 2);
// Bits per sample.
stream.Write(BitConverter.GetBytes(bitDepth), 0, 2);
// Sub-chunk 2.
// Sub-chunk 2 ID.
stream.Write(Encoding.ASCII.GetBytes("data"), 0, 4);
// Sub-chunk 2 size.
stream.Write(BitConverter.GetBytes((bitDepth / 8) * totalSampleCount), 0, 4);
}
private void ReadMetaData(FileStream stream, out bool isFloatinfPoint, out int channelCount, out int sampleRate, out int bitDepth, out int headerSize)
{
var headerBytes = new byte[200];
// Read header bytes.
stream.Position = 0;
stream.Read(headerBytes, 0, 200);
headerSize = new string(Encoding.ASCII.GetChars(headerBytes)).IndexOf("data") + 8;
isFloatinfPoint = BitConverter.ToUInt16(new byte[] { headerBytes[20], headerBytes[21] }, 0) == 3 ? true : false;
channelCount = BitConverter.ToUInt16(new byte[] { headerBytes[22] , headerBytes[23] }, 0);
sampleRate = (int)BitConverter.ToUInt32(new byte[] { headerBytes[24], headerBytes[25], headerBytes[26], headerBytes[27] }, 0);
bitDepth = BitConverter.ToUInt16(new byte[] { headerBytes[34], headerBytes[35] }, 0);
}

RSS Video Feed Enhancement - Need to get duration on items that dont include it in feed

I have a working DNLA device (Xbox360, PSP...) RSS Video feed reader in C#. It parses .opml files to get the feed uri.
Sometimes an RSS feed item will not have a duration value, so I am hard coding a default duration value when it doesn't.
I want to get the true duration of the video file.
My idea is to use httpWebRequest to get a byte stream and seek out the information in the files binary metaData, if available. I'm thinking it could be done, but can find no similar examples.
The process must be fast and does not need to get the whole video file, because the duration value is only needed to build the menu. The files I am expecting to process this way are .flv, .m4v, and .mp4's. the example shown below is for a .flv file:
using System;
using System.IO;
using System.Text;
using System.Net;
namespace myRSSVideoReader
{
public static class FlvMetadataReader
{
private const int BufferLength = 1000;
/// <summary>
/// Reads the meta information (if present) in an FLV
/// </summary>
/// <param name="uri">The path to the FLV file</returns>
public static MediaMetadataInfo GetMetadataInfo(string uri)
{
bool hasMetaData = false;
double duration = 0;
double width = 0;
double height = 0;
double videoDataRate = 0;
double audioDataRate = 0;
double frameRate = 0;
DateTime creationDate = DateTime.MinValue;
WebRequest req = HttpWebRequest.Create(uri);
WebResponse res = req.GetResponse();
Stream s = res.GetResponseStream(); //Source
MemoryStream ms = new MemoryStream((int)(res as HttpWebResponse).ContentLength); //Destination
byte[] b = new byte[BufferLength]; //Buffer
int cnt = 0;
do
{
//Read up to 1000 bytes from the response stream
cnt = s.Read(b, 0, BufferLength);
//Write the number of bytes actually read
ms.Write(b, 0, cnt);
}
while (cnt > 0);
try
{
// read where "onMetaData"
byte[] bytes = new byte[10];
ms.Seek(27, SeekOrigin.Begin);
int result = ms.Read(bytes, 0, 10);
// if "onMetaData" exists then proceed to read the attributes
string onMetaData = ByteArrayToString(bytes);
if (onMetaData == "onMetaData")
{
hasMetaData = true;
// 16 bytes past "onMetaData" is the data for "duration"
duration = GetNextDouble(ms, 16, 8);
// 8 bytes past "duration" is the data for "width"
width = GetNextDouble(ms, 8, 8);
// 9 bytes past "width" is the data for "height"
height = GetNextDouble(ms, 9, 8);
// 16 bytes past "height" is the data for "videoDataRate"
videoDataRate = GetNextDouble(ms, 16, 8);
// 16 bytes past "videoDataRate" is the data for "audioDataRate"
audioDataRate = GetNextDouble(ms, 16, 8);
// 12 bytes past "audioDataRate" is the data for "frameRate"
frameRate = GetNextDouble(ms, 12, 8);
// read in bytes for creationDate manually
ms.Seek(17, SeekOrigin.Current);
byte[] seekBytes = new byte[24];
result = ms.Read(seekBytes, 0, 24);
string dateString = ByteArrayToString(seekBytes);
// create .NET readable date string
// cut off Day of Week
dateString = dateString.Substring(4);
// grab 1) month and day, 2) year, 3) time
dateString = dateString.Substring(0, 6) + " " + dateString.Substring(16, 4) + " " + dateString.Substring(7, 8);
// .NET 2.0 has DateTime.TryParse
try
{
creationDate = Convert.ToDateTime(dateString);
}
catch(Exception)
{
// no error handling
}
}
}
catch (Exception)
{
// no error handling
}
finally
{
ms.Close();
ms.Dispose();
}
Uri newUri = new Uri(uri);
string filename = Path.GetFileName(newUri.AbsoluteUri);
return new MediaMetadataInfo(hasMetaData, filename, duration, width, height, videoDataRate, audioDataRate, frameRate, creationDate);
}
private static Double GetNextDouble(MemoryStream ms, int offset, int length)
{
// move the desired number of places in the array
ms.Seek(offset, SeekOrigin.Current);
// create byte array
byte[] bytes = new byte[length];
// read bytes
int result = ms.Read(bytes, 0, length);
// convert to double (all flass values are written in reverse order)
return ByteArrayToDouble(bytes, true);
}
private static String ByteArrayToString(byte[] bytes)
{
string byteString = string.Empty;
foreach (byte b in bytes)
{
byteString += Convert.ToChar(b).ToString();
}
return byteString;
}
private static Double ByteArrayToDouble(byte[] bytes, bool readInReverse)
{
if (bytes.Length != 8)
throw new Exception("bytes must be exactly 8 in Length");
if (readInReverse)
Array.Reverse(bytes);
return BitConverter.ToDouble(bytes, 0);
}
}
}
Can this be done? I'm including an .flv uri from abc News RSS feed to use as an example:
http://video-cdn.abcnew.go.com/090713_ann_skinnydip.flv
Any help would be appreciated.
Your code looks promising. The hard part will be writing parsers for each of the expected file format. There's also a good chance that the files won't have the metadata you need.
You might also look into using the request range to tell the server that you only need a part of the file. That should speed it up as long as the server supports it.
got it! For Flash files at least! included a little message for the Admin in the user agent string too!
using System;
using System.IO;
using System.Net;
namespace myRSSVideoReader
{
public static class FlvMetadataReader
{
static string onMetaData = "";
static string bytesToFile = "";
/// <summary>
/// Reads the meta information (if present) in an FLV
/// </summary>
/// <param name="uri">The uri to the FLV file</returns>
public static MediaMetadataInfo GetMetadataInfo(string uri)
{
//needed for the file name only
Uri newUri = new Uri(uri);
Stream strm = null;
StreamReader MyReader = null;
bool hasMetaData = false;
double duration = 0;
double width = 0;
double height = 0;
double videoDataRate = 0;
double audioDataRate = 0;
double frameRate = 0;
DateTime creationDate = DateTime.MinValue;
int range = 800;
try
{
//byte[] result;
byte[] buffer = new byte[range];
strm = GetURLStream(uri, range);
if (strm != null)
{
using (MemoryStream fileStream = new MemoryStream())
{
int count = 0;
do
{
count = strm.Read(buffer, 0, buffer.Length);
fileStream.Write(buffer, 0, count);
}
while (count != 0);
// read where "onMetaData" in flash, this indicates we've got maetadata
byte[] bytes = new byte[1000];
fileStream.Seek(27, SeekOrigin.Begin);
int result = fileStream.Read(bytes, 0, 1000);
// if "onMetaData" exists then proceed to read the attributes
bytesToFile = ByteArrayToString(bytes);
onMetaData = bytesToFile.Substring(0, 10);
if (onMetaData == "onMetaData")
{
hasMetaData = true;
duration = GetNextDouble(bytes, bytesToFile.IndexOf("duration") + 9, 8);
duration = Math.Round(duration);
width = GetNextDouble(bytes, bytesToFile.IndexOf("width") + 6, 8);
height = GetNextDouble(bytes, bytesToFile.IndexOf("height") + 7, 8);
videoDataRate = GetNextDouble(bytes, bytesToFile.IndexOf("videodatarate") + 14, 8);
audioDataRate = GetNextDouble(bytes, bytesToFile.IndexOf("audiodatarate") + 14, 8);
frameRate = GetNextDouble(bytes, bytesToFile.IndexOf("framerate") + 10, 8);
}
fileStream.Close();
fileStream.Dispose();
}
}
}
catch {}
finally
{
// do some cleanup
if (MyReader != null)
MyReader.Close();
if (strm != null)
strm.Close();
}
string filename = Path.GetFileName(newUri.AbsoluteUri);
return new MediaMetadataInfo(hasMetaData, filename, duration, width, height, videoDataRate, audioDataRate, frameRate, creationDate);
}
/* ------------------------------------------------------------- */
private static Stream GetURLStream(string strURL, int range)
{
WebRequest req;
WebResponse res = null;
Stream respStream;
try
{
req = WebRequest.Create(strURL);
((HttpWebRequest)req).UserAgent = "myRSSVideoReader/1.0.0.12 (compatible; http://www.myrssvideoreader.com; Your RSS feeds need duration value;)";
((HttpWebRequest)req).AddRange(0, range * 2);
res = req.GetResponse();
respStream = res.GetResponseStream();
return respStream;
}
catch (Exception)
{
res.Close();
return null;
}
}
/* ------------------------------------------------------------- */
private static Double GetNextDouble(Byte[] b, int offset, int length)
{
MemoryStream ms = new MemoryStream(b);
// move the desired number of places in the array
ms.Seek(offset, SeekOrigin.Current);
// create byte array
byte[] bytes = new byte[length];
// read bytes
int result = ms.Read(bytes, 0, length);
// convert to double (all flass values are written in reverse order)
return ByteArrayToDouble(bytes, true);
}
/* ------------------------------------------------------------- */
private static String ByteArrayToString(byte[] bytes)
{
string byteString = string.Empty;
foreach (byte b in bytes)
{
byteString += Convert.ToChar(b).ToString();
}
return byteString;
}
/* ------------------------------------------------------------- */
private static Double ByteArrayToDouble(byte[] bytes, bool readInReverse)
{
if (bytes.Length != 8)
throw new Exception("bytes must be exactly 8 in Length");
if (readInReverse)
Array.Reverse(bytes);
return BitConverter.ToDouble(bytes, 0);
}
}
}

Categories