detect driver sample rate
Hi,
I'm trying to build a Max patch that can automatically detect the audio driver's sample rate set in Audio MIDI settings in Mac OSX. You'll see in this example patch that if you look at the default audio status in Audio MIDI settings (Built-in Output on my machine) that changing the sampling rate in Max changes it in Audio MIDI.
But how do I go the other way - change it in Audio MIDI and detect that in Max? I assume there must be some way to do it with [adstatus] but I haven't been able to find anything so far.
Thanks!
Another Max user told me he thought it couldn't be done, but I just confirmed that Bidule (a much lower-end graphical audio programming system) has this functionality. Surely Max can do this somehow? Anyone have any ideas?
I just posted a posting on this forum with the subject "Adaptive Sampling Rate" with this same exact question. I am wondering if you have found an answer since you posted your question in Sept of 2015.
Indeed, Plogue Bidule, which I use extensively, has this capability but I cannot find a way to do it in Max. If I find a way, I will sure let you know. Please do the same if you get a hint in the right direction.
Thanks.
couldnt you retrigger adstatus or dspstatus every 15 seconds to get the recent changes? and then re-set this setting via max? (which of course would interrupt the chain once more)
While adstatus and dsptatus can be used to set the the SR on the audio device, they do not reflect SR changes made on the actual audio device (hardware) or in Audio Midi Setup. I am looking for a way to query the actual SR on the device (or equivalently, the SR set in Audio Midi Setup).
ah right, you would have to re-select the driver from max _first. and this cant be done somehow in a subpatcher which is silenced.
regarding changes diretly at the device, it owuld think that this needed to be implementated into the CA driver.
Thanks for the reply. I am not sure I understand what you mean by "max_first" or the "CA driver".
I found out that the SR info I need can easily be obtained through the CoreAudio API, it's a simple call to AudioDeviceGetProperty for the kAudioDevicePropertyStreamFormat property, but I have no idea if this could be done from Max.
read /Library/Preferences/Audio/com.apple.audio.DeviceSettings.plist
into text or coll, dump out, route sample rate and read the value ...
but he would have to watch that file for changes all the time. so either a max external which can talk (or actually listen) to coreaudio, or something else in the OS which does the same.
beside the fact that you cant do anything c++ in max, AudioDeviceGetProperty is probably not what is making bidule aware of a change to the SR when the SR is changed directly at the physical device. get property and set property sound like somewhere else, i think the "nominal sampling rate" stuff is what would be required.
if bidule is the only app which can do this with your device maybe ask them?
I don't actually understand why would someone change audio sampling rate on the fly, while max is running.
What sense would that make ?
First, to answer Source Audio's last question: I am developing a standalone (max-based) application that processes stereo audio for 3D rendering over two loudspeakers. The application is intended for audiophiles (who typically have a collection of HD music at various sampling rates from 44.1 to 192 kHz) and audiophiles expect any audio processing to be done at the native sampling rate. Therefore the standalone application must switch its sampling rate to match the sampling rate of the audio device (which automatically switches with the sampling rate of the source). I understand that this not a common thing in most audio applications, but adaptive sampling rate is a standard expectation for DACs and digital audio processing in "high-end audio". (A delay of 1-4 seconds for SR switching is tolerated and most high-end audio digital streaming sources have a setting to accommodate such a delay.)
Thank you for your suggestion to parse the DeviceSettings.plist. Indeed this has to be done on a frequent basis (once every second or two) and I will evaluate how feasible this potential solution is.
Another promising solution is having the audio device send its SR regularly to Max through OSC. Luckily the device I am using does support OSC but unfortunately the SR setting is one of the few things that it does send via OSC. I am talking to the manufacturer to see if this can be added.
In the meantime, I continue to look for more elegant solutions that can work with all devices. As I said in a previous posting, the best and cleanest way to do it is via calls to the Core Audio API. It was indeed the developer of Plogue Bidule, Sebastian Beaulieu, who told me that Bidule does it by calls to AudioDeviceGetProperty.
So if I understand that properly, some external Audio Hardware Player is sending audio to max,
which processes it in real time and sends it back to same device, is that correct?
It probably works without adc / dac conversion, all in digital domain.
What device is it exactly ?
That is correct. The device is RME's Babyface Pro.
RME babyface is just and only audio interface, not a player, and by no means "that" Hi End audiophile device... these "audiophile" guys invest much more in a single chinch cable than what rme interface would cost.
Anyway, babyface is not a player and so it can just input and output audio.
What Audio Player is playing the audio files ?
Why not let Max play Audio Files, detect the Sample Rate before Playback starts and set the SR on Babyface ?
That would definitely be within "normal" quality audio playback,
and audiophile which accepts that audio passest through Max should see no reason not to accept Max to also play fies.
The Babyface Pro is used for its stereo Mic preamp (which is used for the included binaural mics needed to do the required calibration). It is also used to handle the digital audio i/o. Although it has excellent DAC/ADC, almost all of our customers (who are computer audiophiles) prefer to use their high-end audio DACs. The Babyface Pro simply routes the digital audio from the processing application to the outboard high-end DAC.
As to the file source, the application does have a file player (which already accommodates the solution you suggested, i.e. it can switch the processing SR to that of the file being played internally) but it is a rudimentary file player compared to what our customers use (Roon, Audirvana, Pure Music, etc..). For instance it does not handle metadata and we have no intention in making the app a file player for audiophiles. Hence, our customers use their own sources (audio file players or even CD players), which are configured (in various ways) to send digital audio to the BabyFace Pro, which in turn routes it to the app for processing, then routes the processed audio to the outboard high-end DAC.
At present, the processing is done at a fixed SR and I am looking into making the SR adapt to that of the source.
So You will need to switch the SR on external DAC as well, right?
Well how about call to system profiler?
I don't know how fast does it reflect hardware changes (same would apply to audio.DeviceSettings.plist)
Here is a patch that requests audio hardware properties via shell.
It is then only a matter to route infos for device of interest.
You can find shell object here > https://cycling74.com/tools/bernstein-shell/
Before You hit the "system_profiler SPAudioDataType" have a look at output
for my built in and little motu devices...
Sample Rate is being reported on Mountin Lion and up.
But one thing is sure, one would have to frequently ask for changes,
there is no way I know of that would make Max autodetect SR and adapt.
or what about logging out and in again.
the only thing whats sure is that a C++ CA API cannot be added to the max runtime with tesa tape or pattex.
Thank you Source Audio. I put together the attached Max patch that issues the shell call "system_profiler SPAudioDataType" at a set frequency (e.g. every 2 seconds) and extracts the SR of the Default Output Device by parsing the output.
That should do it until I find a more elegant solution.
You are welcome.
As You say this is not elegant solution, because it does not react fast to SR changes on device.
In reality, even if Babyface would send current SR via OSC to Max, Max would actually send it
back to Babyface , so maybe some kind of backloop could become a problem.
One thing is interesting - if one would set the highest available sampling rate
available on a device when max starts, and later change SR on the device, Max will simply
work for In -> Out audio, only any dsp synthesis like for example cycle~frequency would suffer from SR change...
By the way You could optimise the patch a bit to react faster, also maybe one could start requesting, SR only wenn Audio Playback level drops to zero, but then call for SR change
much faster, every 100 ms or so.
Here is little bit changed patch :
If You can spare a bit of time, coud You please provide a bit more info on,
the way that SR gets changed by Audio Playback.
Which device, or software is doing it, and at which point ( wenn Playback starts
or wenn different Hardware gets connected or engaded...)
Thanks again for a good idea. Luckily, it turns out that when the SR is changed on the device, the audio streaming in Max stops (even though audio status/processing remains on) so instead of sending frequent shell calls, all one needs to do is detect when the streaming stops. This cannot be done with signals whose source is digital (since that signal is zero when there is no audio playback even if the streaming has not been interrupted by the SR change) but can easily be done with a signal whose origin is analog, which most conveniently is the signal from the mic(s) channel(s) since there is always noise on the preamp/ADC channel(s). In the case of the BabyFace Pro, these are simply input channels 1 and 2, and in the case of the Mac with no external device, they are the channels associated with the built-in mic.
Therefore, I have evolved the patch (see attached patch) to do such a detection and issue the SPAudioDataType shell call only when audio streaming interruption is detected. Nicely, the "; dsp sr $1" message, not only sets the SR in Max but also restarts the streaming, so by removing, the change object that you had placed before it, the reset SR operation will always restart the streaming and, if the SR has changed on the device, resets the SR in Max to match it.
Perhaps you know a better way to detect the halt in audio streaming (any ideas would be appreciated). Given that the audio stream freezes (it does not just go to zero value) the only way (so far) I could do the detection is by taking recurrent (100 ms) snapshots of the signal and doing a delayed comparison using the pipe object.
It all works nicely now and the SR detection/switch happens in less than 1.5 seconds, which is perfectly fine for my application as many high-end DACs take even longer to switch (as I said before the delay can be set in many high-end audio streaming/file players to wait for the DAC to switch).
I will describe how typical playback switches SR on the device in a separate post.
Now that is good news, You have something which works,
refinements can be done later if needed.
As I am on the road at the time, I can't do any testing,
and what interests me in the first place is how fast info about SR change on the device gets reflected in system profiler.
Audio Stream Interrupt detection is just fine the way You did it, it coud
be done by other objects as well, but I don't see any reason to change it.
As to "how fast info about SR change on the device gets reflected in system profiler", the change is reflected quite quickly - quicker than it takes to get the relevant data from the shell command so there is no need to delay sending the shell command once the streaming halt is detected (as is shown in my latest patch).
Hello,
Is this patch supposed to work now ?
With Mac OS 10.13.6 ?
It doesn't seems to...
EDIT- I hadn't read the total explanation (the needed analogic input)
Sorry my bad...
I'll try again and I'll tell you !
Well I tried with an analog input and it doesn't seems to work...
Did you try on a recent Mac OS ?
Thanks you very much !
EDIT- Or maybe this trick doesn't work with my sound card (Metric Halo 2882)...
But it seems to generate a silence too when I change the Sample Rate...
- UPDATE -
Ok it works !
I took the 1st version your patch (the version with the 2sec triggering) and I changed the triggering with the silence method of the last version.
The combination of the two patches works.
Thank you very much !