• Disclaimer: This Vendor's Forum is a paid-for commercial area. Unlike the rest of diyAudio, the Vendor has complete control of what may or may not be posted in this forum. If you wish to discuss technical matters outside the bounds of what is permitted by the Vendor, please use the non-commercial areas of diyAudio to do so.

Control of BBB-based audio appliances

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
Hi twluke!

Yes, you are certainly on the right track!

Suggestions:

1. delete the new 'global ...' lines. Those specify variables and you are not using any new variables.
2. I suggest that the first option in the 'handle_command' use 'if' (as you have it) but that the others use 'elif'. I see that my GitHub code wasn't that way but now I changed it.
3. I suggest that the logic statements be changed from 'line.startswith' to 'line =='. Only the 'set volume' option needs 'startswith'.
4. By all means transfer the code to your GitHub page!

Hi Frank, thank you for these suggestions and kind words. I'm very grateful to you.
As you gain comfort with the modifications, please begin thinking about what will be your favorite way to control the DAC.
Tanks for this comment. Well, I'm now beginning to consider this option. Will do more home work. :)

Regards,
 
Hi Frank,
I've read the entire thread and would like to try this. My BBB/BuffaloPro system is simple compared to yours. I would like to have control of volume and the various filter parameters. I've just a couple very basic questions to start with.
I have downloaded your Python script but how to you copy it to the BBB? I imagine that the Twisted Pear firmware chip needs to be removed, right?
Thanks for sharing your knowledge.
 
Member
Joined 2007
Paid Member
Greetings @pixelpusher!

I'm happy to be of assistance. The code that Twluke is using is a good start for a simple control system. However, I purposely took out some things that make it compatible with the program 'NetIO'. If you think you would like an iOS or Android controller for your system, then we can restore that functionality.

Here is the big picture. Almost everyone has an older phone or tablet that could be put to good use as a remote control. That's one reason I like the NetIO program - you can make different controller screens to suit the device screen, and you can have multiple controllers active at the same time. Plus, the web interface to design the control screens is slick, and I've ironed out many of the issues that can arise between the server program on the BBB and the remote control device.

I put my current 9028 control code up on GitHub for anyone to look at or import.

Here: https://github.com/francolargo/BBB-audio/blob/master/netio_server.py.9028.py

Unlike the older control programs, the newest version has three separate and parallel processes: a) the server waiting for any remote command, b) a loop to sense and respond to GPIO inputs to the BBB (from my control box front panel), and c) a monitor function that helps keep the ES9028s in the proper configuration to avoid system damage if control registers are unintentionally altered (which never happened with the older 9018s). It also has the beginnings of a log system to monitor its own activity.

Finally, I am transitioning my own media serving duties to a Raspberry Pi from a Macintosh. This gives me the chance to make the system controls even better, since the RPi can also respond to the NetIO controller. It will become the 24/7 system master that manages ON/Off/Standby via logic-level power switches. AND - the cool part - the RPi and BBB can easily communicate wherever 'handshaking' will be needed. The goal is to never touch the equipment, and hopefully avoid any future ESD damage such as I experienced when it got so dry during the recent polar vortex breakup.

So, decide how you want to interact with your system and we'll get you set up...

Best,

Frank
 
Last edited:
Yes, My goal is to control the system with an ipad. I have used iRule for years and recently been enamoured with Demopad. I also purchased NetIO to check that out. These are all apps that can build a graphical interface on an ipad and issue TCP commands accross the network.

I was under the impression that your Python script, DACserver.py, would setup a server on the BBB to accept TCP commands and control the BuffaloPro.

EDIT; the link you posted did not work
 
Last edited:
Member
Joined 2007
Paid Member
Yes, your understanding is correct. The software simply listens to the ports you select and evaluates any incoming TCP text for significance using 'IF such-and-so' recognition logic. Twluke is simply using the command line with 'netcat', so I simplified it a bit for him. NetIO uses a return acknowledgement, which was a complication he didn't need.

I transfer files to and from the BBB using a simple ftp program on the desktop/laptop. ...slick and fast...
Yes, you will have to remove the firmware chip from the DAC, meaning that you will need another method to initialize it and enable I2C. I think Twluke's suggestion here is elegant:
https://www.diyaudio.com/forums/twi...lo-iii-se-pro-9028-9038-a-88.html#post5670544
I'm initializing with a single-purpose arduino for now...

finally, I edited that link - it should work now after a page refresh

F.
 
Last edited:
The link still does not work for me but I found your files by searching Github.

I have noticed the comments about reset but do not really understand the why and how of it. I guess this is more complicated than I thought and will require more study on my part.

Thanks for your files.
 
Member
Joined 2007
Paid Member
Greetings Ichiban

I'd like to input USB audio from a PC into the BBB.

Currently input ethernet from PC into the BBB.

Would need to switch between ethernet & USB.

What do I need to do to accomplish this?

This switching could be done within the BBB. You would need a command to 'pipe' the audio input to the audio output, and that command would specify the source as the USB and output.

Setting code in BOTIC to accept USB audio?

Switching via BOTIC control rather than

a hardware switch.

No, the Botic kernel itself would not participate in this switching. You would accomplish this either from the command line of a BBB login, or better, by writing simple scripts (small programs) and executing them using some other control mechanism. This thread is about those kinds of commands, scripts, and control mechanisms (and how to use them).

Your first step would be to attach your USB source to the BBB and see if it is recognized. Simply make the connection and then from the BBB command line execute 'arecord -L'. If the USB source is listed then the rest is possible. If the USB source is not listed then you may need to work with your USB source computer to be sure it can send a signal via the USB port.

Good luck,

Frank
 
Member
Joined 2007
Paid Member
Question for @twluke:

First, greetings! I hope you are getting more comfortable with controlling your DAC using I2C/Python. I noticed a small error in the GitHub code for DACserver.py. Lines 43 and 46 were reversed. As a result, the DAC would initialize to very near full volume. Register 0x1b is the most significant register for volume. [BTW, I searched GitHub for you to look at your current code but couldn't find you.]

Second, I am now doing some upgrades to my system that will allow me to experiment with synchronous B3 operation. It now uses the newer Cronus board that returns master to the BBB plus has enough reserve power to supply 3 Teleporters. In preparation, I am curious about the relationship between register 0x0a (128fs mode) and register 0x25 (bypass osf).
Does the Cronus clock always maintain the right 128fs frequency multiples?
In synch mode, wouldn't the oversampling factor (register 0x25) always be a simple integer? That wouldn't seem so consequential - whether on or off...

Your comments and any suggestions on synch mode will be much appreciated!

Many thanks in advance,

Frank
 
Member
Joined 2007
Paid Member
I found your GitHub page, twluke...

To initialize your DAC at a low (safer) volume, change line 45 and 48 from:
Code:
    bus.write_byte_data(0x48, 0x18, volume) # Master volume - starts low
    bus.write_byte_data(0x48, 0x19, 0xff)
    bus.write_byte_data(0x48, 0x1a, 0xff)
    bus.write_byte_data(0x48, 0x1b, 0x7f)

to:
Code:
    bus.write_byte_data(0x48, 0x18, 0xff)
    bus.write_byte_data(0x48, 0x19, 0xff)
    bus.write_byte_data(0x48, 0x1a, 0xff)
    bus.write_byte_data(0x48, 0x1b, volume) # Master volume - starts low

Up on your line 14, you can change the '5' to whatever starting volume you prefer. Remember that 127 is -0dB.

I am listening now using your Buffalo III settings and they are working perfectly w/ PCM! :D I updated the Cronus board in my system and brought the MCLK to the B3PROs via Teleporter. I can't make a fair comparison of SQ because I'm repairing and updating a number of little things. New buffered headphone outputs are now 'burning-in', and the SQ results are slowly reaching "seriously good"! :)

Interestingly, I am hearing loud pops when recording sample rates change - and that happens even with auto-mute ON. What are your observations on that problem?

Cheers,

Frank
 
Hi Frank, thank you for this kind update.
I found your GitHub page, twluke...
Good for you :)

To initialize your DAC at a low (safer) volume, change line 45 and 48 from:
Code:
    bus.write_byte_data(0x48, 0x18, volume) # Master volume - starts low
    bus.write_byte_data(0x48, 0x19, 0xff)
    bus.write_byte_data(0x48, 0x1a, 0xff)
    bus.write_byte_data(0x48, 0x1b, 0x7f)
to:
Code:
    bus.write_byte_data(0x48, 0x18, 0xff)
    bus.write_byte_data(0x48, 0x19, 0xff)
    bus.write_byte_data(0x48, 0x1a, 0xff)
    bus.write_byte_data(0x48, 0x1b, volume) # Master volume - starts low
Up on your line 14, you can change the '5' to whatever starting volume you prefer. Remember that 127 is -0dB.
I revised the .py file in my repository, thank you so much.
I am listening now using your Buffalo III settings and they are working perfectly w/ PCM! :D I updated the Cronus board in my system and brought the MCLK to the B3PROs via Teleporter. I can't make a fair comparison of SQ because I'm repairing and updating a number of little things. New buffered headphone outputs are now 'burning-in', and the SQ results are slowly reaching "seriously good"! :)
For now, I've been comparing between the 128fs and non-128fs settings to check if there is any noticeable difference in terms of the SQ but so far, I could not find any differecne so far.

BTW, the diff file between the settings above is like below:
Code:
63,64c63,64
< dac_upd 10 0xff 0x10 # 0b00010000 128fs enabled
< #dac_upd 10 0xff 0x00 # 0b00000000 128fs disabled
---
> #dac_upd 10 0xff 0x10 # 0b00010000 128fs enabled
> dac_upd 10 0xff 0x00 # 0b00000000 128fs disabled
72,73c72,73
< dac_upd 12 0xff 0x00 # 0b00000000 DPLL off 
< #dac_upd 12 0xff 0x11 # 0b00010001 Lowest BW 
---
> #dac_upd 12 0xff 0x00 # 0b00000000 DPLL off 
> dac_upd 12 0xff 0x11 # 0b00010001 Lowest BW 
85c85
< #dac_upd 15 0xff 0x09 # 0b00001001 stereo
---
> dac_upd 15 0xff 0x09 # 0b00001001 stereo
88c88
< dac_upd 15 0xff 0x0f # 0b00001111 Frank's recommend (stereo/all_to_use_ch1/vol_ctl_enabled)
---
 > #dac_upd 15 0xff 0x0f # 0b00001111 Frank's recommend (stereo/all_to_use_ch1/vol_ctl_enabled)
Interestingly, I am hearing loud pops when recording sample rates change - and that happens even with auto-mute ON. What are your observations on that problem?

Cheers,

Frank
Ah yes, I have a similar experience, though the loudness of pops is dependent on the volume. Occasionally I'm still wondering if I have correctly understood how automute works.

From your prior post:
In preparation, I am curious about the relationship between register 0x0a (128fs mode) and register 0x25 (bypass osf).
Does the Cronus clock always maintain the right 128fs frequency multiples?
In synch mode, wouldn't the oversampling factor (register 0x25) always be a simple integer? That wouldn't seem so consequential - whether on or off...
I checked how 128fs is defined by ESS and found that they only say that the condition can be established in sync mode with a 128*FSR MCLK in PCM normal or OSF bypass. There is no definition such as MCLK=128fs (here FSR and fs values are variable according to the modes: DSD or DoP or serial (PCM) normal or serial with OSF bypass. So, my current conclusion is that if the register for 128fs works, you are in the 128fs sync mode. If the register for 128fs is unset and there is still ordinary sound, you are in the sync mode of non-128fs.

The setting of the Cronus clocks is sometimes puzzling. I found that the 128fs condition is dependent on both of the clock divider on the cronus and the clock setting in the /boot/uEnv.txt on Botic BBB.

In my case. if I set 45/49 clocks on the uEnv.txt, the 128fs mode can be well established with x1 jumper setting on the Cronus for DSD512 but it you leave no setting in the uEnv.txt, the jumper position must be moved to x1/4 (x1/2 should be, I think, a reasonable position for 45/49 clocks). In case of 90/98 clocks, setting 45/49 in the uEnv,txt and placing the jumper to x1/4 are required for 128fs in my case. Maybe more home work is necessary for further understanding. :D

Best Regards,
 
LED's to indicate sample rate

Moved this question from the Botic Linux driver thread...
I am using BBB with Hermes/Cronus reclocker and I2S output (no USB) to a DDDAC. Is there a way to get info from BBB or Hermes/Cronus to drive simple LED's to indicate 44.1, 88.2, 176.4, 48, 96, or 192 sample rate of the file I am playing? As a bonus, but not necessary, bit depth indication of 16 or 24 would be nice too.

Francolargo graciously offered to share his Python code that will help to accomplish this. Thanks! :)
 
Member
Joined 2007
Paid Member
Greetings @Heathkit,

The code I run on my BBB is about 700 lines and almost always being revised or improved. However, my controller reports sample rate, and it is easy to accomplish using only a small sample of the code I'm running.

For GPIO setup:

First, import the Adafruit GPIO management module into the BBB.

Then, you set up your program by importing the needed modules:

Code:
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
import select
import Adafruit_BBIO.GPIO as GPIO
import time
from multiprocessing import Process
import subprocess

# misc. GPIO setup as needed to address 7 LED outputs
# these are the pins I use with BBB/Hermes for LEDs - others are available on P8
# first, set up the pin as input or output
GPIO.setup("P8_7", GPIO.OUT)
# then, set them as low or high - to change, these are the simple commands
GPIO.output("P8_7", GPIO.LOW)
GPIO.setup("P8_9", GPIO.OUT)
GPIO.output("P8_9", GPIO.LOW)
GPIO.setup("P8_10", GPIO.OUT)
GPIO.output("P8_10", GPIO.HIGH)
GPIO.setup("P8_13", GPIO.OUT)
GPIO.output("P8_13", GPIO.LOW)
GPIO.setup("P8_15", GPIO.OUT)
GPIO.output("P8_15", GPIO.LOW)
GPIO.setup("P8_17", GPIO.OUT)
GPIO.output("P8_17", GPIO.HIGH)
GPIO.setup("P8_19", GPIO.OUT)
GPIO.output("P8_19", GPIO.LOW)

Sample rate can be read and the variable used logically as follows:

Code:
with open('/proc/asound/Botic/pcm0p/sub0/hw_params') as f:
                 lines = f.readlines()
                 try:
                     rawrate = lines[4] # the entire contents of line 4
                     rate =(int(rawrate[6:12])/1000) # characters 6-12 of line 4 in kHz
                 except IndexError:
                     rate = 0
            if rate == 0:
               self.send('no signal\n') # here you would substitute your GPIO.output lines and remove self.send()
            elif rate == 44:
               self.send('44 kHz\n')
            elif rate == 48:
               self.send('48 kHz\n')
            elif rate == 88:
               self.send('88 kHz\n')
            elif rate == 96:
               self.send('96 kHz\n')
            elif rate == 176:
               self.send('176 kHz\n')
            elif rate == 192:
               self.send('192 kHz\n')

Now you just need to set the sensor block to loop every half second or so...

Code:
While True:

   [sensor block here, all indented]

   time.sleep (0.5) #indented the same amount
 
Member
Joined 2007
Paid Member
and one last thing for now:

To change LEDs, you won't necessarily know which to turn off. You can define a reset function to turn all off and then just turn on the one you want as follows:

Code:
def reset():
    GPIO.output("P8_9", GPIO.LOW) # everything indented from def statement
    # add lines for all of the other pins, all indented
    # place this just above your loop

Then, change your loop if/elif statements to something like:

Code:
   elif rate == 48:
        reset()
        GPIO.output("P8_9", GPIO.HIGH)
 
Member
Joined 2007
Paid Member
@Heathkit,

I imagine it is unnecessary to change your sample rate LEDs very often - at least relative to the frequency of the code's frequency check. Of course you can change the timing. Also, I would run a comparison between the 'old rate' and the most recent measurement - if they are the same, then no need to reset and turn that LED on again. ...something like:

Code:
with open('/proc/asound/Botic/pcm0p/sub0/hw_params') as f:
                 lines = f.readlines()
                 try:
                     rawrate = lines[4] # the entire contents of line 4
                     rate =(int(rawrate[6:12])/1000) # characters 6-12 of line 4 in kHz
                 except IndexError:
                     rate = 0
            if rate != oldrate 
               oldrate = rate
               if rate == 0:
                  reset()
                  GPIO.output("P8_9", GPIO.HIGH) 
               elif rate == 44:
              
# ...and so forth down the list of rates and pins...
# align the following time sleep with the indentation of line 'if rate != oldrate

            time.sleep (0.5) # or whatever time you choose
You would also want to declare some value for the variable 'oldrate' before the program enters the loop. like: oldrate = 0 # positioned at the far left

Note that Python uses indentation to help organize its various functions, so you need to pay attention to the leading spaces. I'm assuming you have a bit of familiarity with Python, nano, the command line, etc. If not, no worries. We can take a step back and start from wherever you are. I am not a programmer - most of what I know about Python is from messing with BBB audio so I'm sure my code could be better optimized. But the great thing about Python is that you don't need to know 'everything' to do 'anything'. :)

By all means, ask questions freely...
 
Last edited:
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.