Using sound Card's ADC with Alsa Api

Status
Not open for further replies.

julian403

Full Member level 5
Joined
Feb 28, 2014
Messages
254
Helped
1
Reputation
2
Reaction score
1
Trophy points
18
Location
Argentina
Activity points
2,105
Hello. Someone has used Alsa's asoundlib.h APi to recorder sound from microphone?

What do you think about this code?

Code:
archivo=fopen("data.txt","w+");
	long loops;
	  int rc;
	  int size;
	  snd_pcm_t *handle;
	  snd_pcm_hw_params_t *params;
	  unsigned int val;
	  int dir;
	  snd_pcm_uframes_t frames;
	  int *buffer;

	  /* Open PCM device for recording (capture). */
	  rc = snd_pcm_open(&handle, "default",
	                    SND_PCM_STREAM_CAPTURE, 0);
	  if (rc < 0) {
	    fprintf(stderr,
	            "unable to open pcm device: %s\n",
	            snd_strerror(rc));
	    exit(1);
	  }

	  /* Allocate a hardware parameters object. */
	  snd_pcm_hw_params_alloca(&params);

	  /* Fill it in with default values. */
	  snd_pcm_hw_params_any(handle, params);

	  /* Set the desired hardware parameters. */

	  /* Interleaved mode */
	  snd_pcm_hw_params_set_access(handle, params,
	                      SND_PCM_ACCESS_RW_INTERLEAVED);

	  /* Signed 16-bit little-endian format */
	  snd_pcm_hw_params_set_format(handle, params,
	                              SND_PCM_FORMAT_S16_LE);

	  /* One channels */
	  snd_pcm_hw_params_set_channels(handle, params, 1);

	  /* 44100 bits/second sampling rate (CD quality) */
	  val = 1000;
	  snd_pcm_hw_params_set_rate_near(handle, params,
	                                  &val, &dir);

	  /* Set period size to 32 frames. */
	  frames = 32;
	  snd_pcm_hw_params_set_period_size_near(handle,
	                              params, &frames, &dir);

	  /* Write the parameters to the driver */
	  rc = snd_pcm_hw_params(handle, params);
	  if (rc < 0) {
	    fprintf(stderr,
	            "unable to set hw parameters: %s\n",
	            snd_strerror(rc));
	    exit(1);
	  }

	  /* Use a buffer large enough to hold one period */
	  snd_pcm_hw_params_get_period_size(params,
	                                      &frames, &dir);
	  size = frames * 4; /* 2 bytes/sample, 2 channels */
	  buffer = ( int *) malloc(size);

	  /* We want to loop for 5 seconds */
	  snd_pcm_hw_params_get_period_time(params,
	                                         &val, &dir);
	  loops = 5000000 / val;
      int i=0;
	  while (loops > 0) {
	    loops--;
	    i++;
	    rc = snd_pcm_readi(handle, buffer, frames);

	    for(int i=0; i<32; i++)
	    { fprintf(archivo, "%d", buffer[i]);
  	    fprintf(archivo, "\n");}

	    if (rc == -EPIPE) {
	      /* EPIPE means overrun */
	      fprintf(stderr, "overrun occurred\n");
	      snd_pcm_prepare(handle);
	    } else if (rc < 0) {
	      fprintf(stderr,
	              "error from read: %s\n",
	              snd_strerror(rc));
	    } else if (rc != (int)frames) {
	      fprintf(stderr, "short read, read %d frames\n", rc);
	    }
	    rc = write(1, buffer, size);
	    if (rc != size)
	      fprintf(stderr,
	              "short write: wrote %d bytes\n", rc);
	  }

	  snd_pcm_drain(handle);
	  snd_pcm_close(handle);
	  free(buffer);


	  fclose(archivo);
	return mraa::SUCCESS;
}

As you can see, the data is put to buffer. I can see the values in data.txt but the signal have straing form. I put a sin like sound in microphone.

Maybe the thing here is that I do not know where to read well the data from adc
 
Last edited:

ADCs usually use either 2's complement, offset binary, or straight binary. If the data appears funny it's usually because you are interpreting it in the wrong format.
 

Ok, I thought that but That's an example of

**broken link removed**

they take tha data type of the buffer as char.

- - - Updated - - -

With that code, I put a pure tone of 440Hz and I got, the net image:



then I put a signal of 1KHz and I got:



what do you think?
 

Maybe you aren't processing the buffer fast enough and are getting an overrun (i.e. a buffer overflow) that is resulting in dropped data? I'm not a software type (I'm a hardware type) so I'm not even going to attempt to check the code at the link you provided. Being I design hardware I normally process the data as fast as it arrives from an ADC so I don't run into overrun problems.
 

The code is fine! the problem was the microphone's sensitivity. It's was at -124dB and increasing it to -114dB I get the next signal at 44KHz sample rate,




I'm a hardware type

jejej I like hardware more too, but if you look fine software and hardware are the same. For example, this case that the problem was the microphone gain. 8-O
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…