As a Roon user, I don’t like the idea to use the BluOS Controller application to change settings on my M33.
The application use Rosetta 2 on Mac Mx and is rather slow.
So I want to share the following small application as a Universal Binary, it will add a menu on top of your Mac screen to do the simple things, the Hardware remote control can’t do.
It was tested using a NAD M33, it was confirmed to work with the M10V2 too, it should work with all BlueSound enabled devices but I think the Standby will only work on NAD devices.
At the first launch of the application you should see this screen:
Enter the IP address of your M33 and press OK.
If the address is not correct or the player is offline, you will be asked to re-enter it until it can connect to it.
Once the address have been validated a menu will appear on top of your screen:
The menu name is your NAD M33 name so try to keep it as short as possible because you will fill your MacOS Topbar pretty quick and when there is no more space MacOS remove silently some items from this bar..
In the menu you will find the following:
System wide hotkeys you can use to mute and control the volume:
I don’t think you will need more explanations for the usage of this menu as it is pretty straitforward. The “*” means that the option is currently used in the NAD M33 ( for Mute, Sources and DIRAC )
If the NAD M33 go offline ( power off or reboot ) The menu will change to ( can take up to 30 seconds to detect availability status change ):
11/29/2023: Fixed Sources after a BlueOs update, hopefully fixed a crash on volume manipulation and lower energy consumption when the player is offline.
08/06/2023: Added an option to hide the Dock Icon.
07/25/2023: Added a “Standby” option and a hotkey to trigger it. ( Player power up automatically on Source change or Stream play and can be turned off using this new function
07/25/2023: The “Players” menu option should only be seen when there are more than one player IP saved
07/25/2023: Added a multi device support, added hotkeys for Back, Play/Pause and Skip
07/22/2023: Increase timeout for player detection, seems to be needed for some users, probably using WIFI connection on the player
07/22/2023: Add hotkeys for Volume control see the HELP option in the menu
07/21/2023: Add Popup for Volume control
07/12/2023: Initial version
As I’m not on registered Apple developper, you will have to authorize the application to run on your Mac ( See in your Mac Security options ) This is needed only at the first launch.
After some tests, I did find that the Basic audio system in the ID.4 is as the name let you know “basic”…
Here is how you can change the audio system to get a much better sound quality.
Tools needed, I think it is better to get the official tools from Audi or VW but any plastic tool should work too.
These tools can be brought on eBay.
2. Select the wanted audio gears
Depending on the system you want, you will want to replace the original speakers and add an amplifier to get a cleaner output from your new speaker, the original system is only 4x20watts.
Speakers:
Front and rear speakers are 165mm ( 6.5′ ) the front ones are separated kits while the rear are coaxial ones.
For my car I choose to go with Focal Flax series, but any decent brand should do the work.
Why Focal you may ask, probably because I use them since a lot time and I knew I would not be disappointed with them.
So the specific items I selected are the following:
You can find them in local Car audio dealers or on Amazon.
You can find them in local Car audio dealers or on Amazon.
Electronics:
For the amplifier, I choose to go with Focal Impulse 4.320, I took this one because it is a very small 4x55watts amplifier and because Focal provide all the needed cables to connect it to the ID.4 without cutting a single car’s cable, it is really a plug and play setup.
Cable to connect the amplifier between the VW infotainment system and the car, basically steal the power and the speaker output from the stock car audio system and inject the newly powered output from the new amplifier to the car speakers.
This adapter simulate speakers on the stock infotainment, without it, the car will show an error message and disable some of its features like the front radar and the ACC. This is used to trick the stock system that there are actually speakers connected to the system.
Cable to extend the connection cables so you can hide the amplifier about where you want in the car’s front.
Amplifier installation
You first have to get access to the infotainment system, it is located behind the glove Box, first you have to open and empty the glove box, open it to the max, the front glove box will go out and stay on the car floor.
Then look in the compartiment, you will see 4 trox, remove them and remove the upper panel, you will then see the infotainment behind it.
You should now see the infotainment unit un front of you, I don’t have the picture but it is the black box with 2 holder on each sides, press the holder and the unit will freely come to you
The amplifier can be placed behind the glovebox on the right of it, there is a free space that can hold the amplifier and the tweeter filter so don’t close everything right now as you probably want to put the filter there later and you will want to fine tune the amplifier gain.
Tweeter installation
You have to get access to the stock tweeter, prolong the tweeter connection to go to the Focal tweeter and then send the Focal tweeter to the filter the Focal tweeters are pre-wired with about 1m of cable so you should be able to hide the filter somewhere in the front and directly connect the tweeter to the filter.
First using the tool T10383/1, remove clip A, then clip B and then slide the whole part, disconnect the tweeter. Clip removal can be hard, don’t give up, it will finally comes to you π
Do the same for both tweeters.
Remove the original tweeter
Tweeter installation
Once this is done, you can place your tweeters, fix them as you can depending on your tweeter model, it can be with some kind of wire beheind the car’s tweeter grille or with some glue, you will find a lot of information source on internet, make sure they are fixed and don’t move.
I didn’t removed the Focal grille as they serve to ensure that no parts will touch the tweeter dome ( it would die immediately if something touch it )
Prolong the car’s cable to the filter, connect it to the filter and put some tape around the cable to ensure your connection will never be lost.
Once you have connected the tweeter to the filter, you can put both parts back in place in the car, you will not need access to them anymore.
Don’t hide the filter to far away for the moment as you will perhaps want to fine tune the filters. I don’t have done it as I found the default pleasant.
Door panel removal
This section apply for all 4 door speaker and door panel removal are about the same for all of the doors, some doors have more connectors than others but still the principle is the same and I will not do separate explanation for them, simply be gentle with your door panels and internal connectors.
Gently remove the door panel with T10383 /0, disconnect all of the cables
I usually start from bottom external corner and then bottom and then each side.
On YouTube, you can find some generic VW door panel removal, as this is pretty standard, you can watch any of them to get an idea.
If you break some of the holders, you can find them on eBay or by your car dealer, it can be handy to get some spares before the door panel removal.
Speaker removal
To remove the original speakers, you have to drill and remove the 4 bits on each speakers.
Do that gently and slowly to no damage your car door.
Once the speaker is removed, you can install the speaker adapter of you liking.
Once the adapters are in place you can install the Focal Woofer in it, keep them out of metallic garbage, clean the work area before hand!
Front speaker installed and connected in the VW ID.4.
Et voilΓ ! The speaker is installed, you can close the door panel using the above instructions in the reverse way.
Completely remove the glove box to get it out of your way. There are 2 plastic pins that need to be slid inward and it will come out. Careful, the dampening gear assembly will most likely fall on the floor when dropping the glove box. Make sure you save the 2 pieces as you will have to reinstall them. Once all back together, if your glove box open instantly but goes up slowly, the gear assembly needs to be flipped 180*.
When installing the tweeters, a hot glue gun works really well to attach the tweeters to the A-Pillar
When doing the Crossovers (X-over) — you called them filters — You have to cut into the LF and RF speaker wires to provide input into the crossover. White/white-black is for the LF speaker and Grey/grey-black is for the RF speaker.
You will have to slightly untape the harness to find out which pair of wires are the output vs. the input, they are all taped together.
Also the speaker simulator needs to go before the amplifier input, not after.
Finally, when shopping for speaker adapters, they need to be 1.25″ deep otherwise the door panels won’t fit back on.
Final setup
Once all of the speaker are connected, play some sound and verify that you get sound on each newly installed speakers, set the infotainment to flat setting and balanced fader. Adjust the amplifier gain and of needed adjust you tweeter filters.
Remember that speaker kit tend to improve after several hours of use, don’t go to full volume when the speakers are brand new, let them adjust a bit before that.
They are plenty of documentation on the internet and on the Focal website on how to correctly adjust the amplifier gain.
When happy with your setup, hide the filters in the from of the car, fix them in a way they will not interfere with your ability to drive the car and that they don’t move by themself. But don’t fix them too strongly so you can once come back to them in case you want to tweak the setup a bit more.
The same apply for the amplifier, fix it to the right of the glove box with some plastic straps so you can still come back to it to change the gain if you did a mistake.
Final ideas
If you find it to be too tricky, you can go with the Focal plug and play lineup, you will have no problem fixing the tweeter, the car cables are not altered in any way and all of the newly installed speaker use the original cables, the woofer is directly compatible and don’t need any adapter. It would still be better to get the amplifier anyway.
One of the task dbas have to do is to quickly upgrade Oracle database and binaries, this post will list you the short path to upgrade an Oracle database from 10g to 11.2.
Do a normal install of Oracle 11.2.0.4 with latest PSU applied. ( don’t touch the 10g version as you need it to upgrade the databases )
On the 10g database run the script utlu112i.sql this script is shipped with the 11.2.0.4 you just have installed. Fix all problems the script showed up!
On the 10g, connected as sysdba do the following cleaning tasks:
cd $ORACLE_HOME/rdbms/admin
$ sqlplus / as sysdba
SQL> startup UPGRADE
SQL> set echo on
SQL> SPOOL upgrade.log
SQL> @catupgrd.sql
$ sqlplus / as sysdba
SQL> STARTUP
SQL> @utlu112s.sql
SQL> @utlrp.sql
SQL> @catuppst.sql
SQL> @utlrp.sql
SQL> shutdown
SQL> startup
SQL> alter system set compatible='11.2.0.4' scope=spfile;
SQL> shutdown immediate
SQL> startup
SQL> exit
Your DB is now upgraded to 11.2.0.4, congrats!
If utlu112i.sql let you know that you should upgrade the timezone definition, then follow the next few steps:
cd $ORACLE_HOME/rdbms/admin $
sqlplus /AS sysdba
shutdown immediate;
startup upgrade;
SET serveroutput ON-- check if previous prepare window is endedSELECT PROPERTY_NAME, SUBSTR(property_value,1,30)VALUEFROM DATABASE_PROPERTIES
WHERE PROPERTY_NAME LIKE'DST_%'ORDERBY PROPERTY_NAME;
-- output should be-- PROPERTY_NAME VALUE-- - -- DST_PRIMARY_TT_VERSION <the old DST version number>-- DST_SECONDARY_TT_VERSION 0-- DST_UPGRADE_STATE NONE
purge dba_recyclebin;
TRUNCATETABLE SYS.DST$TRIGGER_TABLE;
TRUNCATETABLE sys.dst$affected_tables;
TRUNCATETABLE sys.dst$error_table;
ALTERSESSIONSET"_with_subquery"=materialize;
ALTERSESSIONSET"_simple_view_merging"=TRUE;
EXEC DBMS_DST.BEGIN_UPGRADE(14);
-- check if this selectSELECT PROPERTY_NAME, SUBSTR(property_value,1,30)VALUEFROM DATABASE_PROPERTIES
WHERE PROPERTY_NAME LIKE'DST_%'ORDERBY PROPERTY_NAME;
-- gives this output:-- PROPERTY_NAME VALUE-- -- DST_PRIMARY_TT_VERSION <the new DST version number>-- DST_SECONDARY_TT_VERSION <the old DST version number>-- DST_UPGRADE_STATE UPGRADE
shutdown immediate
startup
ALTERSESSIONSET"_with_subquery"=materialize;
ALTERSESSIONSET"_simple_view_merging"=TRUE;
SET serveroutput ON
VAR numfail NUMBERBEGIN
DBMS_DST.UPGRADE_DATABASE(:numfail,
parallel =>TRUE,
log_errors =>TRUE,
log_errors_table =>'SYS.DST$ERROR_TABLE',
log_triggers_table =>'SYS.DST$TRIGGER_TABLE',
error_on_overlap_time =>FALSE,
error_on_nonexisting_time =>FALSE);
DBMS_OUTPUT.PUT_LINE('Failures:'|| :numfail);
END;
/-- ouput of this will be a list of tables like:-- Table list: SYSMAN.AQ$_MGMT_NOTIFY_QTABLE_S-- Number of failures: 0-- if there where no failures then end the upgrade.
VAR fail NUMBERBEGIN
DBMS_DST.END_UPGRADE(:fail);
DBMS_OUTPUT.PUT_LINE('Failures:'|| :fail);
END;
/-- output that will be seen:-- An upgrade window has been successfully ended.-- Failures:0SELECT PROPERTY_NAME, SUBSTR(property_value,1,30)VALUEFROM DATABASE_PROPERTIES
WHERE PROPERTY_NAME LIKE'DST_%'ORDERBY PROPERTY_NAME;
-- needed output:-- PROPERTY_NAME VALUE-- - -- DST_PRIMARY_TT_VERSION <the new DST version number>-- DST_SECONDARY_TT_VERSION 0-- DST_UPGRADE_STATE NONESELECT*FROM v$timezone_file;
-- needed output:-- FILENAME VERSION-- --- timezlrg_14.dat 14SELECT TZ_VERSION FROM registry$database;
UPDATE registry$database SET TZ_VERSION =(SELECT version FROM v$timezone_file);
commit;
These B4X modules will handle the synchronization of key/value databases between multiple devices and between platforms!
So one application runs on a server widely available on the internet such as a low cost VPS that can run java applications.
Then each application have to add simple code to get synchronized variables.
ckvs.Put("User1", "Key1", 100)
Log(ckvs.Get("User1", "Key1")) '100
Log(ckvs.GetDefault("User2", "Key1", 0)) '0 because User2/Key1 is different than User1/Key1
ckvs.Put("User1", "Key1", 100)
Log(ckvs.Get("User1", "Key1")) '100
Log(ckvs.GetDefault("User2", "Key1", 0)) '0 because User2/Key1 is different than User1/Key1
The SetAutoRefresh method sets the user(s) that will be fetched from the remote store.
For example if we want to auto-synchronize the data of “User1”:
ckvs.SetAutoRefresh(Array("User1"), 5)
ckvs.SetAutoRefresh(Array("User1"), 5)
Sample Code:
'Code module
#Region Project Attributes
#ApplicationLabel: B4i Example
#Version: 1.0.0
'Orientation possible values: Portrait, LandscapeLeft, LandscapeRight and PortraitUpsideDown
#iPhoneOrientations: Portrait, LandscapeLeft, LandscapeRight
#iPadOrientations: Portrait, LandscapeLeft, LandscapeRight, PortraitUpsideDown
#Target: iPhone, iPad
#MinVersion: 7
#End Region
Sub Process_Globals
'These global variables will be declared once when the application starts.'Public variables can be accessed from all modules.Public App As Application
Public NavControl As NavigationController
Private Page1 As Page
Type Item (UserField AsString, KeyField AsString, ValueField() AsByte, IdField AsLong, TimeField AsLong)
Type Task (TaskName AsString, TaskItem As Item)
Private ckvs As ClientKVS
Private TextField1 As TextField
Private User AsString = "u1"EndSubPrivateSub Application_Start (Nav As NavigationController)
NavControl = Nav
Page1.Initialize("Page1")
Page1.RootPanel.LoadLayout("1")
NavControl.ShowPage(Page1)
ckvs.Initialize(Me, "ckvs", "http://xxx.nopapers.org:12345")
ckvs.SetAutoRefresh(Array(User), 0.1) 'auto refresh every 0.1 minutes
TextField1.Text = ckvs.GetDefaultAndPut(User, "number", 0)
EndSubPrivateSub ckvs_NewData
TextField1.Text = ckvs.Get(User, "number")
EndSubSub btnSet_Click
Dim number As Int = TextField1.Text
ckvs.Put(User, "number", number)
Page1.ResignFocus
EndSubPrivateSub Page1_Resize(Width As Int, Height As Int)
EndSubPrivateSub Application_Background
EndSub
'Code module
#Region Project Attributes
#ApplicationLabel: B4i Example
#Version: 1.0.0
'Orientation possible values: Portrait, LandscapeLeft, LandscapeRight and PortraitUpsideDown
#iPhoneOrientations: Portrait, LandscapeLeft, LandscapeRight
#iPadOrientations: Portrait, LandscapeLeft, LandscapeRight, PortraitUpsideDown
#Target: iPhone, iPad
#MinVersion: 7
#End Region
Sub Process_Globals
'These global variables will be declared once when the application starts.
'Public variables can be accessed from all modules.
Public App As Application
Public NavControl As NavigationController
Private Page1 As Page
Type Item (UserField As String, KeyField As String, ValueField() As Byte, IdField As Long, TimeField As Long)
Type Task (TaskName As String, TaskItem As Item)
Private ckvs As ClientKVS
Private TextField1 As TextField
Private User As String = "u1"
End Sub
Private Sub Application_Start (Nav As NavigationController)
NavControl = Nav
Page1.Initialize("Page1")
Page1.RootPanel.LoadLayout("1")
NavControl.ShowPage(Page1)
ckvs.Initialize(Me, "ckvs", "http://xxx.nopapers.org:12345")
ckvs.SetAutoRefresh(Array(User), 0.1) 'auto refresh every 0.1 minutes
TextField1.Text = ckvs.GetDefaultAndPut(User, "number", 0)
End Sub
Private Sub ckvs_NewData
TextField1.Text = ckvs.Get(User, "number")
End Sub
Sub btnSet_Click
Dim number As Int = TextField1.Text
ckvs.Put(User, "number", number)
Page1.ResignFocus
End Sub
Private Sub Page1_Resize(Width As Int, Height As Int)
End Sub
Private Sub Application_Background
End Sub
Caution the identifierForVendor value will change if your user reinstall all of your apps ( the identifier is computed using the 2 first parts of your appId.
If your Appid is org.nopapers.myApp then identifier is computed using org.nopapers.