Naudio Buffer Full Exception in Naudio library while i am playing audio from byte array of .wav file - exception

Its work fine when i set delay 20 but wav file playing slowly in some systems with windows 10.
private static void waveSourceAgent_DataAvailable(object sender, WaveInEventArgs e)
{
int delay = 10;
recordedMsgBuffer = RECORDING_BUFFER[0].recordedMsgBuffer;
int iterations = recordedMsgBuffer.Length / 320;
int remainingBytes = recordedMsgBuffer.Length % 320;
byte[] buffer = new byte[320];
for (int i = 0; i < iterations; i++)
{
byte[] tempbuff = new byte[320];
for (int j = 0; j < 320; j++)
{
tempbuff[j] = recordedMsgBuffer[(i * 320) + j];
}
if (waveProviderReciever != null)
waveProviderReciever.AddSamples(tempbuff, 0, tempbuff.Length);
Thread.Sleep(delay);
}

Looks like you are trying to play data that's being received (but not sure exactly how - you're not using the DataAvailable args) by putting it into a BufferedWaveProvider.
The secret to this working is that the speed at which audio is being placed into the buffer should match the speed it is being read out. If the WaveFormat of record and playback match (which they need to for this to work) then the buffer should never fill up unless playback has unexpectedly stopped.
If you are receiving data much faster than you are playing it (e.g. you are downloading a pre-recorded audio file), then you either need to increase the buffer size, or hold off putting any new data into the buffer until there is more space available.

Related

RootBeer silently fails for large arrays?

I have a simple application that (for now) simulates error correction in a large array.
This bit generates the data and adds 16 bytes of Reed-Solomon parity to each block of 255 bytes.
ReedSolomonEncoder encoder = new ReedSolomonEncoder(QR_CODE_FIELD_256);
int[][] data = new int[params.getNumBlocks()][255];
int[][] original = new int[params.getNumBlocks()][];
int value = 0;
for (int i = 0; i < params.getNumBlocks(); i++) {
int[] block = data[i];
for (int j = 0; j < 239; j++) {
value = (value + 1) % 256;
block[j] = value;
}
encoder.encode(block, 16);
original[i] = Arrays.copyOf(block, block.length);
// Corrupt a byte
block[50] += 1;
}
This is my kernel:
public class RsKernel implements Kernel {
private final int[] block;
public RsKernel(int[] block) {
this.block = block;
}
#Override
public void gpuMethod() {
block[50] -= 1;
}
}
it merely manually reverts the corrupted byte in each block (it doesn't do actual Reed-Solomon error-correction).
I run the kernels with the following code:
ArrayList<Kernel> kernels = new ArrayList<>(params.getNumBlocks());
for (int[] block : data) {
kernels.add(new RsKernel(block));
}
new Rootbeer().run(kernels);
And I verify decoding with JUnit's assertArrayEquals:
Assert.assertArrayEquals(original, data);
The curious bit is that if I run this code with up to 8192 (what a suspiciously convenient number) blocks (kernels), the data is reported to have been decoded correctly; for 8193 blocks and above, it is not decoded correctly:
Exception in thread "main" arrays first differed at element [8192][50]; expected:<51> but was:<52>
at org.junit.Assert.internalArrayEquals(Assert.java:437)
at org.junit.Assert.internalArrayEquals(Assert.java:428)
at org.junit.Assert.assertArrayEquals(Assert.java:167)
at org.junit.Assert.assertArrayEquals(Assert.java:184)
at com.amphinicy.blink.rootbeer.RootBeerDemo.main(Jasmin)
What could cause this behaviour?
Here is the output of java -jar rootbeer-1.1.14.jar -printdeviceinfo:
device count: 1
device: GeForce GT 525M
compute_capability: 2.1
total_global_memory: 1073414144 bytes
num_multiprocessors: 2
max_threads_per_multiprocessor: 1536
clock_rate: 1200000 Hz
Looking at the code, I'm thinking it may be because the following:
// Corrupt a byte
block[50] += 1;
Could be adding one to 255, giving 256 which would not be a valid byte. Corrupting the byte might work better with something like this:
block[50] ^= 0x40;
Which would flip the bit in position 7 instead of adding to corrupt the byte.

Application crashes when I try to display multiple images with a for loop

I am trying to display multiple random grass tile images across the 1200 pixel width window. I am using a method called placeGrass which takes an image, an x coordinate, a y coordinate, and then displays the object at that given coordinate. This works correctly if I use my method getRandomGrass() (which returns a random grass tile image) and type in each coordinate by hand. However, when I try and use a method I made called printGrass(), the flash application fails to boot up.
Here is my attempt at the printGrass() method.
public function printGrass():void
{
var grass:Grass = new Grass(play);
for(var i:int = 0; i < 1200; i + 64)
{
grass.placeGrass(grass.getRandomGrass(), i, 800);
}
}
Where as my manual attempts below work correctly.
var test:Grass = new Grass(play);
test.placeGrass(test.getRandomGrass(), 0, 800);
var test2:Grass = new Grass(play);
test2.placeGrass(test2.getRandomGrass(), 64, 800);
I believe the for statement is never terminated because the counter does not increment the i variable.
for(var i:int = 0; i < 1200; i + 64)
should read
for(var i:int = 0; i < 1200; i += 64)
i + 64 will just return 64 each time where i += 64 will increment i each time.
I hope this helps.

An alternative to bitmapdata with less memory usage?

Im using a very big BitmapData as a pathing map for my platformer game, however I only use pixels for 4 particular values, instead of, well 4294967295.
Would converting this Bitmapdata as 2 2D Vectors of Boolean save me some memory ?
And if it does, what about performance, would it be faster or slower to do something like:
MapGetPixel(x:int, y:int):int
{
return MapBoolFirst[x][y] + MapBoolSecond[x][y]*2;
}
instead of the bitmapdata class getPixel32(x:int, y:int):uint ?
In short im looking for a way to reduce the size and/or optimize my 4 colors bitmapdata.
Edit :
Using my boolean method apparently consumes 2 times more memory than the bitmapdata one.
I guess a boolean takes more than one bit in memory, else that would be too easy. So im thinking about bitshifting ints and thus have an int store the value for several pixels, but im not sure about this…
Edit 2 :
Using int bitshifts I can manage the data of 16 pixels into a single int, this trick should work to save some memory, even if it'll probably hit performance a bit.
Bitshifting will be the most memory-optimized way of handling it. Performance wise, that shouldn't be too big of an issue unless you need to poll a lot of asks each frame. The issue with AS is that booleans are 4bits :(
As I see it you can handle it in different cases:
1) Create a lower res texture for the hit detections, usually it is okay to shrink it 4 times (256x256 --> 64x64)
2) Use some kind of technique of saving that data into some kind of storage (bool is easiest, but if that is too big, then you need to find another solution for it)
3) Do the integer-solution (I haven't worked with bit-shifting before, so I thought it would be a fun challenge, here's the result of that)
And that solution is way smaller than the one used for boolean, and also way harder to understand :/
public class Foobar extends MovieClip {
const MAX_X:int = 32;
const MAX_Y:int = 16;
var _itemPixels:Vector.<int> = new Vector.<int>(Math.ceil(MAX_X * MAX_Y / 32));
public function Foobar() {
var pre:Number = System.totalMemory;
init();
trace("size=" + _itemPixels.length);
for (var i = 0; i < MAX_Y; ++i) {
for (var j = 0; j < MAX_X; ++j) {
trace("item=" + (i*MAX_X+j) + "=" + isWalkablePixel(j, i));
}
}
trace("memory preInit=" + pre);
trace("memory postInit=" + System.totalMemory);
}
public function init() {
var MAX_SIZE:int = MAX_X * MAX_Y;
var id:int = 0;
var val:int = 0;
var b:Number = 0;
for(var y=0; y < MAX_Y; ++y) {
for (var x = 0; x < MAX_X; ++x) {
b = Math.round(Math.random()); //lookup the pixel from some kind of texture or however you expose the items
if (b == 1) {
id = Math.floor((y * MAX_X + x) / 32);
val = _itemPixels[id];
var it:uint = (y * MAX_X + x) % 32;
b = b << it;
val |= b;
_itemPixels[id] = val;
}
}
}
}
public function isWalkablePixel(x, y):Boolean {
var val:int = _itemPixels[Math.floor((y * MAX_X + x) / 32)];
var it:uint = 1 << (y * MAX_X + x) % 32;
return (val & it) != 0;
}
}
One simple improvement is to use a ByteArray instead of BitmapData. That means each "pixel" only takes up 1 byte instead of 4. This is still a bit wasteful since you're only needing 2 bits per pixel and not 8, but it's a lot less than using BitmapData. It also gives you some "room to grow" without having to change anything significant later if you need to store more than 4 values per pixel.
ByteArray.readByte()/ByteArray.writeByte() works with integers, so it's really convenient to use. Of course, only the low 8 bits of the integer is written when calling writeByte().
You set ByteArray.position to the point (0-based index) where you want the next read or write to start from.
To sum up: Think of the ByteArray as a one dimensional Array of integers valued 0-255.
Here are the results, I was using an imported 8 bit colored .png by the way, not sure if it changes anything when he gets converted into a
BitmapData.
Memory usage :
BitmapData : 100%
Double Boolean vectors : 200%
Int Bitshifting : 12%
So int bitshifting win hands down, it works pretty much the same way as hexadecimal color components, however in that case I store 16 components (pixel values in 2 bits) not the 4 ARGB:
var pixels:int = -1;// in binary full of 1
for (var i:int = 0; i < 16; i++)
trace("pixel " + (i + 1) +" value : " + (pixels >> i * 2 & 3));
outputs as expected :
"pixel i value : 3"

CUDA kernels not launching before CudaDeviceSynchronize

I am having some trouble with concurrent CUDA. Take a look at the attached image. The kernel is launched at the marked point, at 0.395 seconds. Then there is some green CpuWork. Finally, there is a call to cudaDeviceSynchronize. The kernels that is launched before CpuWork doesnt start before the synchronize call. Ideally, it should run in parallel with the CPU work.
void KdTreeGpu::traceRaysOnGpuAsync(int firstRayIndex, int numRays, int rank, int buffer)
{
int per_block = 128;
int num_blocks = numRays/per_block + (numRays%per_block==0?0:1);
Ray* rays = &this->deviceRayPtr[firstRayIndex];
int* outputHitPanelIds = &this->deviceHitPanelIdPtr[firstRayIndex];
kdTreeTraversal<<<num_blocks, per_block, 0>>>(sceneBoundingBox, rays, deviceNodesPtr, deviceTrianglesListPtr,
firstRayIndex, numRays, rank, rootNodeIndex,
deviceTHitPtr, outputHitPanelIds, deviceReflectionPtr);
CUDA_VALIDATE(cudaMemcpyAsync(resultHitDistances[buffer], deviceTHitPtr, numRays*sizeof(double), cudaMemcpyDeviceToHost));
CUDA_VALIDATE(cudaMemcpyAsync(resultHitPanelIds[buffer], outputHitPanelIds, numRays*sizeof(int), cudaMemcpyDeviceToHost));
CUDA_VALIDATE(cudaMemcpyAsync(resultReflections[buffer], deviceReflectionPtr, numRays*sizeof(Vector3), cudaMemcpyDeviceToHost));
}
The memcopies are async. The result buffers are allocated like this
unsigned int flag = cudaHostAllocPortable;
CUDA_VALIDATE(cudaHostAlloc(&resultHitPanelIds[0], MAX_RAYS_PER_ITERATION*sizeof(int), flag));
CUDA_VALIDATE(cudaHostAlloc(&resultHitPanelIds[1], MAX_RAYS_PER_ITERATION*sizeof(int), flag));
Hoping for a solution for this. Have tried many things, including not running in the default stream. When i added cudaHostAlloc i recognized that the async method returned back to the CPU. But that doesnt help when the kernel does not launch before the deviceSynchronize call later.
resultHitDistances[2] contains two allocated memory areas so that when 0 is read by the CPU, the GPU should put the result in 1.
Thanks!
Edit: This is the code that calls traceRaysAsync.
int numIterations = ceil(float(this->numPrimaryRays) / MAX_RAYS_PER_ITERATION);
int numRaysPrevious = min(MAX_RAYS_PER_ITERATION, this->numPrimaryRays);
nvtxRangePushA("traceRaysOnGpuAsync First");
traceRaysOnGpuAsync(0, numRaysPrevious, rank, 0);
nvtxRangePop();
for(int iteration = 0; iteration < numIterations; iteration++)
{
int rayFrom = (iteration+1)*MAX_RAYS_PER_ITERATION;
int rayTo = min((iteration+2)*MAX_RAYS_PER_ITERATION, this->numPrimaryRays) - 1;
int numRaysIteration = rayTo-rayFrom+1;
// Wait for results to finish and get them
waitForGpu();
// Trace the next iteration asynchronously. This will have data prepared for next iteration
if(numRaysIteration > 0)
{
int nextBuffer = (iteration+1) % 2;
nvtxRangePushA("traceRaysOnGpuAsync Interior");
traceRaysOnGpuAsync(rayFrom, numRaysIteration, rank, nextBuffer);
nvtxRangePop();
}
nvtxRangePushA("CpuWork");
// Store results for current iteration
int rayOffset = iteration*MAX_RAYS_PER_ITERATION;
int buffer = iteration % 2;
for(int i = 0; i < numRaysPrevious; i++)
{
if(this->activeRays[rayOffset+i] && resultHitPanelIds[buffer][i] >= 0)
{
this->activeRays[rayOffset+i] = false;
const TrianglePanelPair & t = this->getTriangle(resultHitPanelIds[buffer][i]);
double hitT = resultHitDistances[buffer][i];
Vector3 reflectedDirection = resultReflections[buffer][i];
Result res = Result(rays[rayOffset+i], hitT, t.panel);
results[rank].push_back(res);
t.panel->incrementIntensity(1.0);
if (t.panel->getParent().absorbtion < 1)
{
numberOfRaysGenerated++;
Ray reflected (res.endPoint() + 0.00001*reflectedDirection, reflectedDirection);
this->newRays[rayOffset+i] = reflected;
this->activeRays[rayOffset+i] = true;
numNewRays++;
}
}
}
numRaysPrevious = numRaysIteration;
nvtxRangePop();
}
This is the expected behavior on Windows with the WDDM driver model, where the driver tries to mitigate the kernel launch overhead by trying to batch kernel launches. Try inserting cudaStreamQuery(0) straight after the kernel invocation to trigger early launching of the kernel before the batch is full.

Windows Azure: Argument Exception was unhandled

I want my Azure application to create a blob and write a data into it. When I tried it I got this exception stating that
ArgumentException was unhandled
Stream was not writable
here is my code
var ms = new MemoryStream();
for (int k = 0; k < 10; k++)
{
using (StreamWriter sw = new StreamWriter(ms))
{
string val = k.ToString();
if (k + 1 != len)
val = val + " ";
sw.Write(val);
sw.Flush();
}
}
ms.Position = 0;
blob.UploadFromStream(ms);
My code is getting executed for k = 0. The exception is thrown when k = 1.
Can anyone tell me how to solve this exception
Moreover, Is this the correct procedure for writing onto the blob. If no, where am I went wrong and how to correct it.
My guess is that the Finalize method of StreamWriter closes the underlying stream (so next time through the loop, you can't write to that MemoryStream).
I think you can solve this by puting the "using (StreamWriter sw = new StreamWriter(ms))" block around the whole loop. It's presumably more efficient than creating a new StreamWriter each time anyway.
In any case, if you're just writing text, it might be better to do something like:
StringBuilder sb = new StringBuilder();
for (int k = 0; k < 10; k++)
{
sb.Append(k.ToString());
if (k + 1 != len) sb.Append(" ");
}
blob.UploadText(sb.ToString());
Or (for this particular use), get fancy. :-) (completely untested):
blob.UploadText(string.Join(" ", Enumerable.Range(0, 10).Select(k => k.ToString()).ToArray()));