element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Raspberry Pi
  • Products
  • More
Raspberry Pi
Raspberry Pi Forum Using ALSA for Custom Real Time Audio Effects
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Raspberry Pi to participate - click to join for free!
Featured Articles
Announcing Pi
Technical Specifications
Raspberry Pi FAQs
Win a Pi
Raspberry Pi Wishlist
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Not Answered
  • Replies 20 replies
  • Subscribers 676 subscribers
  • Views 3991 views
  • Users 0 members are here
  • logic
  • raspberry
  • real-time
  • c
  • audio
  • alsa
  • pi
  • guitar
  • cirrus
  • card
  • signal-processing
Related

Using ALSA for Custom Real Time Audio Effects

Former Member
Former Member over 10 years ago

Hi,

 

I am working on a project where I use a Cirrus Logic Audio Card with a Raspberry Pi to implement a reverberation effect for a guitar. The idea is to use the line in port of the Cirrus card to capture the data one sample at a time, put that sample through some custom C code that I have already finished, and then put the new sample out through the line out port. I have been having a lot of difficulty figuring out how to capture one sample at a time in real time in a way that I can run my C code on it. After reading and asking many questions and discussions I believe it might be necessary to write some custom C code within the ALSA development library. However, I am not experienced at this type of development and was wondering if anyone could help me figure out how to integrate my C code with ALSA so that I can perform real time custom audio effects. (Or if there is a way to do it without ALSA, that is also fine).

 

Thanks for any help,

 

Ryan

  • Sign in to reply
  • Cancel
Parents
  • mconners
    0 mconners over 10 years ago

    Another resource I found

     

    http://www.linuxjournal.com/article/6735?page=0,2

     

    for recording

     

    and

    Introduction to Sound Programming with ALSA | Linux Journal

     

    for playback

     

    Mike

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 10 years ago in reply to mconners

    That looks like a great find. I'm having trouble with compiling though. I think I need to use the -lasound flag, but whenever I try that I get:

     

    /usr/bin/ld: cannot find -lasound

    collect2: error: ld returned 1 exit status

     

    and I cannot figure out how to fix this.

     

    Ryan

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • mconners
    0 mconners over 10 years ago in reply to Former Member

    Hey Ryan, hopefully I'll get some time to play with this this evening. If so I'll post some pointers. I have no reason other than it piqued my interest. I was close on my initial assumptions, but I guess you need to use the alsa API open and not the unix open (or fopen). If you find anything out, post back so we can all learn.

     

     

    Mike

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • mconners
    0 mconners over 10 years ago in reply to mconners

    I was able to get the examples to compile, but first I had to run

     

    sudo apt-get install libasound2 libasound2-dev

     

    to make sure I had the libraries. Then I was able to compile on the pi without error.

     

    I had some runtim errors on the pi, but I don't have any sound hardware.

     

    Worked ok on my desktop.

     

    Mike

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Reply
  • mconners
    0 mconners over 10 years ago in reply to mconners

    I was able to get the examples to compile, but first I had to run

     

    sudo apt-get install libasound2 libasound2-dev

     

    to make sure I had the libraries. Then I was able to compile on the pi without error.

     

    I had some runtim errors on the pi, but I don't have any sound hardware.

     

    Worked ok on my desktop.

     

    Mike

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Children
  • Former Member
    0 Former Member over 10 years ago in reply to mconners

    Thanks! That worked right away, now onto figuring out how to grab one sample at a time and put it straight back out...

     

    Ryan

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 10 years ago in reply to mconners

    Here is the code I made that would hopefully pass audio straight through the raspberry pi, without any reverb yet. It doesn't work but I think I'm on the right track. I was kind of hoping that the Raspberry Pi Cirrus Logic interface was good enough that the cirrus board would be the default board after running a script that sets the default input and output to be the line in and line out on the board, but after running my code, I don't think that is what happened.

     

    I got this showing up over and over in terminal:

     

    short write: wrote -25 bytes

    error from read: Inappropriate ioctl for device

    short write: wrote -25 bytes

    error from read: Inappropriate ioctl for device

    underrun occurred

    short write: wrote -25 bytes

     

    I'm not sure if there is any easy fix, but if you have time or see anything obvious here is my code (specifically I'm confused about whether or not I need separate handle and params varaibles for the input and output, and I'm guessing that I didn't need two rc variables now that I think about it:

     

    /* Use the newer ALSA API */
    #define ALSA_PCM_NEW_HW_PARAMS_API
    
    #include <alsa/asoundlib.h>
    #include <stdio.h>
    
    int main() {
      long loops;
      int rc1, rc2;
      int size;
      snd_pcm_t *handle;
      snd_pcm_hw_params_t *params;
      unsigned int val;
      int dir;
      snd_pcm_uframes_t frames;
      char *buffer;
    
      /* Open PCM device for recording (capture). */
      rc1 = snd_pcm_open(&handle, "default",
      SND_PCM_STREAM_CAPTURE, 0);
      if (rc1 < 0) {
      fprintf(stderr,
      "unable to open pcm device: %s\n",
      snd_strerror(rc1));
      exit(1);
      }
    
      /* Open PCM device for playback. */
      rc2 = snd_pcm_open(&handle, "default",
      SND_PCM_STREAM_PLAYBACK, 0);
      if (rc2 < 0) {
      fprintf(stderr,
      "unable to open pcm device: %s\n",
      snd_strerror(rc2));
      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 channel (mono) */
      snd_pcm_hw_params_set_channels(handle, params, 1);
    
      /* 44100 bits/second sampling rate (CD quality) */
      val = 44100;
      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 */
      rc1 = snd_pcm_hw_params(handle, params);
      if (rc1 < 0) {
      fprintf(stderr,
      "unable to set hw parameters: %s\n",
      snd_strerror(rc1));
      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 = (char *) malloc(size);
    
      /* We want to loop for 5 seconds */
      snd_pcm_hw_params_get_period_time(params,
      &val, &dir);
      /* 5 seconds in microseconds divided by
      * period time */
      loops = 5000000 / val;
    
      while (loops > 0) {
      loops--;
      rc1 = snd_pcm_readi(handle, buffer, frames);
      if (rc1 == -EPIPE) {
      /* EPIPE means overrun */
      fprintf(stderr, "overrun occurred\n"); snd_pcm_prepare(handle);
      } else if (rc1 < 0) {
      fprintf(stderr, "error from read: %s\n", snd_strerror(rc1));
      } else if (rc1 != (int)frames) {
      fprintf(stderr, "short read, read %d frames\n", rc1);
      }
      rc2 = snd_pcm_writei(handle, buffer, frames);
      if (rc2 == -EPIPE) {
      /* EPIPE means underrun */
      fprintf(stderr, "underrun occurred\n");
      snd_pcm_prepare(handle);
      } else if (rc2 < 0) {
      fprintf(stderr,
      "error from writei: %s\n",
      snd_strerror(rc2));
      } else if (rc2 != (int)frames) {
      fprintf(stderr,
      "short write, write %d frames\n", rc2);
      }
      if (rc1 != size){
      fprintf(stderr, "short write: wrote %d bytes\n", rc1);
      }
      }
    
      snd_pcm_drain(handle);
      snd_pcm_close(handle);
      free(buffer);
    
      return 0;
    }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • mconners
    0 mconners over 10 years ago in reply to Former Member

    Nothing jumps out at me as wrong, but I won't be able to look at this in depth until later this evening.

     

     

    Mike

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • mconners
    0 mconners over 10 years ago in reply to Former Member

    One thing to check in the meantime, look for listing 2 in the examples I linked, it will dump the capabilities of the card, ensure it is capable of full duplex, you may have to open for read, read, close, open for write, write, close, etc...

     

    Mike

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • mconners
    0 mconners over 10 years ago in reply to mconners

    Hey Ryan, one other thing maybe to look at is Jack instead of ALSA.

     

    JACK Audio Connection Kit|Home

     

    It looks interesting at the very least.

     

    Mike

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 10 years ago in reply to mconners

    Hi Mike,

     

    I did have a couple of errors in my code, I needed two handle variables. Unfortunately that was only enough to get rid of some clear errors, it still doesn't really work. I have heard of JACK, maybe that is the way to go since it did seem like ALSA might have some inherent problems. My code kept having underrun errors and would output garbage, although I probably am using the buffers wrong .

     

    Ryan

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • mconners
    0 mconners over 10 years ago in reply to Former Member

    Yeah, I was looking at real time audio processing using ALSA and there were several articles about kernel tweaks to get the performance right. Jack didn't seem to have those same limitations. I looked over their website briefly, looks like there are some examples.

     

    Mike

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • mconners
    0 mconners over 10 years ago in reply to mconners

    Just for fun, I ran

     

    sudo apt-get install jack jackd1 libjack-dev

     

    dl'd https://github.com/jackaudio/jack2/blob/master/example-clients/simple_client.c

     

    which is supposed to pipe the input to the output

     

    and compiled using

    gcc -o simple_client simple_client.c -ljack -lm

     

    that may be a good starting point for you.

     

    http://jackaudio.github.io/api/

     

    search for simple_client.c in the above link

     

    Mike

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube