ALSA tutorial required

痞子三分冷 提交于 2019-11-29 21:56:43

Just collecting some here, that have example code:

Note that some of these are old, and API may have changed in the meantime... you can also look up aplay.c (the source for the command line arecord and aplay), but that one is not the easiest to read for starters...

You'll have a tough time finding anything concrete on ALSA, as I have have found from just starting learning it too. The best place to begin is the ALSA project homepage where they link to a number of tutorials, the best one being Dr Nagorni's one IMO.

From what it sounds like you're trying to do, JACK would most likely be a quicker and easier solution, though.

Check out the docs. There are some good examples.

http://www.alsa-project.org/alsa-doc/alsa-lib/examples.html

Be aware of the safe alsa subset.

https://www.winehq.org/pipermail/wine-bugs/2009-June/179698.html

Here's something small I put together using the various sources I could find. It miiiiiiiiiight be a good starting point.

/* Compile with gcc -lasound -pthread threadaudio.c */

#include <alsa/asoundlib.h>
#include <pthread.h>
#include <stdio.h>

unsigned char audiobuffer[0x400];
pthread_mutex_t audiomutex = PTHREAD_MUTEX_INITIALIZER;

void changeaudio (int volume) {
  int i;
  pthread_mutex_lock(&audiomutex);
  for (i = 0; i < sizeof(audiobuffer); i++)
    audiobuffer[i] = (random() & 0xff) * volume / 10;
  pthread_mutex_unlock(&audiomutex);
}

void *startaudio (void *param)
{
  static char *device = "default";
  snd_output_t *output = NULL;
  int *audiostop = (int*)param;
  int err;
  snd_pcm_t *handle;
  snd_pcm_sframes_t frames;

  changeaudio(5);

  if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
    printf("Playback open error: %s\n", snd_strerror(err));
    exit(EXIT_FAILURE);
  }

  if ((err = snd_pcm_set_params(handle,
                SND_PCM_FORMAT_U8,
                SND_PCM_ACCESS_RW_INTERLEAVED,
                1,
                48000,
                1,
                100000)) < 0) {   /* 0.1sec */
    printf("Playback open error: %s\n", snd_strerror(err));
    exit(EXIT_FAILURE);
  }

  while (!*audiostop) {
    err = snd_pcm_wait(handle, 1000);
    if (err < 0) {
      fprintf (stderr, "poll failed (%d)\n", err);
      break;
    }

    pthread_mutex_lock(&audiomutex);
    frames = snd_pcm_writei(handle, audiobuffer, sizeof(audiobuffer));
    pthread_mutex_unlock(&audiomutex);

    if (frames < 0)
      err = snd_pcm_recover(handle, frames, 0);
    if (err < 0) {
      printf("snd_pcm_writei failed: %s\n", snd_strerror(err));
      break;
    }

    if (frames > 0 && frames < (long)sizeof(audiobuffer))
      printf("Short write (expected %li, wrote %li)\n", (long)sizeof(audiobuffer), frames);
  }
  snd_pcm_close(handle);  
}

int main(void)
{
  pthread_t audiothread;
  int audiostop = 0;
  int volume;

  pthread_create(&audiothread, NULL, startaudio, &audiostop);

  while (1) {
    printf("Enter volume 1 through 10. [0 to quit.]: ");
    scanf("%d", &volume);
    if (volume == 0) break;
    changeaudio(volume);
  }

  audiostop = 1;
  pthread_join(audiothread, NULL);

  return 0;
}

And after reading the code above you'll probably want to read this article regarding (among other things) not using locks.

http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!