Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Using sound Card's ADC with Alsa Api

Status
Not open for further replies.

julian403

Full Member level 5
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:

LA440.png

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

1000hz.png

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,

Seno44KHz.pngSeno44KHz.png


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.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top