Pd-extended mp3amp~ crashes

I received my Organelle M yesterday and already I’m back to being a computer developer rather than a musician… oh well.

So here’s my conundrum. One of my favorite materials to work with are live internet radio streams. I’m trying to use [mp3amp~] from the pd-extended/unauthorized external. However, it crashes as soon as DSP is flipped on.

There’s a Pd forum discussion here: mp3amp~ causing Pd to crash when open with DSP on | PURE DATA forum~

So I went to try to recompile it from scratch. But then discovered that the Organelle does not have a package manager installed, so getting lmp3lame-dev installed required me to compile THAT from scratch. Which was actually painless.

But now I’m faced with trying to get mp3amp~ itself compiled, and I’m running into issues. And I don’t even know if it’s going to work. There are complexities in the Makefile that don’t really let me compile just the one external successfully; and to compile the entire thing requires that I have the speex lib available, which was a dependency nightmare (to compile that from scratch require Meson and Ninja).

Any advice or help would be greatly appreciated, I think that this external would be of general interest to many Organellistes. I was never very good at compiling things, as I never studied C and am from a generation spoilt by package managers.

1 Like

I think I actually ran into this issue years ago when I first started working with the internet streams, and compromised by cobbling together a handful of OGG streams and using pdogg/oggamp~ instead.

Indeed, as consolation for today’s failures, ONE of the OGG streams I used in my original project still works (http://stream.xaok.org:8000/frs.ogg)

There’s a broader discussion to be had about why (the patented) mp3 stream has won out over open-source ogg; why radio stations are pulling their OGG streams (WFMU, for example); and why so many are moving to Mixcloud instead (which basically breaks a lot of what makes radio/internet radio so much fun).

3 Likes

I tried looking for the mp3cast~ external and had no luck tracking it down. I couldn’t find the source or anything either but I don’t know how much help I could be either since I have limited C skills too. If you could post some of your work, I’ll see if I can bang my head against the keyboard enough to be helpful tho. If you are thinking of going the oggamp route, C&G has compiled an external for the Organelle.

I am in fact already successfully using the pdogg/oggamp~ external as compiled by C&G, so no real issues there (except that it is fussy about disconnecting and reconnecting).

The mp3cast~ external is under the pd-extended/unauthorized directory of the same pd-extended collection. [as I note in another post I actually care about mp3AMP~, but I keep accidentally typing “mp3CAST~” and I’m trying to edit my posts… sorry!]

The C&G Organelle binaries are at Organelle_pd_extra/pd-extended/unauthorized at master · critterandguitari/Organelle_pd_extra · GitHub

The source code for it is at https://puredata.info/downloads/unauthorized (the link to actually download it is Download Pure Data Computer Music System from SourceForge.net)

I assume this would be child’s play for anybody with any gcc/make skills whatsoever. Given the limitations of the stock Organelle w/r/t a package manager especially, cross-compiling on a different machine is probably indicated.

Oh! Also, be aware that I edited my posts because I keep mixing up mp3cast~ and mp3amp~: the one I care about is “amp”, the one that is a client for playing back mp3 streams . I don’t know if mp3cast~ (for publishing mp3 streams) works well or not, but it would of course be useful to know if it does.

I’ll see if I can take a crack at it. Also if your oggamp module is in a state where it could be released, I would love to take a look at it

I’m working on it! It’s pretty straightforward to use oggamp~ in itself, so I’m essentially just trying to figure out a good interface for it.

I’m thinking that one would just provide a simple text file with a list of ogg stream urls that would be shared across all slotted instances of the module. Each module could “tune” to one of these urls at a time.

The only thing that is posing a challenge, or is an open question at this time, is how to override what orac shows on the display, since there is no “string” or “symbol” data type (that I’m aware of) in orac’s configuration setup. I’ll do some experimenting, as I’m just becoming familiar with both orac and organelle’s API.

Ideally, I’d like to have some way to have a unique configuration of urls for each module instance, but that’s not really the focus of orac. It would be akin to shared sample kits, but for text files.

There is no data/string type that is readily available. If you check out a lot of the recent modules I have put out (OracLoops, Loopy, Samplekids, and Converb) they all pull a file path using an abstraction called soundshare.

You could probably have a random number generator choose to pull a random one into a textfile object and then tune it with a float object with a 0 to 1 boundary

Currently I’m using an “int” type and splitting out a text file that way. The display shows “Station 0” (for example), which also requires hard-coding a range that at least encompasses the number of url entries in the text file.

Using a float and some rounding, I could make it a bit more flexible. But if you’re already providing a hard-coded list of urls anyway, it doesn’t really make too much sense to fuss.

Ideally, I’d love to see a “symbol” or even “list” type for the orac module configuration.

1 Like

In my PD ignorance the first thing I’d try in this case would be to put mp3amp~ in its own pd~ subprocess and try to run the instance with some flags especially the “compatibility” flag, but I’d also experiment with audio buffer etc…

Give it a try! :slightly_smiling_face:

2 Likes

Tried in a sub-process with lower versions, same issues.

Successfully compiled Yves Degoyon’s (the original author) own non-free version. However, it crashed in new and different ways!

Apparently implementing and maintaining a streaming MP3 decoder is not easy.

I’m wondering if maybe I can use an up-to-date command-line program via ggee/shell and pipe the audio into Pd.

Thoughts?

The only way I’ve been able to stream mp3 into Pd is by using mplayer to open the stream and then connecting the output to Pd input using jack (audio server for connecting different audio apps). So the process is a little different from a default Organelle Pd patch, which doesn’t use jack (Pd is just connected right to the audio hardware).

You can override the default behavior by including a run.sh file in your patch folder, instead of a main.pd. When you start the patch from the Organelle, it will execute run.sh instead of starting Pd. Then in run.sh you can run the commands to open mplayer, start Pd and connect things up. Here is an example of run.sh that seemed to work:

killall mplayer
killall jackd
sleep 2
/usr/bin/jackd -dalsa -dhw:audioinjectorpi,0 -r44100 -p1024 -n2 &
mplayer -ao jack:noconnect:name=radio http://wprb.streamguys1.com/live &
pd -jack -nojackconnect ~/fw_dir/mother.pd radio.pd &
sleep 4
jack_connect radio:out_0 pure_data:input0
jack_connect radio:out_1 pure_data:input1
jack_connect pure_data:output0 system:playback_1
jack_connect pure_data:output1 system:playback_2

In my notes I also have this one which is a bit simpler but does the same thing:

killall mplayer
killall jackd
sleep 1
/usr/bin/jackd -dalsa -dhw:audioinjectorpi,0 -r44100 -p1024 -n2 &
sleep 1
pd -nogui -jack  ~/fw_dir/mother.pd radio.pd &
sleep 1
mplayer -ao jack:port=pure_data:name=radio http://wprb.streamguys1.com/live &

(you might need to install mplayer and/or jack)

In the patch radio.pd (also in the patch folder) you can do whatever with the stream using [r~ inL] and [r~ inR]. It was pretty fun proof of concept, but would be great to get it working in a more general sense, like globally selecting streaming audio as the audio input.

3 Likes

I did some debugging and it seems (for me) that mp3amp~ is crashing with a Segmentation Fault when it calls the external decode_header() function, which appears to be part of mpg123 (inside libmp3lame?).

My best guess (after looking at the current mpg123 source code) is that the struct used in that call is defined in mp3amp~ against an older version of mpg123, so decode_header is trying to write to invalid memory locations.

Next thing I would try would be to see if it is possible to install an older build of libmp3lame on the Organelle, or re-implement decode_header.

But of course there could be further problems down the line. This is all probably a dead end. But just wanted to share this here in case some brave person is looking for info in the future.

2 Likes

OK, so a more up-to-date effort here looks promising: ffplay~ - An implementation of FFmpeg for audio playback of almost any media format | PURE DATA forum~

And the repo: GitHub - myQwil/pd-quilt: Externals I've made for pure data

Further into the thread, somebody posts a version they compiled for a Pi 3. I tried it and it doesn’t work out of the box: a bunch of .so files are off by like, one number. I don’t understand much about .so files and linking, etc, but I tried and failed to compile it directly on the Organelle.

I’m a bit short on time at the moment, but next time I get a chance to try, I’ll update this thread. Perhaps somebody else will beat me to it and get it compiled for the Organelle??

2 Likes

It looks like the [ffplay~] was failing to compile because the version of ffmpeg in the Organelle M’s repo is quite old. I’m compiling the latest version to see if it goes… could be going for a while though, lol.

Keep your fingers crossed. Looks like a really powerful, long-term solution to many format playback tasks in Pd

2 Likes

GOOD NEWS EVERYBODY.

After a few weeks, I’ve finally gotten [ffplay~] to compile for the Organelle M. AND IT WORKS. It was comforting to hear the sounds of home – WFMU – coming through the lil speaker, while I’ve been with my family in San Diego during difficult times.

I’ll do my best to describe the process. It is unfortunately rather involved, but could be vastly simplified with a better Makefile.

Prerequisites:

  • OS 4.2 (others may work, just noting it here)
  • connect the organelle to the internet
  • ssh or vnc in
  • set the OS to read-write: > sudo ./home/music/fw_dir/scripts/remount-rw.sh
  • I did all of this in /sdcard but it doesn’t really matter

First of all, one needs to have the latest versions of Pure Data and FFmpeg:
> git clone https://github.com/pure-data/pure-data.git
> git clone https://github.com/FFmpeg/FFmpeg.git

The library that contains ffplay~ is called “pd-quilt”. Clone its repo (and submodules) too:
> git clone --recursive https://github.com/myQwil/pd-quilt.git

You don’t need to build or install Pure Data, we just need the latest header files for building ffplay~.

We do need to build and install ffmpeg. As it’s a newer version than is provided by the official Organelle repository, let’s install and use checkinstall to make sure we can easily remove/replace it if needed:
> sudo apt update && sudo apt install checkinstall

Now ffmpeg (in the FFmpeg repo):
> ./configure
> make
> sudo checkinstall

Be patient, the ffmpeg steps take the longest (about 15 minutes to compile, several minutes at least for building the package for checkinstall).

The reason we have to install ffmpeg is because it’s rather large and the pd-quilt author wisely decided to dynamically link it to the pure data lib. Unfortunately, this means we have to fiddle with either where ffmpeg installs itself, or fiddle with the linker configuration (by telling it where the libraries it needs are located). I chose the latter because, from my non-expert perspective, it’s more explicit (that is, easier to poke at until things work).

OK! Now we have to build one of pd-quilt’s submodules, game-music-emu. First, it requires cmake.

> sudo apt install cmake

In the pd-quilt/game-music-emu directory:
> mkdir build
> cd build
> cmake ../
> make -j4

As became clear to me once I figured out the secret sauce for the linking step, we need to install zlib:
> sudo apt install zlib1g zlib1g-dev

At this point we’re ready to actually compile ffplay~ Except that for reasons I’m not entirely clear on, the Makefile will fail to properly link the external libraries. As best I have been able to gather, it’s because of the cc invocation: the order of the libs to be linked is significant, and they all need to come before the object files; and the -l statements need to directly follow their corresponding -L statements. Needless to say, the Makefile doesn’t do this right.

The build command output by the Makefile is correct, so back up in the pd-quilt repo: > PDINCLUDEDIR=/sdcard/pure-data/src make ffplay~.pd_linux -j4

For reference, this is what it’s running (it gets spit out into the console):

cc -DPD -I "/sdcard/pure-data/src" -DUNIX  -fPIC -DBLUNT=1 -DDATE=\"2022-05-27\" -DTIME=\"11:49:07\" -I./game-music-emu/gme -Wall -Wextra -Wshadow -Winline -Wstrict-aliasing -O3 -ffast-math -funroll-loops -fomit-frame-pointer -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -o /sdcard/repos/pd-quilt/src/ffplay~.o -c /sdcard/repos/pd-quilt/src/ffplay~.c

And now the corrected link command:

cc -rdynamic -shared -fPIC -Wl,-rpath,"\$ORIGIN",--enable-new-dtags /sdcard/repos/pd-quilt/src/ffplay~.o -L/usr/local/include/libswresample -lswresample -L/usr/local/include/libavformat -lavformat -L/usr/local/include/libavcodec -lavcodec -L/usr/local/include/libavutil -lavutil -L/usr/include -lsamplerate -L/lib/arm-linux-gnueabihf -lz -lc -lm -o ffplay~.pd_linux

There you go! You should see ffplay~.pd_linux sitting in the directory. You can copy it to wherever you keep your pure data externs and it should work.

Lemme know if anything here isn’t clear or if I seem to have left something out or got it wrong. Obviously it’s quite a number of steps and I may have gotten something wrong writing it out. I could also post the compiled external, and it should work so long as you compile and install ffmpeg exact as I have.

If anybody is a make expert or knows someone here who may be, we should try to update it to take care of all of these details more automatically.

3 Likes

This may be a dumb question but if you share the ffplay~.pd_linux external, would that be all you would need for it to work since the compilation has been taken care of or does ffmpeg need to be installed as well? If so it would make it easier to include in a patch without all the extra steps

Ffmpeg is dynamically linked to ffplay~. You would need to have it installed on your system in order for ffplay~ to work, and it has to be installed in the same locations (e.g. /usr/local/include/libavcodec).

A static compilation would be as you describe, but it would be very large. Might be worth the minor inconvenience, though, but the compilation process would be very different (I think) and require more time for me to figure out.

I just checked: even dynamically linked, the thing is 72 megabytes! Too big for me to post here directly.

As I said, the lengthiest part of the process is compiling and installing ffmpeg from source. It’s necessary (the version you get by doing apt install ffmpeg is incompatible) but easy.

Let me know if it works, as I’m not expert enough to know whether there are other issues that arise from doing it this way.

Or perhaps more easily, instead of compiling, I am now finally understanding the instructions in myQwil’s original post to the pd patch repo forum: you can download his compiled version, and it “should” work if you install the various dependencies:

apt install libsamplerate0 zlib1g libunrar5 libubsan1 libavutil56 libavcodec-extra58 libavformat58 libswresample3

FYI several of these deps are for other parts of the library besides ffplay~.

After my experience trying to compile, you should give this a shot and see if it works.

OG topic: ffplay~ - An implementation of FFmpeg for audio playback of almost any media format | PURE DATA forum~

1 Like