对数-线性值转换

roejwanj  于 2022-10-16  发布在  其他
关注(0)|答案(1)|浏览(237)

下面的代码使用DrawGrid()绘制对数网格。看起来垂直线还行。当我使用函数SetPositionHzValue()时,结果位置似乎可以(它使用与DrawGrid()相同的逻辑,并且似乎与网格匹配)。但是如何将这个使用线性显示宽度的0-1.0归一化值转换为实际的Hz值呢?为什么GetPositionsHzValue()函数是错误的?
更复杂的是,显示器具有起始频率(在本例中为20赫兹)和结束频率(在本例中为44100赫兹)。

procedure TAudioBezierCurves.DrawGrid(Bitmap32: TBitmap32);
var
    GridPosition: Integer;
    GridPositionF: Double;
    i: Integer;
    Base: Double;
    LogOffsetValue: Double;
    LogMaxValue: Double;
begin
    GridPosition := 0;
    Base := 1;
    if GridFrequencyMin = 0 then begin
        LogOffsetValue := 0;
    end else begin
        LogOffsetValue := Log10(GridFrequencyMin);
    end;
    LogMaxValue := Log10(GridFrequencyMax) - LogOffsetValue;
    repeat
        for i := 2 to 10 do begin
            if Base * i < GridFrequencyMin then begin
                Continue;
            end;
            //* This gives the % value relative to the total scale
            GridPositionF := (Log10(Base  * i) - LogOffsetValue) / LogMaxValue; 
            GridPositionF := GridPositionF * Bitmap32.Width;
            GridPosition := Trunc(GridPositionF);
            Bitmap32.VertLineS(GridPosition, 0, Bitmap32.Height - 1, GridColor);
        end;
        Base := Base * 10;
    until GridPosition > Bitmap32.Width;
end;

procedure TAudioBezierCurve.SetPositionHzValue(AValue: Double);
var
    LogOffsetValue: Double;
    LogMaxValue: Double;
begin
    if AValue = 0 then begin
        Self.Position := 0;
    end else begin
        if Parent.GridFrequencyMin = 0 then begin
            LogOffsetValue := 0;
        end else begin
            LogOffsetValue := Log10(Parent.GridFrequencyMin);
        end;
        LogMaxValue := Log10(Parent.GridFrequencyMax) - LogOffsetValue;
        //* This gives the % value relative to the total scale
        AValue := (Log10(AValue) - LogOffsetValue) / LogMaxValue;
        Self.Position := AValue;
    end;
end;

function TAudioBezierCurve.GetPositionsHzValue: Double;
var
    AValue: Double;
begin
    AValue := Power(AValue, 2);
    Result := AValue * (Parent.GridFrequencyMax);
    Result := Result - (AValue * Parent.GridFrequencyMin) + Parent.GridFrequencyMin;
end;
guykilcj

guykilcj1#

在函数GetPositionsHzValue中,行“AValue:=Power(AValue,2);”“AValue”的值来自哪里?
也许您应该像您在“SetPositionHzValue(AValue:Double);”中所做的那样。AValue应为参数,而不是局部变量。

相关问题