Did you manage to get a display to work?Good news; I managed to get the Muses72320 chip working on an Arduino Uno, with and without a library. The best result is with Christoffer Hjalmarsson's Muses library: github.com/qhris/Muses72320
Attenuation goes from -1 to -135dB which is very quiet, but not completely off. Setting attenuation to -447 is basically "mute".
The @alexcp code also worked easily on Arduino, but I can't get it to go very quiet, although Alex confirmed his setup does go very quiet. Maybe there's an error in my code.
I'm also pleased to announce that I managed to make the Muses chip work on the binary PSU supply of the IronPre. That means I don't need an external +-15V supply; just 5V for the digital block of the Muses. The "trick" is to separate the GND's of audio and the digital block. My gratitude goes to Zen Mod for steering my attention in that direction.
I'm now looking for a way to use the ESP32 for controlling the Muses... In its current form, the library doesn't even compile on the ESP32. Does anyone know how to port the library to ESP32?
-135db is apsolutly mute, you might miss gain configuration bits, take a look into datasheet there is not much number of registers and it is easy to configure without a need for any lib,
When I wrote: "Attenuation goes from -1 to -135dB which is very quiet, but not completely off" I actually meant that I can feed the library values from -1 to -135. Whether it corresponds with dB of attenuation or not, I'm not sure or convinced because at -135 I can hear very, very faint sound on 96dB sensitive speakers.
I'm happy to work with that because in my application I want to go from 0 to 100, therefore I'll use the map() function to convert the range.
Did you manage to get a display to work?
No, not yet. My display is a 2.4" TFT LCD screen and for that I need the speed and memory of the ESP32. But I have an idea to make it work without a dedicated Muses library for the ESP32. More about that later when it's successful.
I should mention that my project is still on breadboard so that I can easily make hardware changes if needed, but I think the Muses circuit is close to perfect as it is now. For mounting the Muses chip I used the adapter board shown in post #1. It has been working flawlessly for three days and I'm listening to music through it while I'm typing this.
PS: The unconnected green jumper cable is for the switch on the rotary encoder, which I don't need at this stage.
-135db is apsolutly mute, you might miss gain configuration bits, take a look into datasheet there is not much number of registers and it is easy to configure without a need for any lib,
It might be easy for some, but coding is not my background. Please share an example sketch if you have one.
My code works as advertised, with level going from -111.5dB to 0dB in 0.25dB steps, then from 0dB to 31.5dB in 1dB steps. This was tested with my board and confirmed to you in a private message. BTW -135dB is not achievable with MUSES72320; it goes down to -111.5dB, below which is only MUTE, see the datasheet.The @alexcp code also worked easily on Arduino, but I can't get it to go very quiet, although Alex confirmed his setup does go very quiet. Maybe there's an error in my code.
Also, I have a more advanced formware which is not public yet. I posted a video of that code working a while ago.
I have no doubt that your code works fine for your boards, Alex. The 0dB to 31.5dB gain is achieved with external opamps, and not inside the Muses chip. I suspect that your code didn't work 100% for me because I am not using opamps for gain, while your code addresses opamps on your boards. I'm using the Muses with the Iron Pre which already has 6 or 12dB gain (selectable with a jumper), thus I have no need for opamps. I suspect your code would work for me if I could eliminate the gain instructions in the code.
BTW -135dB is not achievable with MUSES72320; it goes down to -111.5dB, below which is only MUTE, see the datasheet.
Sorry for the misunderstanding around the "-135dB". The Muses library addresses the -115.5dB attenuation, which is native to the 72320 chip by multiplying by 2 so that the attenuation steps can be addressed with integer values. l realized that last night after delving into the library code and saw that inside the library, the integer value gets multiplied by -0.5, effectively halving it again. I erroneously called those integer steps dB in one post and then someone picked up on it and repeated it. It is NOT -135dB as you rightfully pointed out. The library accepts integer values from 0 to 223, which is 115.5 * 2. At -135 (not dB, but steps), attenuation is enough that sound is barely audible.
This is what I found in the library:
// set the volume using the following formula:
// (-0.5 * volume) db
// audio level goes from [-111.5, 0.0] dB
// input goes from -223 to 0.
Now a question about your boards at hifiocean.com: Does the "ground sensing" effectively separate the GNDs of the audio section and the digital block? If it does, I can see that your boards would work well with the Iron Pre using the binary psu of the Iron Pre.
Sorry I don't have it, I just looked into https://www.mouser.com/datasheet/2/294/MUSES72320_E-1710801.pdf , structure of the control bits is very simple, see page 12 to page 22, command structure is only 16bits (two bytes)! Page 12 is important and explain how to write to Muses to control them. It is allso possible to change step size from 0.5db to 0.25db by setting booth volume & gain bits (see page 22). Also care must be satisfied for initial condition (page 13).It might be easy for some, but coding is not my background. Please share an example sketch if you have one.
Here is my short analyse and short example, hope it help for understanding how to control Muses, the rest of mathemnatics keeping for you : )
Code:
volume:
#define VOLUME_BYTE_MIN 16
#define VOLUME_BYTE_MAX 239
if (volume_byte < VOLUME_BYTE_MIN) volume_byte = 0;
if (volume_byte > 0 && volume_byte < VOLUME_BYTE_MIN) volume_byte = VOLUME_BYTE_MIN;
if (volume_byte > VOLUME_BYTE_MAX) volume_byte = 255;
if (volume_byte < 255 && volume_byte > VOLUME_BYTE_MAX) volume_byte = VOLUME_BYTE_MAX;
gain:
#define GAIN_MIN 0
#define GAIN_MAX 63
if (gain_byte == 64) gain_byte = 0.5;
if (gain_byte == 80) gain_byte = 16.5;
if (gain_byte == 96) gain_byte = 32.5;
if (gain_byte == 112) gain_byte = 48.5;
formula:
0 - ((volume_byte x 0.5) - 8) + (gain_byte x 0.5) = volume_db
example:
0 - ((17 x 0.5) - 8) + (9 x 0.5) = 4db
0 - ((0b000010001 x 0.5) - 8) + (0b00001001 x 0.5) = 4db
0 - ((0b11101111 x 0.5) - 8) + (0.5 x 0.5) = -111.25db
Last edited:
With this being a DIY thread on diyaudio.com, with the emphasis on “DIY”, this is how I see the way forward. For me anyway.
Requirements:
Possible implementation:
Split the duties: Drive the Muses and peripherals on two independent boards. May be integrated on one board, but using two MCUs, connected via I2C:
Board A. Slave Arduino-compatible MCU to drive Muses chip via SPI
Board B. Master MCU (ESP32) to control slave MCU via I2C. Master MCU also drives screen, IR & rotary encoder.
With the above setup, there is no need for specialized Muses libraries, except the one already available and working for me.
With this mix-and-match approach, I see this solution as being ideal for the average DIY’er with basic MCU coding experience, because just about any master MCU can be used, whether it’s ESP32, Teensy, PIC, etc., without needing in-depth coding knowledge of writing to the Muses registers. That part has already been taken care of in the Muses library. Just connect your favorite MCU (with peripherals of choice) to the slave MCU board via I2C. There are even some Attiny chips that will allow simultaneous SPI and I2C operations.
Requirements:
- Use a Muses chip for attenuation
- Preferably use the +-15V binary psu of the Iron Pre (need galvanically isolated GNDs)
- Use screen of choice: TFT LCD, 2.4” in my case
- IR remote control: Apple TV remote preferably
- Hi-res rotary encoder: 200 steps per rotation preferably
- Easy integration with my MCU of choice (ESP32)
- There is no need for gain as the Iron Pre already has enough gain.
Possible implementation:
Split the duties: Drive the Muses and peripherals on two independent boards. May be integrated on one board, but using two MCUs, connected via I2C:
Board A. Slave Arduino-compatible MCU to drive Muses chip via SPI
Board B. Master MCU (ESP32) to control slave MCU via I2C. Master MCU also drives screen, IR & rotary encoder.
With the above setup, there is no need for specialized Muses libraries, except the one already available and working for me.
With this mix-and-match approach, I see this solution as being ideal for the average DIY’er with basic MCU coding experience, because just about any master MCU can be used, whether it’s ESP32, Teensy, PIC, etc., without needing in-depth coding knowledge of writing to the Muses registers. That part has already been taken care of in the Muses library. Just connect your favorite MCU (with peripherals of choice) to the slave MCU board via I2C. There are even some Attiny chips that will allow simultaneous SPI and I2C operations.
Look at page 12 first, you should notice 16 bits D15 to D0, every D represent bit value and what every each mean, so in short explanation you need to set the right control data bits (see table what each bit mean), when you set right control bits you need to send it to Muses. Its allways writen in 16bits (or two bytes). Post above is just for how to calculate volume level by setting booth gain+volume, you will need to understand it first and add your own loogic for it, I'm just wrote few examples which you can compare with tables from datasheet to understand, my hope it is easy for you to understand that configuration bits and in the same time gain+volume settings of the Muses. I never using any libraries, instead I always writing my own logic by looking into datasheet : ) Writing this because I do not found complete Muses library on the net, expecialy didn't found any logic for step=0.25, my examples with a further mathematic work might help for completing those libraries.
Last edited:
I really appreciate you taking the time to explain how it's done. I will certainly study your posts and see if I can do it.
This is exactly why I've started this thread!
This is exactly why I've started this thread!

This might help too expecialy for setting bits D15-D0 to the Muses registers : )
https://www.binaryhexconverter.com/hex-to-binary-converter
https://www.binaryhexconverter.com/binary-to-hex-converter
https://www.binaryhexconverter.com/decimal-to-binary-converter
https://www.binaryhexconverter.com/binary-to-decimal-converter
https://www.binaryhexconverter.com/hex-to-binary-converter
https://www.binaryhexconverter.com/binary-to-hex-converter
https://www.binaryhexconverter.com/decimal-to-binary-converter
https://www.binaryhexconverter.com/binary-to-decimal-converter
This might help too expecialy for setting bits D15-D0 to the Muses registers : )
I was just busy converting decimal to binary when you posted. Those are nice converters. 👍
Question: If I don't want any gain, but just want to set volume, how do I write that into the registers? Is there a separate command for writing volume? In other words, is it possible to ignore gain and just set volume?
I guess I'm asking if the 16-bit command structure is made up of gain + volume or are they set independently?
Sorry, I realize these are very much beginner questions, but I have to start somewhere. 😵
Yes, see my formula! Volume is sum of (0 - volumebyte + gainbyte). You can even set step 50, or step 100, or step 1, just right D bit configuration need to be set! And a bit of mathematics too is need : ) . Thats easy to understand if you look into page 12, try to understand each D bit first! Writing to Muses is always in 16bits, so for example you want to set volume_db=-111.25db for example to left channel (take a look into bits D5 and D4 on table on page 12) you need to set bitD4=0 and bit D5=0, also you need to st cont1, cont2... every other bit from D15 to D0, for example to get volume level for left channel=-111.25db (see my example) you need to set all bits for example like this:
11101111 (D15-D8) Lch Volume Control (Att.) in my example its volume_byte
0000 (D7-D4) address for Lch Volume Control (Att.)
0 (D3 is always zero)
000 (D2-D0) hardware pin address configuration
so now you have all 16 bits which you need to write to Muses:
11101111 00000000
for example if you convert 11101111 to decimal you getting 239, use formula from my example. Configuring everything is trought right D bit value, for example if you need to set right channel just change corensponding D bit value in our 16bit container. Whole formula from my example post need to be reverse enginered, for example you should use volume_db in your mcu code as a changeable value, you just need to define step size, and reverse enginer my formula for volume_byte and gain_byte which you need to write to corensponding D bit register. A bit of more work is need for mcu code, but my hope example I have gaved is easy to uderstand including explanation about D15-D0 which you need to understand from datasheet. Understanding bits from datasheet is helpfull for understanding every other ic without a need for any library.
11101111 (D15-D8) Lch Volume Control (Att.) in my example its volume_byte
0000 (D7-D4) address for Lch Volume Control (Att.)
0 (D3 is always zero)
000 (D2-D0) hardware pin address configuration
so now you have all 16 bits which you need to write to Muses:
11101111 00000000
for example if you convert 11101111 to decimal you getting 239, use formula from my example. Configuring everything is trought right D bit value, for example if you need to set right channel just change corensponding D bit value in our 16bit container. Whole formula from my example post need to be reverse enginered, for example you should use volume_db in your mcu code as a changeable value, you just need to define step size, and reverse enginer my formula for volume_byte and gain_byte which you need to write to corensponding D bit register. A bit of more work is need for mcu code, but my hope example I have gaved is easy to uderstand including explanation about D15-D0 which you need to understand from datasheet. Understanding bits from datasheet is helpfull for understanding every other ic without a need for any library.
Last edited:
Fantastic, I understand all of it so far. The 16-bits contain all the info to send to the chip, from the volume D15-D8, the channel D5 and D4, and finally the chip address with D3-D0.
So, reverse engineer means taking the desired dB and calculate what D15-D8 should be and adding the remainder of the D bit values?
So, reverse engineer means taking the desired dB and calculate what D15-D8 should be and adding the remainder of the D bit values?
yes! : )
Look from page12 to page22 what D bit configuration can be or what can not be writen when or when not! The rest I see you understand well : )
After volume left ch registers and you want to write to left gain registers you just need to repat writing 16bits to Muses but this time D7-D4 is diferent, see table on page 12 (row/col of the D bits).
Look from page12 to page22 what D bit configuration can be or what can not be writen when or when not! The rest I see you understand well : )
After volume left ch registers and you want to write to left gain registers you just need to repat writing 16bits to Muses but this time D7-D4 is diferent, see table on page 12 (row/col of the D bits).
Last edited:
Great. I'm looking at your example formula: 0 - ((0b11101111 x 0.5) - 8) + (0.5 x 0.5) = -111.25db but I have no idea how to code that calculation. Is it done with the itoa() function in C++ (for Arduino)?
Obviously one has to stay within the MIN and MAX constraints of what the chip can handle, set by the if statements you gave previously.
Obviously one has to stay within the MIN and MAX constraints of what the chip can handle, set by the if statements you gave previously.
https://www.google.com/search?q=0+-+((0b11101111+x+0.5)+-+8)+++(0.5+x+0.5)&oq=0+-+((0b11101111+x+0.5)+-+8)+++(0.5+x+0.5)
0b11101111 is binary value, use 11101111 and put in converter I have gaved, you can use hex, dec or bin it is the same when using formula! Writing in binary form is better for understanding when you looking into D15-D0 from datasheet : )
0b11101111 is the same as 239 is he same as 0xEF
0.5 or 111.25 is a float value, whole formula is an float value
0b11101111 is binary value, use 11101111 and put in converter I have gaved, you can use hex, dec or bin it is the same when using formula! Writing in binary form is better for understanding when you looking into D15-D0 from datasheet : )
0b11101111 is the same as 239 is he same as 0xEF
0.5 or 111.25 is a float value, whole formula is an float value
Last edited:
You can predefine an hardcoded 16bit value for test in your code without any math, use math trought google, for example predefined 16bit value looks like this
in bin:
unsigned short bits_to_send = 0b1110111100000000;
or
uint16_t bits_to_send = 0b1110111100000000;
or the same in dec:
uint16_t bits_to_send = 61184;
or the same in hex:
uint16_t bits_to_send = 0xFE00;
than write to Muses for example (I don't know arduino function code for serial comunication, not using arduino at all, so this is just an example):
write_to_muses_function(bits_to_send);
bits_to_send = 0b1111010101100100; // changed bits
write_to_muses_function(bits_to_send); // repeat write another config. for right channel... etc...etc
Hope this help : )
in bin:
unsigned short bits_to_send = 0b1110111100000000;
or
uint16_t bits_to_send = 0b1110111100000000;
or the same in dec:
uint16_t bits_to_send = 61184;
or the same in hex:
uint16_t bits_to_send = 0xFE00;
than write to Muses for example (I don't know arduino function code for serial comunication, not using arduino at all, so this is just an example):
write_to_muses_function(bits_to_send);
bits_to_send = 0b1111010101100100; // changed bits
write_to_muses_function(bits_to_send); // repeat write another config. for right channel... etc...etc
Hope this help : )
Last edited:
- Home
- Amplifiers
- Pass Labs
- Digital Control of Attenuation – Repository for DIY