I am developing an app which uses simple pitch perception and it runs fine in the Xcode Simulator. The app loads in the iPhone 4 and I can navigate the app but no output is shown . I have started to debug and find that when I convert Sint16 to float I get an overflow error.
I have tried vDSP and a simple loop.
simplified code n=1536
sampleBuffer = (SInt16*) malloc(n);
floatSamples = (float*) malloc(sizeof(float)*n);
// Convert SInt 16 to float
for(int i = 0; i<n; i++) {
floatSamples[i] = (float)samples[i];
}
//vDSP_vflt16(samples,1,floatSamples,1,n);
This results in
-0.000000
-0.000000
-0.000000
964957789008661674961361960960.000000
-5629971079108504200413184.000000
-inf
35116851871418647838720.000000
-inf
0.000000
0.000000
0.000000
-1233.760620
288987875649316726325339192557568.000000
-0.000000
-0.000000
-0.000000
-7508525217561044282816045485425426432.000000
-656399043038732589927376093184.000000
0.000000
-0.000053
9470091451011432448.000000
-24555002
similar result from vDSP
Everything is fine in the simulator on iPhone 4s all the vDSP calculations work.
iPhone is running ios7.1.2 and xCode 6 on MacBook pro.
Just looking for a clue really.
The code
sampleBuffer = (SInt16*) malloc(n);
allocates n bytes, not n SInt16 values.
You need:
sampleBuffer = (SInt16*) malloc(sizeof(SInt16)*n);
Related
I am testing my laptop integrated cam, and after writing this simple code, FrameRates doesn't match. It shows that it's 30fps, but after calc I can see it's the half, 15fps. This is the code:
vid = videoinput('winvideo',1);
frameRates = set(getselectedsource(vid), 'FrameRate')
vid.FramesPerTrigger = 30;
start(vid); [frames, timeStamp] = getdata(vid);
frameRateCalc = 1/mean(diff(timeStamp))
And this is the output
>> framerate
frameRates =
'30.0000'
frameRateCalc =
15.2007
I have tested with another external cam and seems to work fine, 30 match with 30. Anybody knows why they doesn't match with the integrated cam?
The playback of my Matlab VideoPlayer is too fast and shows people walking twice as fast. I tried adjusting .FrameRate but no effect. Am working with Windows 7 64-bit computer, and playing back using Windows Media Player.
Here is code:
%// Init:
detection_video_file = VideoWriter( 'my_file');
writerObj.FrameRate = 10; % but 100 60 30 don't have an effect
open( detection_video_file );
%// The loop
writeVideo( detection_video_file, dispFrame );
%// And finally:
close( detection_video_file );
Here is the correction:
detection_video_file.FrameRate = 5;
This question already has answers here:
How to create a 2D-matrix out of my data for surf()?
(2 answers)
Closed 8 years ago.
I have a set of 3D data which are not ordered. I need to plot a surface which basically connects them together and color the surface based on my z values.
Here is an example of the data that I have.
-0.144847 -5.239271 -0.000000
-5.430672 -0.044747 0.000000
0.006860 0.282666 -0.000000
0.385219 0.005522 -0.000000
-6.464983 -7.105215 -0.000000
-7.028026 -4.026576 0.000000
-6.092855 -1.826723 -0.000000
-5.619010 -0.886051 0.000000
-5.769190 -0.487232 0.000000
-3.496163 -7.561789 -0.000000
-1.883844 -7.683578 0.000000
-0.845860 -6.159235 -0.000000
-0.487085 -5.865159 0.000000
-5.442694 0.346838 -0.000000
0.158343 -5.402572 -0.000000
0.075667 0.309257 0.000000
0.648079 -1.368195 0.000000
0.510721 -0.525318 0.000000
-0.749283 0.435931 0.000000
-0.338834 0.399974 -0.000000
-0.151157 0.367955 0.000000
-0.071820 0.371475 0.000000
-0.125133 -4.846842 -1.025075
-5.425106 0.058539 -0.341047
0.006806 0.282034 -0.057553
0.384929 0.005456 -0.021184
-5.890619 -6.417012 -0.339540
-6.828500 -3.837339 -0.394468
-6.048110 -1.732177 -0.362965
-5.597372 -0.822289 -0.333655
-5.815376 -0.394711 -0.360211
-3.447449 -7.345610 -0.198281
-1.883239 -7.680056 -0.098589
-0.845817 -6.153723 -0.041199
-0.487017 -5.863854 -0.019289
-5.475775 0.419626 -0.104516
0.159202 -5.400629 -0.017949
0.189255 0.205864 -0.010534
0.280893 0.151170 -0.015441
0.327987 0.090052 -0.018171
0.128256 0.272671 -0.006972
0.075667 0.309256 -0.003940
0.652881 -2.917007 -0.040059
0.647424 -1.368548 -0.037539
0.510386 -0.525737 -0.029055
0.546600 -0.273572 -0.030561
0.448142 -0.108028 -0.024821
-1.643195 0.460307 -0.102182
-0.751135 0.435615 -0.045282
-0.326989 0.388574 -0.019874
-0.151168 0.367766 -0.009394
-0.071815 0.371646 -0.004734
-0.125133 -4.846842 -1.025075
-5.425106 0.058539 -0.341047
0.006806 0.282034 -0.057553
0.384929 0.005456 -0.021184
-5.890619 -6.417012 -0.339540
-6.828500 -3.837339 -0.394468
-6.048110 -1.732177 -0.362965
-5.597372 -0.822289 -0.333655
-5.815376 -0.394711 -0.360211
-3.447449 -7.345610 -0.198281
-1.883239 -7.680056 -0.098589
I have around 400 points, like the ones above.
Thank you in advance for your help.
What format is your data in and what kind of plot do you want? Once you have separated the data into 3 variables it is simple to plot it into a 3-D scatter plot and specify the color using:
scatter3(X,Y,Z,S,C)
More info is available on the mathworks website which is SUPER useful for figuring out MATLAB
I draw 2560 very slim polygons for each frame on an iPhone 4S using OpenGL ES. The problem is that I'm getting framerates around 30, which is not smooth enough for my taste. I think it should be faster than that.
Is that right?
Please help me finding out what can be improved.
UPDATE: I do the rendering on the main thread. Are there any recommendations on which thread to perform the rendering operations?
A bit background:
I'm trying to make a smoothly scrolling (target is 60 FPS) waveform of size 320x200 in iPhone view coordinates, so 640x400 pixels on a retina display.
My test device is an iPhone 4S. With iOS 6 and 6.1, I could achieve this easily with normal UIKit drawing operations. However, since I updated the device to iOS 7, it got much slower, so I decided to use OpenGL ES, because I read lots of times that it allows faster 2D drawing.
I implemented drawing the waveform with OpenGL ES 2.0, but now it's just a slight bit faster on the device than with UIKit. And like with UIKit, the speed greatly depends on the number of pixels being drawn to, which makes me wonder what's going on.
The waveform is composed out of bars/rectangles, each of them is exactly 1 pixel in width. I draw two bars per pixel column, and each bar consists of two polygons, which means I draw 1280 bars, or 2560 polygons for each frame. The polygons are extremely slim. Each of them is at most 1 pixel wide. I think this should be no problem to draw at 60FPS with OpenGL ES.
I draw one bar like this:
- (void) glFillRect: (Float32)x0 : (Float32)y0 : (Float32)x1 : (Float32)y1 {
glEnableVertexAttribArray(GLKVertexAttribPosition);
GLfloat vertices[8];
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, vertices);
GLfloat* vp = vertices;
*vp++ = x0; *vp++ = y0;
*vp++ = x1; *vp++ = y0;
*vp++ = x0; *vp++ = y1;
*vp++ = x1; *vp++ = y1;
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(GLKVertexAttribPosition);
}
The code calling the above method is below. _maxDrawing and _avgDrawing are my effects, which are composed like this at app startup time:
_maxDrawing = [[GLKBaseEffect alloc] init];
_maxDrawing.useConstantColor = GL_TRUE;
_maxDrawing.constantColor = GLKVector4Make(0.075f, 0.1f, 0.25f, 1.0f);
I later adjust the projection matrix so that my drawing coordinates for OpenGL ES line up with the view coordinates of my view, which, afaik, is the standard way to go for 2D drawing.
[_maxDrawing prepareToDraw];
x_Cu = [self transformViewXToWaveformX:rect.origin.x];
for (Float32 x_Vu = rect.origin.x; x_Vu < viewEndX_Vu; x_Vu += onePixelInViewUnits) {
x_Cu += onePixelInContentUnits;
if (x_Cu < 0 || x_Cu >= waveformEndX_Cu) {
continue;
}
SInt64 frameIdx = (SInt64) x_Cu;
CBWaveformElement element;
element = [self.dataSource getElementContainingFrame:frameIdx];
prevMax = curMax;
curMax = futureMax;
futureMax = element.max;
smoothMax = prevMax * 0.25 + curMax * 0.5 + futureMax * 0.25;
if (smoothMax < curMax)
smoothMax = curMax;
Float32 barHeightHalf = smoothMax * heightScaleHalf;
Float32 barY0 = viewHeightHalf - barHeightHalf;
Float32 barY1 = viewHeightHalf + barHeightHalf;
[self glFillRect: x_Vu : barY0 : x_Vu + onePixelInViewUnits : barY1];
}
[_avgDrawing prepareToDraw];
x_Cu = [self transformViewXToWaveformX:rect.origin.x];
for (Float32 x_Vu = rect.origin.x; x_Vu < viewEndX_Vu; x_Vu += onePixelInViewUnits) {
x_Cu += onePixelInContentUnits;
if (x_Cu < 0 || x_Cu >= waveformEndX_Cu) {
continue;
}
SInt64 frameIdx = (SInt64) x_Cu;
CBWaveformElement element;
element = [self.dataSource getElementContainingFrame:frameIdx];
Float32 barHeightHalf = element.avg * heightScaleHalf;
Float32 barY0 = viewHeightHalf - barHeightHalf;
Float32 barY1 = viewHeightHalf + barHeightHalf;
[self glFillRect: x_Vu : barY0 : x_Vu + onePixelInViewUnits : barY1];
}
When I take out all the OpenGL calls, the execution duration for one frame is around 1ms, which means it could theoretically go up to 1000 FPS. All other time (around 33ms) is spent drawing.
Per Daniel's request, I'm posting this as an answer to close the question out.
In the above code, it appears that you're using a glDrawArrays() call per each box. This incurs a significant amount of overhead with a lot of boxes.
A more efficient way to approach this would be to use a VBO (probably a dynamically updated one) containing all the vertices of a your scene, or at least a larger group of the boxes, and to draw all of those with a single call.
As rickster points out, iOS 7 adds some nice support for instancing, which could also be a help here.
Regarding whether or not to render on a background thread, in my experience I've usually seen significant performance boosts (10-40%, particularly on the multicore devices) when rendering my OpenGL ES scene on a background thread. Using a serial GCD queue, it's also pretty easy to do that in a safe manner.
I switched my code to use VBO and suddenly my sprites (2 triangle triangle-strip) have bad texture coordinates.
Disabling VBO makes the problem go away.
Note - I align my vertex and texture coordinate data to 4 bytes as specified in this link:
https://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html
This is a printout of the vertex data, it goes:
x, y, z, 0.0f, tu, tv, 0.0f, 0.0f
Vertex 0 -0.500000 0.500000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000
Vertex 1 -0.500000 -0.500000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Vertex 2 0.500000 0.500000 0.000000 0.000000 1.000000 1.000000 0.000000 0.000000
Vertex 3 0.500000 -0.500000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000
This is how I generate the VBOs:
m_numVertices = 4
m_stride = 8
glGenBuffers( 1, &m_vboVertices); // Generate our Vertex Buffer Object
glBindBuffer( GL_ARRAY_BUFFER, m_vboVertices); // Bind our Vertex Buffer Object
glBufferData( GL_ARRAY_BUFFER, (m_numVertices * m_stride) * sizeof(float), m_pVertexData, GL_STATIC_DRAW); // Set the size and data of our VBO and set it to STATIC_DRAW
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glGenBuffers( 1, &m_vboIndices );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_vboIndices );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte)*4, m_pIndices, GL_STATIC_DRAW );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
And this is how I render the sprite:
glBindBuffer(GL_ARRAY_BUFFER, m_vboVertices);
glVertexPointer( 3, GL_FLOAT, byteStride, BUFFER_OFFSET(0) );
glTexCoordPointer( 2, GL_FLOAT, byteStride, BUFFER_OFFSET(4) );
glBindBuffer(GL_ARRAY_BUFFER,0); // reset
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vboIndices );
glDrawElements(GL_TRIANGLE_STRIP, m_numVertices, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); // reset
BUFFER_OFFSET is defined as:
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
With VBO:
Without VBO:
Thanks.
Edit - After messing around a bit with the code, it appears that this problem also occurs when drawing using GL_TRIANGLES.
It appears that the problem is that I am not calculating the glTexCoordPointer offset in bytes. It should be:
glTexCoordPointer( 2, GL_FLOAT, byteStride, (char*)NULL + (4*sizeof(float)) );
The Macro BUFFER_OFFSET was incorrect.
Applying this fix solved the problem.