tags:

views:

142

answers:

5

I have a double pointer data->mono_channel, where I would like to cast all the doubles to integers and put them in an array.

int frames = data->audio_info_save->frames;
short buffer[frames];
double* p;
int i = 0;
for (p = &(data->mono_channel)[0]; p < &(data->mono_channel)[frames]; p++) {
  buffer[i] = (int) *p;
  i++;
}

The purpose is that ALSA takes an integer array of samples, and my samples are in doubles.

if ((err = snd_pcm_writei(playback_handle, buffer, frames)) != frames) {
  fprintf(stderr, "write to audio interface failed (%s)\n", snd_strerror(err));
  exit(1);
}

So somehow I need my doubles to be casted to integers.

I don't hear any sound. So is the casting done correctly?

+1  A: 

The samples probably need to be scaled from [-1,1] to [min, max], where min and max are minimum and maximum integer values for integer samples.

MSN
+1  A: 

If data->mono_channel is an array of doubles, the casting is correct (although your code is overly complicated -- you should just use index i as the control variable in the loop, and use it to index the input array of doubles as well as the resulting array of ints).

The resulting silence may be due to the input doubles not being in the right range (i.e., you might need some scaling!). What do you see if you print out some of those doubles?

Alex Martelli
A: 

It looks okay, it'd be easier to just:

for (i = 0; i < frames; i++) {
  buffer[i] = (int)pdata->mono_channel[i];
}

Is the data PCM encoded? That might be your problem.

paul
What does it mean to be PCM encoded? The data comes from libsndfile. Does that make it PCM encoded?
Louise
A: 

Your buffer is of type short[]. Have you configured ALSA PCM to expect 16bit values? Have a look at this example from ALSA project.

Miroslav Bajtoš
That's a really cool example. Now I at least get some noise =) Thanks a lot for this. I will build on top of this instead.
Louise
+1  A: 

You probably have to scale and clip the input values, clipping can be quite slow, but there's a trick. So if your input is in range[-1,1], then you may use the following code:

double fclip( double value, double start, double end ) {
  return 0.5 * ( fabs(value-start) + (start+end) - fabs(value-end) );
}
...
for( i = 0; i < frames; i++ ) {
  buffer[i] = (short)fclip( 32767.0 * pdata->mono_channel[i], -32767, +32768 );
}
frunsi
WOW! That's fantastic. Thanks =)
Louise
BTW, I once found that on http://musicdsp.org/archive.php?classid=5#81 - this website is a good source for dsp related code snippets
frunsi