0

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?

2
  • 1
    What are the ranges of your double values? Note that if they're between, say, 0.000000 and 0.9999999 the cast to int will convert all of them to 0. Commented Nov 15, 2009 at 17:34
  • Does this work if you just use a function to return an int value of p? I.e. buffer[i] = double_to_int(*p) ? I think gcc is optimizing your intention away. Commented Nov 15, 2009 at 17:38

5 Answers 5

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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?

Comments

1

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 );
}

1 Comment

BTW, I once found that on musicdsp.org/archive.php?classid=5#81 - this website is a good source for dsp related code snippets
0

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.

1 Comment

What does it mean to be PCM encoded? The data comes from libsndfile. Does that make it PCM encoded?
0

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

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.