Go Back   Home > Forums > >
Home Forums Rules Articles diyAudio Store Blogs Gallery Wiki Register Donations FAQ Calendar Search Today's Posts Mark Forums Read

PC Based Computer music servers, crossovers, and equalization

PeppyMeter
PeppyMeter
Please consider donating to help us continue to serve you.

Ads on/off / Custom Title / More PMs / More album space / Advanced printing & mass image saving
Reply
 
Thread Tools Search this Thread
Old 31st May 2018, 05:30 PM   #21
rpi is offline rpi  United States
diyAudio Member
 
Join Date: Apr 2015
Location: San Francisco
That PLabs Player looks great and has some interesting solutions which I've never seen before. Those touch buttons look cool
I'm making something similar (Peppy player) but completely based on Raspberry Pi platform.

I've checked the syntax of the File Plugin configuration here:
ALSA project - the C library reference: PCM (digital audio) plugins
but don't see anything related to mbuffer. Is there any other documentation or examples showing how I can do that?
Thanks!
  Reply With Quote
Old 31st May 2018, 09:59 PM   #22
phofman is offline phofman  Czech Republic
diyAudio Member
 
Join Date: Apr 2005
Location: Pilsen
I have been admiring your woodwork for years. I do not have the equipment to make such fancy enclosures, I have to resort solely to modifying the original PC cases.


The mbuffer or its predecessor buffer is a large fifo with some extra parameters. I mentioned it just as an option in case the python script could not be started to consume samples fast enough for the regular pipe not to become full (8kB?) and block the alsa chain.

Code:
file "! your_script.py -c %c -b %b -f %f"
If the pipe in popen gets full before your_script.py starts reading from it, I would use a simple script instead

Code:
file "! helper_script.sh %c %b %f"
with

Code:
buffer | your_script.py -c $1 -b $2 -f $3
By default buffer uses up to 1MB circular buffer which is plenty for this purpose.
  Reply With Quote
Old 1st June 2018, 05:33 AM   #23
rpi is offline rpi  United States
diyAudio Member
 
Join Date: Apr 2015
Location: San Francisco
These lines from the documentation were confusing:
# Output filename (or shell command the stream
# will be piped to if STR starts with the pipe
# char).
I used to use '|' as pipe character not '!'.

1. Right now if I use ALSA File plugin and I don't start PeppyMeter before starting media player (mpd, vlc or mplayer) then the latter will fill up the buffer and it will be blocked. As a result there is no sound.

2. If I start PeppyMeter before player everything works fine.

What you are suggesting is to configure ALSA File plugin in such a way which will resolve issue #1. For that you are suggesting to use two scripts:
helper_script.sh - this script will be configured in plugin and it will start reading data from player into buffer (is it just reading from stdin $1 ?) and at the same time it will start main Python script which will read data from stdin where File plugin will be sending it.
Please correct me if I misunderstood your proposal.

I think it should work but starting PeppyMeter before player is easier IMHO. For example I use the same code from PeppyMeter as VU Meter screensaver in Peppy Player. To avoid issue #1 I just start pipe reader before starting player. That solves the issue. That reader is always running while player is running.

Probably the best way to fix issues would be to make File plugin working the same way MPD is working with pipe. And another way as I mentioned already would be to write own plugin. I would also prefer to refrain from writing any C/C++ code and do that only if it's really not possible to solve the issues in Python.
  Reply With Quote
Old 1st June 2018, 06:43 AM   #24
phofman is offline phofman  Czech Republic
diyAudio Member
 
Join Date: Apr 2005
Location: Pilsen
I am sorry, of course it should be | instead of ! :-) Stupid me.

There are many ways, as always, fortunately.

The problem with starting the reader before the stream starts is that you do not know in advance what format you will be receiving. You can make the format fixed in a special branch of your .asoundrc and split the stream into two - one stream going unchanged to the soundcard, the other one with fixed bit width/format feeding your meter.

Or file plugin can start the reader each time the stream is opened/started with stream-specific params. The reader will use these params to read the incoming stream correctly.

Perhaps I would do it like this:

1) Continuously running GUI python script, reading 16/32bit integers from a named pipe FIFO. First byte - right channel value to display, second byte - left channel value


2) Python script started by the file plugin in piping mode, reading incoming bytes from stdin, converting to samples based on args info, calculating the averages, writing the output two-channel integers to the named pipe FIFO in non-blocking mode python Non-block read file - Stack Overflow . I would guess a single thread should be OK.

Should the script 2 fail, all it takes is just play another track and it will be started again. If the GUI script 1 fails, no problem since script 2 will just skip writing to the full FIFO (due to the nonblocking mode).

Of course the best way would be implementing a non-blocking option in the alsa file plugin :-)
My 2 cents.

Last edited by phofman; 1st June 2018 at 06:55 AM.
  Reply With Quote
Old 1st June 2018, 03:20 PM   #25
rpi is offline rpi  United States
diyAudio Member
 
Join Date: Apr 2015
Location: San Francisco
I will collect a lot of money from your 2 cents

As I mentioned already I use the same PeppyMeter code for VU Meter screensaver in Peppy player. In that player you can switch from Internet radio to audio files, from audio files to audiobooks etc. The sound parameters (rate and size) can be different in each case. Therefore it's hard to use File plugin. I'm not sure if it invokes script each time the sound stream parameters change. MPD has 'format' parameter for pipe audio_output. So you can define fixed rate/size and it looks like MPD will transcode signal into the signal with defined parameters. This solves the issue with arbitrary sound parameters.

As for the File plugin I believe you described a working solution. As far as I understand you are suggesting to use two pipes - one for the File plugin and the other to feed GUI. One Python process could read the first pipe, make all necessary calculations and send just resulting VU levels to another pipe. That should work if File plugin restarts script with new parameters when sound parameters change.

I agree that changing pipe opening mode from blocking to non-blocking would be the best solution. It should also properly handle buffer overflow. But ALSA user base is so large that any minor change can affect too many people. One way could be just to make a custom build of that plugin.

Thanks!
  Reply With Quote
Old 1st June 2018, 04:27 PM   #26
phofman is offline phofman  Czech Republic
diyAudio Member
 
Join Date: Apr 2005
Location: Pilsen
Quote:
Originally Posted by rpi View Post
The sound parameters (rate and size) can be different in each case. Therefore it's hard to use File plugin. I'm not sure if it invokes script each time the sound stream parameters change.
An open alsa device cannot change parameters. For that the player must close and reopen the device, configuring the parameters first.

Each plugin in alsa chain will be called for every alsa "event" - open device, close device, write data etc. In its open-device "hook" the file plugin calls popen syscall popen(3) - Linux manual page which will start the process specified in configuration and return pipe to its stdin. Into this pipe the file plugin writes samples in the write "hook". In close-device hook the plugin closes the pipe, after which the python reader will receive EOF while reading the from pipe and should quit nicely.

Therefore, yes, the file plugin starts the script each time the device is opened by the player, typically every track. Each track can have different params but if you let the file plugin substitute the script args with the actual values of the stream, as described in the posts above, your python code will know the stream params and can handle the incoming bytes accordingly.


Quote:
MPD has 'format' parameter for pipe audio_output. So you can define fixed rate/size and it looks like MPD will transcode signal into the signal with defined parameters. This solves the issue with arbitrary sound parameters.
You certainly can force MPD convert any input into fixed output. But why resample a rate your soundcard can handle. Perhaps rate is not relevant for your script, but even sample width can change (some soundcards support two different sample widths, e.g. Intel HDA).

It is true that you can force MPD output single sample width (e.g. 32 bits) and no data loss will occur. That would let you ignore the params from file plugin. I personally would make the script be more fault-proof and accept various sample widths, even if they cannot occur in your particular setup.

Quote:
As for the File plugin I believe you described a working solution. As far as I understand you are suggesting to use two pipes - one for the File plugin and the other to feed GUI. One Python process could read the first pipe, make all necessary calculations and send just resulting VU levels to another pipe.
Yes, the first pipe is blocking (unless file plugin is modified), but the second pipe used from python would be in nonblocking mode - that is what you need to avoid stalling the playback chain.

Quote:
I agree that changing pipe opening mode from blocking to non-blocking would be the best solution. It should also properly handle buffer overflow.
That is the natural outcome of the nonblocking mode.

Quote:
But ALSA user base is so large that any minor change can affect too many people. One way could be just to make a custom build of that plugin.
The nonblocking mode would be activated with an optional plugin parameter. Just finding someone to code it. Honestly, this time I do not volunteer, I have too many other undergoing projects to finish :-)
  Reply With Quote
Old 1st June 2018, 04:49 PM   #27
rpi is offline rpi  United States
diyAudio Member
 
Join Date: Apr 2015
Location: San Francisco
MPD supports multiple audio outputs with different parameters. I think pipe 'format' parameter should not cause transcoding for all other outputs. It can be used just for VU Meter where you care only about signal amplitude and don't care about sound quality.

I will try the approach with two pipes/Python processes whenever I'll start working on new version. I'll also check if I can modify/rebuild ALSA File plugin. Need to finish some on-going projects too New version of one of them (Peppy player) I hope to release this weekend.

Thanks for interesting discussion!
  Reply With Quote
Old 1st June 2018, 05:23 PM   #28
rpi is offline rpi  United States
diyAudio Member
 
Join Date: Apr 2015
Location: San Francisco
Just to recap the discussion - PeppyMeter should work fine with MPD if you define all required parameters in mpd.conf file:
mpd * project-owner/PeppyMeter.doc Wiki * GitHub

In case of any other player (e.g. vlc, mplayer etc) you need to configure ALSA File plugin:
mplayer * project-owner/PeppyMeter.doc Wiki * GitHub
and start PeppyMeter before player. If you start player first it will not play anything as it will be blocked. Also in this use case PeppyMeter can have issues playing audio signal other than 16 bit 44.1K as it currently doesn't handle other formats properly. I hope to fix that in the next release.
  Reply With Quote
Old 7th August 2018, 03:39 PM   #29
rpi is offline rpi  United States
diyAudio Member
 
Join Date: Apr 2015
Location: San Francisco
This post is just to revive the old didcussion and consider some new "pure" ALSA approaches.
To remind the issue - Peppy Meter is currently using the following configuration in .asoundrc file:
pcm.!default {
type file
slave.pcm "hw:0,0"
file /home/pi/myfifo
format raw
}
This is so called ALSA file plugin:
ALSA project - the C library reference: PCM (digital audio) plugins
It allows to send the signal to the sound card (slave) - "hw:0,0" and to the named pipe
at the same time - /home/pi/myfifo

The signal from the named pipe is used by Peppy Meter to show volume levels. The problem
is that input signal can be in different rate and size. Peppy Meter is not clever enough (and probably
should not be) to detect that rate and size. Therefore there is the need to convert the signal into
some fixed rate/size before sending it to the file plugin. The question is how to do that using just
ALSA plugins?

Thanks!
  Reply With Quote
Old 7th August 2018, 08:11 PM   #30
phofman is offline phofman  Czech Republic
diyAudio Member
 
Join Date: Apr 2005
Location: Pilsen
Does your asoundrc with file plugin work OK, is the problem only with various rates? Or do you experience too large latency of peppy meter, or sound interruptions when peppy meter stops (the pipe is full and stops the writing thread)?

The reason I am asking is which complexity your case will need. Adding plug plugin with rate specification to your asoundrc is trivial. snd-aloop with resampling is a bit more complicated but would solve the latency problem (if any) and the lockup problem (if any).
  Reply With Quote

Reply


PeppyMeterHide this!Advertise here!
Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


New To Site? Need Help?

All times are GMT. The time now is 11:40 PM.


Search Engine Optimisation provided by DragonByte SEO (Pro) - vBulletin Mods & Addons Copyright © 2018 DragonByte Technologies Ltd.
Resources saved on this page: MySQL 15.79%
vBulletin Optimisation provided by vB Optimise (Pro) - vBulletin Mods & Addons Copyright © 2018 DragonByte Technologies Ltd.
Copyright ©1999-2018 diyAudio
Wiki