Home AMX User Forum AMXForums Archive Threads AMX Hardware AutoPatch Forum

AutoPatch Volume?

I'm just about done writing a module for the new AP 18 x18 w/ DSP and up until a couple of days ago I was programming with a AP unit that wasn't hooked up to any other audio equipment and all went well with no problems. I finally got it hooked up on site the other day but noticed my audible volume range wasn't that great. The lower bargraph indication 0 of a 0-100 scale was still audibly loud where I resonably expected mute or near mute results. On the other end of the scale the volume was loud but not as loud as I would have expected. It was a comfortably loud level and I'm using 55 watts per channel B & K amps. Not obnoxiuously loud or distorted as I would expect at +10 db out of the AP. My amp gain levels are sent mid range, so I do have play there. I'm sending converted absolute levels from -70 to + 10 and everything in between and my returned string mirrors (echos) my values but I'm not audibly getting the range I'm expected. I haven't adjusted any input gains or any EQ but that shouldn't affect my outputs in a manner where my low vloume is too too high and my high volume is too low.

I haven't gotten too deep into this yet because it does work and I have so many other things to get online and working before I isolate this problem.

To any of you guys that have used these AP switches before: you do get a full range of audible volume control, right! These are supposed to be absolute db values -70 to +10 being sent so it should be!

Comments

  • DHawthorneDHawthorne Posts: 4,584
    I've not used many of them, but where I have, I haven't seen this problem. Perhaps it's more the amp than the preamp (Autopatch) stage.
  • I've only used the 8x8 DSP and haven't had this problem. I would check the settings of the switcher with the autopatch APcontrol program, it could be the input gains or some other setting.
  • Spire_JeffSpire_Jeff Posts: 1,917
    Are you sending -700 and 100 for -70db and 10db? The autopatch interprets the numbers with one decimal place (ie -7.0 and 1.0), so simply multiplying the volume by 10 should work if you are using -70 to 10 as your range.

    I am using an Autopatch Precis LT 18x18 here at the office with B&K amps and the volume levels are no problem.

    Jeff
  • viningvining Posts: 4,368
    Spire_Jeff wrote:
    [quopte]
    Are you sending -700 and 100 for -70db and 10db?
    [/quote]
    That's probably what it is and I know that's what the manual says but it seems every time I tried 3 digits like that I would get some thing screwed up back. I though it was another one of those things where they chnage the paremeters from what's published and just don't let any one know. That sound like it matches my symptom, I give that a real second attemp.
  • Joe HebertJoe Hebert Posts: 2,159
    vining wrote:
    Spire_Jeff wrote:
    Are you sending -700 and 100 for -70db and 10db?
    That's probably what it is and I know that's what the manual says but it seems every time I tried 3 digits like that I would get some thing screwed up back.
    For what it's worth, I can confirm that -700 to 100 are the correct values to send. I did have one instance where the installer said the volume wasn't working and I was getting odd returns. Turns out the problem was they accidentally ordered the Precis without the DSP.
  • viningvining Posts: 4,368
    Ok, everything seems to work alot better going from -700 to 100 then from -70 to 1. Go figure! I also realize the way I was handling and storing my volumes was a bit absurd trying to store my values in a 0 - 100 scale, doing math to convert from sinteger to float with type casting, what a mess. I now store native AP sinteger values and just do conversions for the bargraph level displays which is so much simpler.

    I was using the conversion examples that was posted a month or so ago but that example didn't have the additional divide by 10 that's needed.
    //Note: in the example below audio input 1 = off.
    if(sAP_Zone[i].Selected || sAP_Zone[i].AudioIn > 1)
    	       {
    	       SEND_LEVEL dvTP_Arry,nAP_LVLBtnArry[(LVL_OUTPUTS - 1) + i],((sAP_Zone[i].Volume / 10) + 70) * 1.25 ;
    	       }
    	  else
    	       {
    	       SEND_LEVEL dvTP_Arry,nAP_LVLBtnArry[(LVL_OUTPUTS - 1) + i],0 ;
    	       }
    

    Thanks for the inputs!
  • flcusatflcusat Posts: 309
    vining wrote:
    Ok, everything seems to work alot better going from -700 to 100 then from -70 to 1. Go figure! I also realize the way I was handling and storing my volumes was a bit absurd trying to store my values in a 0 - 100 scale, doing math to convert from sinteger to float with type casting, what a mess. I now store native AP sinteger values and just do conversions for the bargraph level displays which is so much simpler.

    Daniel do you have a real mute when you go all the way down to -700 or press mute? Somebody reported the following a little while ago in another forum.

    Has anyone noticed with the DSP units that the MUTE command seems to mute until you put your ear next to the speaker where you can still hear the sound a bit? Might not seem like a big until you have a totally quiet house in the middle of the night with a pair of Paradigm Sig 2s run through an MCA20 amp on the desk where the homeowner is working...
  • viningvining Posts: 4,368
    flcusat wrote
    do you have a real mute when you go all the way down to -700 or press mute?
    I don't know, I made the code changes remotely and just watched my debug variables while viewing the TP in VNC. I guess technically I don't know for sure that everything is working fine but it looks good.

    I'll be there later this morning and check it out.
  • flcusat wrote:
    Daniel do you have a real mute when you go all the way down to -700 or press mute? Somebody reported the following a little while ago in another forum.

    It might have been the poor excuse for a control system that guy was using.

    The Precis with DSP also has a command to completely disconnect the output from any inputs.
  • flcusatflcusat Posts: 309
    AVOPHILE wrote:
    It might have been the poor excuse for a control system that guy was using.

    The Precis with DSP also has a command to completely disconnect the output from any inputs.

    I suspected about that Doug, but I just want to confirm.
  • I was dealing with an Autopatch Precis LT with DSP today, and everything went smoothly with one exception.

    Although I can capture the Autopatch volume ranges, parse them individually and convert them to 0-100 values, when I tried to store the Autopatch values in an array, they appeared in debug as values in the 60K range.

    Here are my variable declarations and my string handler:
    DEFINE_VARIABLE
    
    PERSISTENT INTEGER nCURRENT_ZONE
    
    PERSISTENT SINTEGER nAPVOL [18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    
    PERSISTENT INTEGER nLEV	[18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}		
    
    CHAR sBUFFER [100]
    CHAR sREPLY [100]
    
    CHAR	sTMP10	[30]
    CHAR	sTMP20	[30]
    
    VOLATILE nLENGTH
    
    PERSISTENT SINTEGER nVOLUME
    
    DATA_EVENT[dvSWTCH]
    {
    STRING: 
        {
        WHILE (FIND_STRING(DATA.TEXT,"13",1)) 
    	{ 
    	sREPLY = "sBUFFER, REMOVE_STRING (DATA.TEXT,"13",1)"
    	CLEAR_BUFFER sBUFFER
    	IF (FIND_STRING(sREPLY," '(' ",1)) 
    	    {
    	    REMOVE_STRING (sREPLY," '( ' ",  1)
    	    nLENGTH = LENGTH_STRING (sREPLY)
    	    sTMP10 = sREPLY
    	    sTMP20 = LEFT_STRING (sTMP10, (nLENGTH-3))
    	    nVOLUME = ATOI (sTMP20)
    	    nAPVOL [nCURRENT_ZONE] = nVOLUME
    	    nLEV [nCURRENT_ZONE]= ((ATOI(sTMP20)+ 700)/8)  
    	    SEND_LEVEL dvTP3, 2, ( nLEV [nCURRENT_ZONE])
                }
            }
        }
    }
    

    Although nVOLUME appears as the expected Autopatch level of -700 to +100 in debug, when I store the nVolume variable in the nAPVOL array, it goes from the expected values to values up in the 60,000's.

    Does anyone have an idea why this is happening?

    By the way, I was initially capturing the Autopatch strings in DATA.TEXT, but moved to this method in an attempt to follow Tech Note 616.

    I'm not quite sure why this implementation would be in any way superior to working straight from DATA.TEXT, as I am not really creating a buffer, I am simply creating a variable called buffer.

    Thanks to all who have posted code dealing with the Autopatch in the past.
  • viningvining Posts: 4,368
    Here's the conversion that Dave posted a while back.
    Autopatch to level:                                   
    where db = Autopatch volume, nVol = level value       
                                                          
    (db + 70) * 1.25 = nVol for a level scale of 0-100.   
    (db + 70) * 3.1875 = nVol for a level scale of 0-255. 
                                                          
    Level to Autopatch:                                   
                                                          
    (nVol / 1.25) - 70 = db for level scale 0-100         
    (nVol / 3.1875) - 70 = db for level scale 0-255       
    

    I found it cleaner to parsed the return from the AP and store the value natively, that is, leave it as a singed integer, manipulate as a signed integer while adding or subtracting to increase or decrease the volume and only convert it to 0-100 scale to display as a level. I don't beleave in volume bar graph for active touch volume setting because it's very easy for someone to accidentially touch the bar graph at the high end and annoy the heck out of every one. I do like and use the bargraph for display and use up/dwn arrow to increase or decrease levels. Active bargraph to set lighting levels is one thing but IMHO not for setting audio levels especially w/ kids around!

    In my example below, which was also posted earlier in this thread I added / 10 to the above examples for the level to dispaly correctly.
    //Note: in the example below audio input 1 = off.
    if(sAP_Zone[i].Selected || sAP_Zone[i].AudioIn > 1)
    	       {
    	       SEND_LEVEL dvTP_Arry,nAP_LVLBtnArry[(LVL_OUTPUTS - 1) + i],((sAP_Zone[i].Volume / 10) + 70) * 1.25 ;
    	       }
    	  else
    	       {
    	       SEND_LEVEL dvTP_Arry,nAP_LVLBtnArry[(LVL_OUTPUTS - 1) + i],0 ;
    	       }
    
  • vining wrote:

    I found it cleaner to parsed the return from the AP and store the value natively, that is, leave it as a singed integer, manipulate as a signed integer while adding or subtracting to increase or decrease the volume and only convert it to 0-100 scale to display as a level.

    This is what I am trying to do as well, and it is working, except when I try to store the SINTEGER nVOLUME in the SINTEGER array nAPVOL [nCURRENT_ZONE].

    When I increment or decrement the volume, the nVOLUME variable changes from -700 to 100 by tens, but the array values display in the 60,000's, and increment inconsistently... by relatively small amounts like 10's. Dividing by ten won't fix this.

    This is happening in debug, and I am displaying in ASCII and decimal as appropriate.
  • DHawthorneDHawthorne Posts: 4,584
    AVOPHILE wrote:
    This is what I am trying to do as well, and it is working, except when I try to store the SINTEGER nVOLUME in the SINTEGER array nAPVOL [nCURRENT_ZONE].

    When I increment or decrement the volume, the nVOLUME variable changes from -700 to 100 by tens, but the array values display in the 60,000's, and increment inconsistently... by relatively small amounts like 10's. Dividing by ten won't fix this.

    This is happening in debug, and I am displaying in ASCII and decimal as appropriate.

    It sounds an awful lot like a variable type overflow, as if ATOI wasn't returning a signed INT like it ought. I can't see anything in your code that runs it through an intermediate of the wrong type, but some internal typecasting might be introducing one. Have you tried changing nVolume to an SLONG and using ATOL instead? Another trick I have found that works in some cases is to short-circuit internal typecasting by not doing multiple conversions in the same statement ... which means no arithmetic on the value either, since they generated typecasting too. Your code is fine in that respect, but it's something to look for in this kind of situation.
  • Spire_JeffSpire_Jeff Posts: 1,917
    vining wrote:
    I don't beleave in volume bar graph for active touch volume setting because it's very easy for someone to accidentially touch the bar graph at the high end and annoy the heck out of every one. I do like and use the bargraph for display and use up/dwn arrow to increase or decrease levels. Active bargraph to set lighting levels is one thing but IMHO not for setting audio levels especially w/ kids around!

    I don't mean to hijack the thread (but I will anyway ;) ), but I wanted to point out that you are able to set the bargraph level function to Drag and set the Range Time Up/Down values to control how quickly the level changes. I only point this out because I used to hate using bargraph buttons to set volume, but doing this in conjunction with two levels has changed my mind. (Two levels = one level for display, and a second level for setting the volume)

    Jeff
  • viningvining Posts: 4,368
    Spire_Jeff wrote:
    (Two levels = one level for display, and a second level for setting the volume)
    I've always done it like this. You can't really do it any other way.
    Drag and set the Range Time Up/Down values
    Do you mean you have to drag the volume and simply pushing the bar graph at the top will not send the level to the top? If so, that I didn't know and haven't tried.
  • Thanks for all the tips... the SLONG worked:
    DEFINE_VARIABLE
    
    PERSISTENT INTEGER nCURRENT_ZONE
    [b]
    PERSISTENT SLONG nAPVOL [18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    [/b]
    PERSISTENT INTEGER nLEV	[18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}		
    
    CHAR sBUFFER [100]
    CHAR sREPLY [100]
    
    CHAR	sTMP10	[30]
    CHAR	sTMP20	[30]
    
    VOLATILE nLENGTH
    [b]
    PERSISTENT SLONG nVOLUME
    [/b]
    DATA_EVENT[dvSWTCH]
    {
    STRING: 
        WHILE (FIND_STRING(DATA.TEXT,"13",1)) 
    	{ 
    	sREPLY = "sBUFFER, REMOVE_STRING (DATA.TEXT,"13",1)"
    	CLEAR_BUFFER sBUFFER
    	IF (FIND_STRING(sREPLY,"'('",1)) 
    	    {
    	    REMOVE_STRING (sREPLY,"'( '",  1)
    	    nLENGTH = LENGTH_STRING (sREPLY)
    	    sTMP10 = sREPLY
    	    sTMP20 = LEFT_STRING (sTMP10, (nLENGTH-3))
    	    nVolume = ATOL (sTMP20)
                nAPVOL [nCURRENT_ZONE] = nVolume
    	    nLEV [nCURRENT_ZONE]= ((ATOI(sTMP20)+ 700)/8)  
    	    SEND_LEVEL dvTP1, 1, ( nLEV [nCURRENT_ZONE])
    	    nCURRENT_VOLUMES [nCURRENT_ZONE] = nLEV [nCURRENT_ZONE]
    	   }
           } 
        sBUFFER = "sBUFFER,DATA.TEXT"
    }
    

    Unfortunately, the Autopatch level doesn't update as quickly on my panel as does the Denon receiver level. On the Denon, it is virtually simultaneous. The Autopatch has an appreciable lag that only begins after I have sent either a series of volume up commands, or even a single 'VA'- absolute volume command.
  • AVOPHILE wrote:
    Unfortunately, the Autopatch level doesn't update as quickly on my panel as does the Denon receiver level. On the Denon, it is virtually simultaneous. The Autopatch has an appreciable lag that only begins after I have sent either a series of volume up commands, or even a single 'VA'- absolute volume command.

    Denon provides the volume level in the feedback for a volume ramp command. The Autopatch needs to be asked to get the volume level. So what I do for the Autopatch is increment the vol level during a ramp with code and then poll it for vol level after the ramp is over.
  • ericmedleyericmedley Posts: 4,177
    TonyAngelo wrote:
    Denon provides the volume level in the feedback for a volume ramp command. The Autopatch needs to be asked to get the volume level. So what I do for the Autopatch is increment the vol level during a ramp with code and then poll it for vol level after the ramp is over.

    In my program for this I do a vol level poll on the release of the volume up/down buttons. That way it happens right after they let go of the volume.
  • ericmedley wrote:
    In my program for this I do a vol level poll on the release of the volume up/down buttons. That way it happens right after they let go of the volume.

    Thats what I'm talking about. But if you want to update the level feedback during the ramp you need to do it manually.
  • viningvining Posts: 4,368
    If you send the auto patch absolute volume levels it will automatically send you an echo of the command with the absolute volume value it just set if the take is successful. So it's easier to forget about sending incrementing or decrementing commands and then querying it and just do the math in code and send it an absolute value.
  • Joe HebertJoe Hebert Posts: 2,159
    AVOPHILE wrote:
    Although nVOLUME appears as the expected Autopatch level of -700 to +100 in debug, when I store the nVolume variable in the nAPVOL array, it goes from the expected values to values up in the 60,000's.

    Does anyone have an idea why this is happening?
    AVOPHILE wrote:
    Thanks for all the tips... the SLONG worked:
    Just for future reference sake, there was nothing wrong with your code when you used the SINTEGER[] array. The SLONG[] was certainly a good suggestion/workaround to get the values to display properly but I believe the root of the problem is a buggy debugger and not an internal Netlinx error.

    The following code should illustrate both points. If you want to play along, load the program and drop the variables in the watch window. Try changing the values of the variables and you?ll see there is no way to get a negative sign to display in the SINTEGER[] array. You?ll also see when you push button 1 the values will report back correctly with the expected values, it?s just the debugger having a bit of a brain fart.
    DEFINE_DEVICE
    
    dvTP			= 10001:1:0
    
    DEFINE_VARIABLE
    
    INTEGER  nZone 	= 1
    SINTEGER snVolume 	= -700
    
    SINTEGER snVolumes[]	= {0,0,0,0}
    
    DEFINE_EVENT
    
    BUTTON_EVENT[dvTP,1] {
    
       PUSH: {
          SEND_STRING 0, "'snVolume = ',ITOA(snVolume)"
          SEND_STRING 0, "'snVolumes[nZone] = ',ITOA(snVolumes[nZone])"
       }
    
    }
    
    DEFINE_PROGRAM
    
    snVolumes[nZone] = snVolume
    
    Here is the output when you push button 1 after the program boots:
    Line 1 :: snVolume = -700 - 05:37:41
    Line 2 :: snVolumes[nZone] = -700 - 05:37:41

    Even though the debugger shows 64836 in the SINTEGER[] array.


    The debugger (watch window) will display an SINTEGER correctly but it won?t display an SINTEGER in an SINTEGER[] array, instead it displays it as an INTEGER.

    I assume when you watched the SINTEGER value in your program go from -700 thru -1 in the in the debugger you saw 64836 thru 65535 displayed in the SINTEGER[] array. The first clue that something is wrong is that SINTEGERs only range from -32K thru +32K however the debugger displays values thru 64K in the SINTEGER[] array. Reason being is because the debugger isn?t treating the sign bit as a sign bit in a signed integer array. Or at least that?s what it looks like.
  • a_riot42a_riot42 Posts: 1,624
    vining wrote:
    Here's the conversion that Dave posted a while back.
    Autopatch to level:                                   
    where db = Autopatch volume, nVol = level value       
                                                          
    (db + 70) * 1.25 = nVol for a level scale of 0-100.   
    (db + 70) * 3.1875 = nVol for a level scale of 0-255. 
                                                          
    Level to Autopatch:                                   
                                                          
    (nVol / 1.25) - 70 = db for level scale 0-100         
    (nVol / 3.1875) - 70 = db for level scale 0-255       
    


    I am late to this thread but I am not following why you're doing this crazy math business with the volume level. Why do you need to mathematically scale from 0-100 to 0-255 and back again?

    The bargraph has 255 levels but the volume level the user sees is between 0-100%. You can set the range in the bargraph to 255 so no mathematical conversion is ever required. If you use $P% as your text then the volume gets updated to the correct percentage. I am controlling a Precis/dsp this way right now and it works great. I send the volume level to the panel with no converting and it shows up in the correct precentage.
    Paul
  • viningvining Posts: 4,368
    a_riot42 wrote:
    Why do you need to mathematically scale from 0-100 to 0-255 and back again?
    You don't! That's for converting the AP scale of -70 - +10 (if memory serves me) to either a 0-100 bargraph scale or a 0-255 bargraph scale.
  • a_riot42a_riot42 Posts: 1,624
    vining wrote:
    a_riot42 wrote:

    You don't! That's for converting the AP scale of -70 - +10 (if memory serves me) to either a 0-100 bargraph scale or a 0-255 bargraph scale.

    Oh, you aren't using the module. My mistake, I wasn't looking close enough. I am using the module so I get 0-255 not the -70-+10 range.
    Paul
  • trobertstroberts Posts: 228
    Few questions

    Just wondering when you all have an A/V receiver in a room getting fed from an autopatch switcher...do you set the volume on the autopatch to an "absolute volume"? When/if you do, does the switcher ever loose that setting and when do you send that string to and absolute volume (online event, every time room is turned on, etc)?

    Can someone tell me what the default baud rate is on a Precis switcher?

    I thought the BCS protocol would have been improved when AMX took autopatch over, but I don't see any protocol improvements. :(
  • John NagyJohn Nagy Posts: 1,734
    We set any multiroom preamp to 100% when feeding an AVR or other external volume control device, so the MR is only selecting sources. This is part of the room on routines, that manage setting whatever the volume should be for the room in question. Room off routines set the MR volume to 0.

    As all the documentation says, 9600 baud.

    And what "improvements" on BCS did you have in mind? The protocol is simple, obvious, and complete - which one of those would you change?
  • trobertstroberts Posts: 228
    [QUOTE=
    As all the documentation says, 9600 baud.
    [/QUOTE]

    Thanks for the reply on this old thread. Maybe I am not looking at the correct protocol doc, but I don't see baud rate mentioned anywhere, I am looking at:
    Instruction Manual - BCS Basic Control Structure Protocol (from product page on AMX's website)
    and
    Quick Start Guide - BCS Basic Control Structure Protocol (from product page on AMX's website)

    Regarding improvements (only because you asked)
    1) a way to fix the volume on any given output, without fear it will loose its set volume output
    2) volume on a scale from 0 - 255 (really anything other than negative asci numbers)
    3) Ability to set a max and min volume
    4) Unsolicited response when ramping volume up and down
    5) ability to save an initial turn on volume
    (I realize all my issues with autopatch can be worked around through programming, but I should not have to...I guess that is my point. Autopatch being that it is AMX should be the easiest switcher to work with via the protocol and in my opinion it is not)
  • John NagyJohn Nagy Posts: 1,734
    I see, it isn't mostly the BCS protocol you want changed, it is device features you want added.

    Some of the features you suggest have caused confounding issues when encountered in other devices - things to trip over or conflict with what you really want programmatic control of, things to turn off to get out of the way.
Sign In or Register to comment.