Robotics StackExchange | Archived questions

Make a beep sound - ROS C++ Ubuntu

I would like to make a beeping sound when my timer reaches a certain value. I tried the simple '/a' but this does not work. Can anyone suggest how to make this work or perhaps some other way of making a beep sound? The lines I tried are :

std::cout << '\a' << std::endl;
std::cout << "Beeping \a" << std::endl;

I do see the "Beeping" output on console, just no sound. And yes, sounds in general do work well on my computer, I tried ;)

BTW, I have tried sound_play package to play a .wav file and found it to be somewhat unreliable, therefore I settled to get just a simple beep for now.

EDIT: I also tried ncurses, but it is apparently incompatible with qt environemnt and I got errors with qtextformat.h (which wasn't even realted!) so I had to get rid of it.

I launch this node from a launch file like so :

<?xml version="1.0"?>

<launch>

  <group ns="sensors_recorder_gui">
    <node name="sensors_recorder_gui" output="screen" pkg="rqt_gui" type="rqt_gui" args="-s sensors_recorder_gui" />
  </group>

</launch>

It is to be noted that this is an RQT widget application (I have come across QSound library but could not get the include to work, but perhaps that should be a different question.)

Many thanks for any great suggestions!

Asked by Tejas Kumar shastha on 2018-08-09 09:42:12 UTC

Comments

Answers

https://stackoverflow.com/questions/9981087/simple-c-sound-api suggests SDL_Mixer, I tried that out and the results are here: https://github.com/lucasw/sdl2_ros . It wasn't completely trivial to use SDL2 (maybe SDL would have been easier) see #q253311 .

  if (SDL_Init(SDL_INIT_AUDIO) < 0)
  {
    ROS_ERROR_STREAM("Couldn't initialize SDL " << SDL_GetError());
    return -1;
  }

  if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
  {
    ROS_ERROR_STREAM("Couldn't initialize SDL audio " << Mix_GetError());
    return -2;
  }

  std::string sound_file = "test.wav";
  ros::param::get("~sound", sound_file);

  Mix_Chunk* sound = NULL;
  sound = Mix_LoadWAV(sound_file.c_str());
  if (!sound)
  {
    ROS_ERROR_STREAM("Couldn't load sound" << sound_file << ", " << Mix_GetError());
    return -3;
  }

  Mix_PlayChannel(-1, sound, 0);
  while (ros::ok())
  {
    if (!Mix_Playing(-1))
      break;
    ros::Duration(0.2).sleep();
  }
  // shutdown
  Mix_FreeChunk(sound);
  sound = NULL;
  Mix_Quit();
  SDL_Quit();

There didn't turn out to be anything ros specific here, I don't think there should be any problem putting something like the above into an rqt plugin. But if there was, would there be anything wrong with separating the sound playback from the plugin and use a topic to trigger the sound? In that case ncurses or perhaps the '\a' could be made to work in standalone nodes if not in a plugin.

Asked by lucasw on 2018-08-11 08:22:19 UTC

Comments

Thank you for the really descriptive answer! I would prefer to avoid using relatively complex libraries like SDL since all I really want is just a simple BEEP when my timer runs out :D. To that end, it would be nice if I could somehow get the easier options to work out. (contd...)

Asked by Tejas Kumar shastha on 2018-08-13 06:42:58 UTC

(...contd) Failing the simple approach, perhaps I could indeed try ncurses with a non qt node over a topic or a service. The /a option, as far as the internet has taught me, is rather hardware and terminal application dependent. If none of these pan out, I suppose SDL is my only option then. Thanks!

Asked by Tejas Kumar shastha on 2018-08-13 06:45:39 UTC