Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Xtremehobo

Weirdness with PCM waves, shorts, and ints

This topic is 5401 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Aight, so I think i've finally got the deal down with using 16-bit shorts to specify the amplitude of 16-bit-samples in PCM audio data, but I've got a strange problem in the source for a little program I wrote to create a simple line of samples that starts at full-negative amplitude then climbs all the way up to full-positive amplitude. [/source] The problem is that I'm only able to get it to either go from full-positive-amplitude to 0 amplitude, or full-negative-amplitude to 0-amplitude. Here's the source that generates it:
short halfwave[65536];
int current=0;

for(int i = -32768; i < 32768; i++)
{
  wave[current] = (short)i;
  current++;
}
Now, since in the PCM audio format, my samples are 16 bits each, that means there's 65536 possible values it could be (-32768 to +32768) (am I correct?). This should mean that if I were to create 65536 samples, with the value starting at -32768 and going all the way up to +32768, the part of the wave should go all the way from full-negative amplitude to full-positive amplitude. It's only going from full-negative to zero however. Pic: Ok, so here's a pic of what happens when I change the for statement to: for(int i=0; i<32768; i++) ... [/source] ok, so -32768 to +32768 only creates the bottom half of this line, but 0 to +32768 only creates the top. Why won't I get the whole thing when I do -32768 to +32768? I'm suspecting its a problem when I assign a 32-bit integer to a 16-bit short variable? Thanks, Matt Matt Carpenter Founder and CEO of nothing! Deviantart | My Site [edited by - Xtremehobo on February 26, 2004 10:05:55 PM] [edited by - Xtremehobo on February 26, 2004 10:06:27 PM]

Share this post


Link to post
Share on other sites
Advertisement
Answer #1, Look at the dis-assembly, and see for yurself what it's doing

Answer #2 -32768 = 0 (or 0x8000, not sure) as a short. Try -32767 (which equals 0x7FFF in hex)

You can't go from -32768 to 32768, that's 65357 numbers (including 0), so you're 1 over.

Hope you got it!


(EDIT, why don't you set i to a short? I don't get that at all.)

[edited by - beernutts on February 26, 2004 10:16:15 PM]

Share this post


Link to post
Share on other sites
Even if you do write that to a file, you won''t hear anything when you play it. You have to exceed about 60Hz for speakers, and 25Hz if you have a sub-woofer. That signal is about 0.34 Hz.

Share this post


Link to post
Share on other sites
quote:

Answer #2 -32768 = 0 (or 0x8000, not sure) as a short. Try -32767 (which equals 0x7FFF in hex)

You can't go from -32768 to 32768, that's 65357 numbers (including 0), so you're 1 over.

Hope you got it!



Aight, I tried -32768 and it still does the same thing. I also tried using a double and the same thing happened. When I try setting I as a short, however, I get lots of first-chance exception access violations.

edit1: I also tried an unsigned int and an unsigned short but the line stayed at an amplitude of -40 (whatever units those are...)

edit2: I just checked the values in wave[] and they all appear to be how they should be. Maybe its a problem with the way I'm writing my file?

here's the file writing source

ofstream myFile;
myFile.open("C:/wave.raw", ios::out | ios::binary);
myFile.write((const char*)wave, 65536);
myFile.close();

hmm.. maybe I shouldn't be casting it to a const char* (i.e. could the fact that I'm casting a 16-bit short to an 8-bit char have anything to do with it)?


[edited by - Xtremehobo on February 26, 2004 12:14:40 AM]

Share this post


Link to post
Share on other sites

short buffer[65536]={0};
short* wave = &buffer[32768];
for(int i=-32768; i<32768; ++i)
wave[i] = i;



though

double Hz = 400;
double amplitude = 32000;
static const int length = 100000;
short wave[length]={0};
for(int i=0; i<length; ++i)
wave[i] = i;
wave[i] = amplitude * sin(Hz * i*2.0*3.14159265358979323/44100.0);


Will produce something you can hear (caveat: sin and cos run into trouble when the parameter greatly exceeds 2pi).

[edited by - Magmai Kai Holmlor on February 26, 2004 12:49:52 AM]

Share this post


Link to post
Share on other sites
welllll that''s interesting...

your code actually creates waes that''ll go all the way from full negative amplitude to full positive... Im quite confused now as to why I can''t even draw a simple line that does it :-\

Share this post


Link to post
Share on other sites
Item #1:
You said you changed -32768 to -32768. Those are the same... did you change it to -32767? Just double checking .

Implementing your problem in OpenGL produced the expected result...

#include <SDL/SDL.h>
#include <GL/gl.h>
#include <stdlib.h>

int main ( int argc , char ** argv )
{
SDL_Init( SDL_INIT_EVERYTHING );
atexit( SDL_Quit );

short halfwave[65536];

int current = 0;
for ( int i = -32767 ; i < 32768 ; i ++ ) {
halfwave[current] = (short)i;
current++;
}

SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER , 1 );
SDL_SetVideoMode( 640 , 480 , 32 , SDL_OPENGL );
while ( true )
{
SDL_Event e;
while ( SDL_PollEvent( &e ))
{
switch ( e.type )
{
case SDL_QUIT:
case SDL_KEYDOWN:
return 0;
}
}

glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0 , 65536 , -32768 , 32768 , -1 , 1 );
//left = 0

//right = 65536

//bottom = -32768

//top = 32768

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glBegin( GL_QUADS );
for ( unsigned int i = 0 ; i < 65536 ; i ++ ) {
float c = ((float)halfwave[i])/65536+0.5;
glColor3f(c,c,c);
glVertex2f( i , halfwave[i] );
glVertex2f( i + 1 , halfwave[i + 1] );
glVertex2f( i + 1 , 0 );
glVertex2f( i , 0 );
}
glEnd();
SDL_GL_SwapBuffers();
}
}


The (expected) result: a graph filled in from black @ left bottom to white @ right top.

Share this post


Link to post
Share on other sites
Ok, I think I found the problem -- I think the software I''m using to view the audio file it outputs is just a bit buggy (ie not showing the full thing when theres something with a realllllllllly long wavelength.

I guess all''s good

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!