ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

How to play a wav content with the bitrate of 256kbps by audio_play?

asked 2016-08-04 05:58:46 -0500

78226415 gravatar image

updated 2016-08-10 21:31:48 -0500

Hi every one, we provide a wav content with the bitrate of 16kbps for the audio_play to play, it is ok. Now, if the bitrate is another one, for example 256kbps, what shoud we do? Should we change the bitrate of the wav content? Should some one help me?

thanks

I have do some test like this:

I have put the test source codes to the github, every one can git them from : test bite rate for audio play.

My enviroment is: ubuntu 14.04 LTS, ros indigo.

First you should install the audio_common: sudo apt-get install ros-indigo-audio-common

Secondly, open the test_bite_rate_audio_play_server/src/test_bite_rate_audio_play_server.cpp, you will see the two lines codes:

FILE *fp_test = fopen("/home/turtlebot/catkin_ws/src/test_bite_rate_audio_play_server/res/test2.wav", "r"); // this is no sound, it's bite rate is 256kbps

//FILE *fp_test = fopen("/home/turtlebot/catkin_ws/src/test_bite_rate_audio_play_server/res/test1.wav", "r"); // this is ok, the bite rate is 16kbps

you should replace the file path for your local environment. Then build the packages.

Third, open a terminal and run : roscore

the next few new tap, you may be run the source: source /home/turtlebot/catkin_ws/devel/setup.bash

open a new tap and run: rosrun audio_play audio_play audio:=audio_content_publisher

open a new tap and run: rosrun audio_server audio_content_publish_server

open a new tap and run: rosrun test_bite_rate_audio_play_server test_bite_rate_audio_play_server

Then you should hear nothing, or see a message at the final tap terminal: Segmentation fault (core dumped)

Now, do the second test, it is nearly the same as the first test, common the first line and uncommon the second line, like this:

//FILE *fp_test = fopen("/home/turtlebot/catkin_ws/src/test_bite_rate_audio_play_server/res/test2.wav", "r"); // this is no sound, it's bite rate is 256kbps

FILE *fp_test = fopen("/home/turtlebot/catkin_ws/src/test_bite_rate_audio_play_server/res/test1.wav", "r"); // this is ok, the bite rate is 16kbps

when you run the final command, you will hear some sound.

The different of the two test is : the bite rate of wav files is different, one is 16kbps and the other is 256kbps, so some would help me? thanks

edit retag flag offensive close merge delete

Comments

Have you tried playing a 256kbps wav file to see if it works?

ahendrix gravatar image ahendrix  ( 2016-08-09 12:32:46 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted
2

answered 2016-08-11 00:17:37 -0500

ahendrix gravatar image

Firstly, audio_play was not designed to be used this way; it's really only designed as an endpoint for data from audio_capture (and it's barely good at that). If you want to play wave files or do text to speech, I suggest you start with sound_play and only move to audio_play if that doesn't work for you.

I was able to reproduce your issue with the instructions you provided; they're very complete!

I found two issues:

The first was that your program segfaults (memory error) when I try to run it. This is a bug in your program and not really related to the bit rate, but it only happened with the 256kbps file because it was a larger file. Your file read code was corrupting memory and crashing your program. You can see more details about this bu running your program with valgrind:

rosrun --prefix valgrind test_bite_rate_audio_play_server test_bite_rate_audio_play_server

Once I fixed your test program, the second thing I found is that audio_play expects all of the data at the same bit rate, so if you send it data at one bit rate it expects all of the data at that bit rate. This means that playing a 16kbps file and then a 256kbps file doesn't work. It also means that if you play a 256kbps file first, it works fine.

The fixed version of your program is:

int main (int argc, char **argv)
{
  ros::init(argc, argv, "test_bite_rate_audio_play_server");
  ros::NodeHandle _nh;
  ros::ServiceClient audioContentPublishClient = _nh.serviceClient<hlf_common_srv::AudioPublishData>("audio_content_publish_server");

  int total_count = 0;
  const int read_size = 1024;
  int buffer_size = read_size * 64; // initialize the buffer to 64k bytes
  char * audio_buffer = (char*)malloc(buffer_size); // allocate the initial buffer
  //the next two lines, you should replace the file path for your local environment
  FILE *fp_test = fopen("/home/turtlebot/catkin_ws/src/test_bite_rate_audio_play_server/res/test2.wav", "r"); // this is no sound, it's bite rate is 256kbps
  //FILE *fp_test = fopen("/home/turtlebot/catkin_ws/src/test_bite_rate_audio_play_server/res/test1.wav", "r"); // this is ok, the bite rate is 16kbps

  if (fp_test == NULL) {
    ROS_INFO("Open file failed");
    return 1;
  }

  int read_count = fread(audio_buffer, 1, read_size, fp_test);
  total_count = read_count;

  while(read_count == read_size)
  {
    // if there isn't enough space in the buffer for the next read, realloc
    // to increase the buffer size
    if(total_count + read_count > buffer_size) {
      buffer_size *= 2;
      audio_buffer = (char*)realloc(audio_buffer, buffer_size);
    }

    read_count = fread(audio_buffer + total_count, 1, read_size, fp_test);
    total_count += read_count;
  }

  fclose(fp_test);
  //ROS_INFO("wav data : %s \n", tts_receive_data); 
  ROS_INFO("total_count : %d \n", total_count);

  hlf_common_srv::AudioPublishData audio_publish_msg;
  audio_publish_msg.request.audioPlayContent = std::string( audio_buffer, total_count );
  audioContentPublishClient.call(audio_publish_msg);

  ROS_INFO("test server is over.");

  ros::spin();
}
edit flag offensive delete link more
0

answered 2016-08-12 02:54:57 -0500

78226415 gravatar image

updated 2016-08-12 02:55:58 -0500

Hi ahendrix, thank you very much.

As you said, i am doing tts(text to speech), i get the audio data and need to play it, there are two sources of audio data, one's bit rate is 16kbps and the other's is 256kbps, so i need to play them by audio_play. I put the audio data into a wave file so that some one else to reproduce the cases easily. Another way is to put the audio data into a wave file and then play it by sound_play if there is not a better way as you said.

I can reproduce the cases you did, and i found some issues.

The wave file with the bit rate of 256kbps, first, it doesn't play all the audio data, may be about the last 0.5 second of the all wave file data can not be heard, if you play it the second time, it only play the last 0.5 second of the all wave file data.

Second, also with the wave file with the bit rate of 256kbps, if you play the first case the third time, forth time, or more, you can hear nothing unless you restart the audio_play: rosrun audio_play audio_play audio:=audio_connt_publisher

May be some one else has a better way about it, let's look forward to that.

Thank you very much.

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2016-08-04 05:58:46 -0500

Seen: 730 times

Last updated: Aug 12 '16