This question only vise versa. For now I got this:
UInt32[] target;
byte[] decoded = new byte[target.Length * 2];
Buffer.BlockCopy(target, 0, decoded, 0, target.Length);
And this doesn't work, I get array filled with 0x00.
I would recommend something like the following:
UInt32[] target;
//Assignments
byte[] decoded = new byte[target.Length * sizeof(uint)];
Buffer.BlockCopy(target, 0, decoded, 0, decoded.Length);
See code:
uint[] target = new uint[] { 1, 2, 3 };
//Assignments
byte[] decoded = new byte[target.Length * sizeof(uint)];
Buffer.BlockCopy(target, 0, decoded, 0, decoded.Length);
for (int i = 0; i < decoded.Length; i++)
{
Console.WriteLine(decoded[i]);
}
Console.ReadKey();
Also see:
Size of values
Int Array to Byte Array
BlockCopy MSDN
You can use BitConverter.GetBytes method for converting a unit to byte
Try this code. It works for me.
UInt32[] target = new UInt32[]{1,2,3};
byte[] decoded = new byte[target.Length * sizeof(UInt32)];
Buffer.BlockCopy(target, 0, decoded, 0, target.Length*sizeof(UInt32));
foreach(byte b in decoded)
{
Console.WriteLine( b);
}
You need to multiple by 4 to create your byte array, since UInt32 is 4 bytes (32 bit). But use BitConverter and fill a list of byte and late you can create an array out of it if you need.
UInt32[] target = new UInt32[] { 1, 2, 3 };
byte[] decoded = new byte[target.Length * 4]; //not required now
List<byte> listOfBytes = new List<byte>();
foreach (var item in target)
{
listOfBytes.AddRange(BitConverter.GetBytes(item));
}
If you need array then:
byte[] decoded = listOfBytes.ToArray();
Your code has a few errors:
UInt32[] target = new uint[] { 1, 2, 3, 4 };
// Error 1:
// You had 2 instead of 4. Each UInt32 is actually 4 bytes.
byte[] decoded = new byte[target.Length * 4];
// Error 2:
Buffer.BlockCopy(
src: target,
srcOffset: 0,
dst: decoded,
dstOffset: 0,
count: decoded.Length // You had target.Length. You want the length in bytes.
);
This should yield what you're expecting.
Related
I have a byte array result. I would like to convert my type called Info which are all int to the byte array but all of them are in different size.
a = 4 bytes
b = 3 bytes
c = 2 bytes
d = 1 bytes
This is the code I've tried.
private byte[] getInfoByteArray(Info data)
{
byte[] result = new byte[10];
BitConverter.GetBytes((data.a)).CopyTo(result, 0);
BitConverter.GetBytes((data.b)).CopyTo(result, 4);
BitConverter.GetBytes((data.c)).CopyTo(result, 7);
result [9] = Convert.ToByte(data.d);
return result;
}
However, I found out that BitConverter.GetBytes returns 4 bytes.
Are there any general solutions that can get different size of bytes to a byte array?
Use Array.Copy(Array, Int32, Array, Int32, Int32) method:
byte[] result = new byte[10];
Array.Copy(BitConverter.GetBytes(data.a), 0, result, 0, 4);
Array.Copy(BitConverter.GetBytes(data.b), 0, result, 4, 3);
Array.Copy(BitConverter.GetBytes(data.c), 0, result, 7, 2);
Array.Copy(BitConverter.GetBytes(data.d), 0, result, 9, 1);
This assumes little endian hardware. If your hardware is big endian, use
byte[] result = new byte[10];
Array.Copy(BitConverter.GetBytes(data.a), 0, result, 0, 4);
Array.Copy(BitConverter.GetBytes(data.b), 1, result, 4, 3);
Array.Copy(BitConverter.GetBytes(data.c), 2, result, 7, 2);
Array.Copy(BitConverter.GetBytes(data.d), 3, result, 9, 1);
I want to convert a two dimensional int array to a byte array. what is the most simple way to do so? Example:
int[,] array = new int[2, 2] { { 2, 1 }, { 0, 1 } };
How can i convert array to a byte[]? On your answer, please include also the reverse function to that. (if there is a function to convert an int[,] to a byte[] please show me also how to convert a byte[] to an int[,] )
If you're asking yourself why do i need to do it: i need to send a int[,] over a TCP client to a server, then send a response to the client
PS: I thought about making a [Serializeable] class, which will contain the int[,], then serialize the class into a file and send that file, on the server side i will deserialize that file and get the array from there. but i thought that it would take a lot more resrouces to do that then just converting it to a byte[].
Thank you for your help! :)
Short answer: Buffer.BlockCopy.
public static byte[] ToBytes<T>(this T[,] array) where T : struct
{
var buffer = new byte[array.GetLength(0) * array.GetLength(1) * System.Runtime.InteropServices.Marshal.SizeOf(typeof(T))];
Buffer.BlockCopy(array, 0, buffer, 0, buffer.Length);
return buffer;
}
public static void FromBytes<T>(this T[,] array, byte[] buffer) where T : struct
{
var len = Math.Min(array.GetLength(0) * array.GetLength(1) * System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), buffer.Length);
Buffer.BlockCopy(buffer, 0, array, 0, len);
}
If you aren't afraid of using unsafe code it's really simple:
int[,] array = new int[2, 2];
//Do whatever to fill the array
byte[] buffer = new byte[array.GetLength(0) * array.GetLength(1) * sizeof(int)];
fixed (void* pArray = &array[0,0])
{
byte* pData = (byte*)pArray;
for (int buc = 0; buc < buffer.Length; buc++)
buffer[buc] = *(pData + buc);
}
static void Main(string[] args)
{
FileStream fs = File.Open(#"C:\Skrillex - Rock n' Roll (Will Take You to the Mountain).mp3", FileMode.Open);
BinaryReader br = new BinaryReader(fs);
byte[] tag = new byte[3];
byte[] version = new byte[2];
byte[] flags = new byte[1];
byte[] size = new byte[4];
byte[] frameId = new byte[4];
byte[] frameSize = new byte[4];
byte[] frameFlags = new byte[2];
br.Read(tag, 0, tag.Length);
br.Read(version, 0, version.Length);
br.Read(flags, 0, flags.Length);
br.Read(size, 0, size.Length);
br.Read(frameId, 0, frameId.Length);
br.Read(frameSize, 0, frameSize.Length);
br.Read(frameFlags, 0, frameFlags.Length);
ulong iSize = (ulong)frameSize[0] << 21 | (ulong)frameSize[1] << 14 | (ulong)frameSize[2] << 7 | (ulong)frameSize[3];
Console.WriteLine("Frame Data Size : " + iSize.ToString());
byte[] body = new byte[iSize];
br.Read(body, 0, body.Length);
Console.WriteLine(BitConverter.ToString(body));
Console.WriteLine(ConvertHexToString(BitConverter.ToString(body)));
br.Close();
}
public string ConvertHexToString(string HexValue)
{
string StrValue = "";
HexValue = HexValue.Replace("-", "");
while (HexValue.Length > 0)
{
StrValue += Convert.ToChar(Convert.ToUInt32(HexValue.Substring(0, 2), 16)).ToString();
HexValue = HexValue.Substring(2, HexValue.Length - 2);
}
return StrValue;
}
I am writing the code for reading ID3v2.3 tags without external library or Shell32.
The above code is that code, but it seems not to work properly.
The following is the result when I run the code:
Frame Data Size : 91
01-FF-FE-52-00-6F-00-63-00-6B-00-20-00-6E-00-27-00-20-00-52-00-6F-00-6C-00-6C-00-20-00-28-> 00-57-00-69-00-6C-00-6C-00-20-00-54-00-61-00-6B-00-65-00-20-00-59-00-6F-00-75-00-20-00-74-> 00-6F-00-20-00-74-00-68-00-65-00-20-00-4D-00-6F-00-75-00-6E-00-74-00-61-00-69-00-6E-00-29-00
ÿþR
It is not returning the song title "Rock n' Roll (Will Take You to the Mountain)" that was recorded in the tag.
What is problem?
The 01 at the start indicates that it is encoded as UTF-16 (2 bytes per character). The next two bytes, FF FE, are the byte order mark so you can tell whether to interpret the byte pairs as most significant first or least significant first. After that you have the actual text data.
0052 - R
006F - o
0063 - c
006B - k
etc.
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;
...
How can generate a byte dynamically in c# code?
Format as below :
First byte is standard 88, second byte is the number of remaining byte, and the last one is the remaining bytes.
Example:
1 byte:
byte[] bytes = new byte[] { 0x88, 0x01, 0};
2 bytes:
byte[] bytes = new byte[] { 0x88, 0x02, 0, 0};
5 bytes:
byte[] bytes = new byte[] { 0x88, 0x05, 0, 0, 0, 0, 0};
Thank you.
Just this:
static byte[] Get(byte num)
{
byte[] a = new byte[num + 2];
a[0] = 0x88;
a[1] = num;
return a;
}
All the other bytes are initialized by default with 0.
If you have the data bytes in an array, you can create an array dynamically like this:
// data bytes
byte[] data = { 1, 2, 3 };
byte[] buffer = new byte[data.Length + 2];
buffer[0] = 0x88;
buffer[1] = (byte)data.Length;
data.CopyTo(buffer, 2);
If you create the data bytes in some other way, the first part of the code is the same, then just put the data in the rest of the array in the same way as the first two bytes. For example five zero bytes:
int len = 5;
byte[] buffer = new byte[len + 2];
buffer[0] = 0x88;
buffer[1] = (byte)len;
for (int i = 0; i < len; i++) {
buffer[i + 2] = 0;
}