4

I want to be able to break a song into packets and have access to these individual packets. The reason for that is that I want to send each individual packet over the network using an experimental network protocol called Named Data Network.

As the packets arrive at the destination I want to play them. So I want to implement a streaming functionality. The only difference is the network layer that I will use. This network layer is not based on IP.

Does anyone know any C/C++ implementation of breaking a song file into pieces and then playing these packets individually? I looked over Gstreamer, but it seems complicated to get individual packets from its pipeline structure. I found this reference which was the closest to what I wanted, however it was not so clear for me: how can I parse audio raw data recorder with gstreamer?

Summarizing the points I need:

  1. Break a song into packets
  2. Play the audio content of a single packet (or a small set of packets).

Thank you very much for the help!

Community
  • 1
  • 1
Pedro Borges
  • 1,240
  • 10
  • 20
  • MP3 is a streaming format, so you can more or less just chop it up and it will still play more or less ok. – Jonathan Potter Nov 24 '14 at 19:13
  • 1
    A streaming format still consists of chunks. In case of MP3, these are called frames and are not necessarily independent - a frame might reference data from several previous frames (search for 'bit reservoir'). Simply chopping an MP3 into random chunks of data might work if the decoder supports this and performs some kind of buffering. However, this is far from guaranteed. For example, Web Audio API 's decodeAudioData has a hard time with those. See http://stackoverflow.com/questions/10470742/define-valid-mp3-chunk-for-decodeaudiodata-webaudio-api – Lukas Pokorny Nov 24 '14 at 19:29

1 Answers1

3

An MP3 file is just a succession of MP3 frames. Each frame is made of a header and a data block.

Splitting the MP3 file as MP3 frames will involve parsing the MP3 file. You can refer to this documentation for a good description of the format.

Note that in the case of mpeg layer 3 codec, frames are not independant. In the worst case, 9 input frames may be needed before beeing able to decode one single frame.

What I would do instead of this

I guess you could probably ignore most of these details and focus on the streaming problem itself. Here is what I would try to build first:

  • on the sender side, split a file into packets, and send them one by one using your system. Command example: send_stream test.mp3

  • on the receiver side, receive the packets and rebuild the original file. Command example: receive_stream test.mp3

Once you have this working fine, modify the receiver program so that it writes the packets in-order on the standard output. This will allow you to redirect stdout to a file

# sender side did not change
send_stream test.mp3

# receiver side
receive_stream > test.mp3

Then, you can use madplay to play the mp3 while it is received simply by redirecting receive_stream output to madplay:

# madplay - tells madplay to read its input from standard input.
receive_stream | madplay -

For a good mp3 decoder, take a look at MAD.

Gilles Gregoire
  • 1,696
  • 1
  • 12
  • 14