Converting between MIDI channel volume and real gain - formula

What is the recommended way of mapping MIDI channel volume to gain?
From here [1]
It is recommended that a device use the volume value in a logarithmic manner, as specified by the following formula if only the coarse value is used:
40 log (Volume/127)
To me, this formula looks like an inverse formula. If channel volume is given in dB, then the formula should use exp instead of log. If volume already is an amplitude, then there should only be Volume/127. To clarify, this does not make sense
*output_buffer = 40*log(channel_volume/127.0) * (*input_buffer);
(Testcase: channel_volume=0 will give infinite gain) The following on the other hand is better (provided that channel_volume is the real gain and not the gain in dB):
*output_buffer = channel_volume * (*input_buffer)/127.0;
[1] http://www.blitter.com/~russtopia/MIDI/~jglatt/tech/midispec/vol.htm

The MIDI specification itself does not specify the volume response.
However, the General MIDI Level 1 Developer Guidelines show this formula, because it's actually used by most implementations.
The channel volume is given as a value from 0 to 127.
The result of that formula is measured in dB; you have to convert it into a gain value afterwards:
gain = 10 ^ (dB / 20)
See the same document for how to handle interactions with the expression controller.

Related

Calculate minimum QRcode version from input data

I started to study ISO/IEC 18004 - the "QRcode specification".
When encoding data as a QRcode (generating a QRcode), the following information must be specified:
Mode (what kind of data, eg numeric, alphanumeric, binary, ...)
Error correction level (L, M, Q or H)
Version (the "size" of the QRcode)
I am looking for a mathematical (equation) way of determining the version requires to hold the provided data with the specified mode and error correction level. The standard itself contains a look-up table which is also available from various web sources such as this or this (they are just look-up tables).
A quote from this very related SO answer:
Any formula for the data capacity will be necessarily awkward and unenlightening since many of the parameters that determine the structure of QR Code symbols have been manually chosen and therefore implementations must generally resort to including tables of constants for these non-computed values.
As per my current understanding of the standard, it should be possible to determine the data capacity (and therefore minimum version) required based on the input data, mode and ECC level. The answer even expressed the calculations for the maximum capacity:
DataModules = Rows × Columns − ( FinderModules + AlignmentModules + TimingPatternModules ) − ( FormatInformationModules + VersionInformationModules )
UsableDataBits = DataModules − ErrorCorrectionBits
I don't understand where the "awkwardness" that would lead to resorting to a look-up table originates from? As per my understanding sizes of timing pattern etc. are fixed per version.
Could somebody further explain this?
zxing provides an implementation for that:
https://github.com/zxing/zxing/blob/master/core/src/main/java/com/google/zxing/qrcode/encoder/Encoder.java
/**
* Decides the smallest version of QR code that will contain all of the
provided data.
*
* #throws WriterException if the data cannot fit in any version
*/
private static Version recommendVersion(ErrorCorrectionLevel ecLevel,
Mode mode,
BitArray headerBits,
BitArray dataBits)
The Encoder class provides the algorithm ("mathematical way") of determining the minimum version you are looking for.
If this implementation is in any kind "awkward" or not, I cannot answer.

Dymola: Initialization of District Heating Network Simluation model using Non-linear solver

I have been modelling and simulating a number of simple district heating networks in Dymola and am quite often faced with an error during initialisation.
The system we are simulating consists of
A producer: two pressure boundaries - source and sink. Pressure at source is controlled via PI which ensures that the source pressure is such that the minimum differential pressure accross a consumer is greater than or equal to some set value.
Consumers: They have a PI controlled valve and a heat exchanger with a fixed return temp. Valve controls mass flow and subsequently the heat flow to match the consumer load at any given time.
Pipes: dynamic thermo-hydraulic model with heat loss and and Spatialdistribution to account for delay. Vectorised ports and mixing volumes used to reduce non linear equations.
The figure below is a heavily simplified version of the network (same error occuring here)
The consumer model looks as follows:
And the producer:
During initialisation, the following error occurs:
ERROR: Failed to solve non-linear system using Newton solver.
To get more information: Turn on Simulation/Setup/Debug/Nonlinear solver diagnostics/Details
Solution to systems of equations not found at time = 0
Nonlinear system of equations number = 3
Infinity-norm of residue = 118280
Iteration is not making good progress.
Accumulated number of residue calc.: 389
Accumulated number of symbolic Jacobian calc.: 5
Last values of solution vector:
L.PI.gainPID.y = 0
Last values of residual vector:
{ -118280 }
Trying to solve non-linear system using global homotopy-method.
... loading "data" from "C:/Users/Sim1/Desktop/Keith Dymola Files/GrazReininghaus_UseCase/PythonScriptsforTranslation/Reininghaus.txt"
ERROR: Failed to solve non-linear system using Newton solver.
To get more information: Turn on Simulation/Setup/Debug/Nonlinear solver diagnostics/Details
Solution to systems of equations not found at time = 0
Nonlinear system of equations number = 1
Infinity-norm of residue = 2.22814E+018
Iteration is not making good progress.
Accumulated number of residue calc.: 101
Accumulated number of symbolic Jacobian calc.: 9
Last values of solution vector:
M.port_a.m_flow = 0.000485868
N.valveLinear.dp = -55.8243
O.valveLinear.dp = -135.618
P.valveLinear.dp = 550.474
I.port_a.m_flow = 3.20321E-010
C.port_a.m_flow = 2.19343E-011
D.port_a.m_flow = 0.00208272
E.valveLinear.dp = 371.552
L.port_a.m_flow = -7.10982E-012
J.valveLinear.dp = 243.085
K.port_a.m_flow = 1.924E-005
Last values of residual vector:
{ 6.60393E+013, -1.14781E+018, -1.05438E+018, -2.58754E+016, -111988,
-1.56817E+010, 16024.9, 3.14411E+007, 3.99781E+008, 3.14412E+007,
-15012.9 }
Error: could not solve simplified initialization for homotopy method.
Error: could not solve simplified initialization for homotopy method.
FixInitials:Init
The components A,B,C e.t.c are the consumers in the network. I am using the Radau IIa 5th order solver with tol=1e-06. The PI controller in the consumer valves inittype is to integrate only with integrtor state and the PI in the producer is initialised with an output value.
I have tried playing around with all sorts of nominal values for mass flows and pressure drops in the network, a well as initial values in the PI controllerrs but the same form ERROR is always returned. The model passes the error check but always fails at initialisation.
I would like to know if anybody has had experience in debugging such nonlinear systems, and if so, a few tips in how to initialise these models would be a great help with the debugging process.
Ok so for anybody who is interested, I managed to simulate my network in the end. It turns out the initialisation problem was arising in the "first order" block within the consumer which takes the measured heat flow signal in the heat exchanger and passes it to the PI. The default init type for this component was "noinit", however by changing it to take in an initial guess value (nominal consumer load worked in this case), the initialisation sections passed. I guess this problem occured in this example as my consumer nominal loads were quite a bit higher than in previous examples and therefore the initial value was outside of the suitable range without specifying it manually.

Why does lsoda (in R) fail to complete running duration, with warning messages?

I am writing a numerical model in R, for an ecological system, and solving it using "lsoda" from package deSolve.
My model has 14 state variables.
I define the model, set it up fine, and give time duration according to this:
nyears<-60
ndays<-nyears*365+1
times<-seq(0,nyears*365,by=1)
Rates of change of state variables (e.g. the rate of change of variable "A1" is "dA1")are calculated according to existing values for state variables (at time=t) and a set of parameters.
Simplified example:
dA1<-Tf*A1*(ImaxA*p_sub)
Where Tf, ImaxA and p_sub are parameters, and A1 is my state variable at time=t.
When I solve the model, I use the lsoda solver like this:
out<-as.data.frame(lsoda(start,times,model,parms))
Sometimes (depending on my parameter combinations), the model run completes over the entire duration I have specified, however sometimes it stops short of the mark (still giving me output up until the solver "crashes"). When it "crashes", this message is displayed:
DLSODA- At current T (=R1), MXSTEP (=I1) steps
taken on this call before reaching TOUT
In above message, I1 = 5000
In above message, R1 = 11535.5
Warning messages:
1: In lsoda(start, times, model, parms) :
an excessive amount of work (> maxsteps ) was done, but integration was not successful - increase maxsteps
2: In lsoda(start, times, model, parms) :
Returning early. Results are accurate, as far as they go
It commonly appears when one of the state variables is getting exponentially bigger, or is tending very near to zero, however sometimes it crashes when seemingly not much change is happening. I may be wrong, but is it due to the rate of change of state-variables becoming too large? If so, why might it also "crash" when there is not a fast rate of change?
Is there a way that I can make the solver complete its task with the specified parameter values, maybe with a more relaxed tolerance for error?
Thank you all for your contributions. I looked at some of the rates, and at the point of crashing, the model was switching between two metabolic states - and the fast rate of this binary switch caused the solver to stop - rejecting the solution because the rate of change was too large. I have fixed my model by introducing a gradual switch between states (with a logistic curve) instead of this binary switch. I aknowledge that I didn;t give enough info in the original question, so thanks for the help you offered!

Trouble implementing a very simple mass flow source

I am currently learning Modelica by trying some very simple examples. I have defined a connector Incompressible for an incompressible fluid like this:
connector Incompressible
flow Modelica.SIunits.VolumeFlowRate V_dot;
Modelica.SIunits.SpecificEnthalpy h;
Modelica.SIunits.Pressure p;
end Incompressible;
I now wish to define a mass or volume flow source:
model Source_incompressible
parameter Modelica.SIunits.VolumeFlowRate V_dot;
parameter Modelica.SIunits.Temperature T;
parameter Modelica.SIunits.Pressure p;
Incompressible outlet;
equation
outlet.V_dot = V_dot;
outlet.h = enthalpyWaterIncompressible(T); // quick'n'dirty enthalpy function
outlet.p = p;
end Source_incompressible;
However, when checking Source_incompressible, I get this:
The problem is structurally singular for the element type Real.
The number of scalar Real unknown elements are 3.
The number of scalar Real equation elements are 4.
I am at a loss here. Clearly, there are three equations in the model - where does the fourth equation come from?
Thanks a lot for any insight.
Dominic,
There are a couple of issues going on here. As Martin points out, the connector is unbalanced (you don't have matching "through" and "across" pairs in that connector). For fluid systems, this is acceptable. However, intensive fluid properties (e.g., enthalpy) have to be marked as so-called "stream" variables.
This topic is, admittedly, pretty complicated. I'm planning on adding an advanced chapter to my online Modelica book on this topic but I haven't had the time yet. In the meantime, I would suggest you have a look at the Modelica.Fluid library and/or this presentation by one of its authors, Francesco Casella.
That connector is not a physical connector. You need one flow variable for each potential variable. This is the OpenModelica error message if it helps a little:
Warning: Connector .Incompressible is not balanced: The number of potential variables (2) is not equal to the number of flow variables (1).
Error: Too many equations, over-determined system. The model has 4 equation(s) and 3 variable(s).
Error: Internal error Found Equation without time dependent variables outlet.V_dot = V_dot
This is because the unconnected connector will generate one equation for the flow:
outlet.V_dot = 0.0;
This means outlet.V_dot is replaced in:
outlet.V_dot = V_dot;
And you get:
0.0 = V_dot;
But V_dot is a parameter and can not be assigned to in an equation section (needs an initial equation if the parameter has fixed=false, or a binding equation in the default case).

RChannel Sensitivity in DICOM waveforms

I am trying to make an ECG viewer reading DICOM files.
I get all data (like Channel Definition Seqeunce), also got the waveform samples to each channel. My problem is that there is a Tag (Channel Sensitivity), and I can't figure out it's meaning.
What purpose does it have?
After you have the raw value for a sample you have to apply some transformations defined by several tags.
Channel Sensitivity is a mandatory field when samples represent defined units and it must be used in conjunction with Channel Sensitivity Correction Factor, Channel Baseline and Channel Sensitivity Units. It represents numeric value of unit quantity of sample.
What does it means? Suppose you did read the sample, you added the bias of Channel Baseline and applied the correction factor of Channel Sensitivity Correction Factor.
Now that value matches Channel Sensitivity with the unit of Channel Sensitivity Units. For example suppose you acquired a constant 5 mV signal, you may set Sensitivity to 5 mV, write to disk the value 1 for each sample and use a Channel Sensitivity Correction Factor of 5. After decoding you'll have back 5 mV. You do not need to consider this (but you have to consider its unit) if you'll display the signal with the same sensitivity.
For your reference: http://dicomlookup.com/html/03_03PU.html#LinkTarget_229394

Resources