📄 soundviewer.aspx.htm
字号:
_isTest = isTest;
}
<span class="code-SummaryComment">///</span><span class="code-comment"> <span class="code-SummaryComment"><</span><span class="code-SummaryComment">summary</span><span class="code-SummaryComment">></span>
</span>
<span class="code-SummaryComment">///</span><span class="code-comment"> Process 16 bit sample
</span>
<span class="code-SummaryComment">///</span><span class="code-comment"> <span class="code-SummaryComment"><</span><span class="code-SummaryComment">/</span><span class="code-SummaryComment">summary</span><span class="code-SummaryComment">></span>
</span>
<span class="code-SummaryComment">///</span><span class="code-comment"> <span class="code-SummaryComment"><</span><span class="code-SummaryComment">param</span> <span class="code-SummaryComment">name="wave"</span><span class="code-SummaryComment">></span><span class="code-SummaryComment"><</span><span class="code-SummaryComment">/</span><span class="code-SummaryComment">param</span><span class="code-SummaryComment">></span>
</span>
<span class="code-keyword">public</span> <span class="code-keyword">void</span> Process(<span class="code-keyword">ref</span> <span class="code-keyword">byte</span>[] wave)
{
_waveLeft = <span class="code-keyword">new</span> <span class="code-keyword">double</span>[wave.Length / <span class="code-digit">4</span>];
_waveRight = <span class="code-keyword">new</span> <span class="code-keyword">double</span>[wave.Length / <span class="code-digit">4</span>];
<span class="code-keyword">if</span> (_isTest == <span class="code-keyword">false</span>)
{
<span class="code-comment">//</span><span class="code-comment"> Split out channels from sample
</span>
<span class="code-keyword">int</span> h = <span class="code-digit">0</span>;
<span class="code-keyword">for</span> (<span class="code-keyword">int</span> i = <span class="code-digit">0</span>; i < wave.Length; i += <span class="code-digit">4</span>)
{
_waveLeft[h] = (<span class="code-keyword">double</span>)BitConverter.ToInt16(wave, i);
_waveRight[h] = (<span class="code-keyword">double</span>)BitConverter.ToInt16(wave, i + <span class="code-digit">2</span>);
h++;
}
}
<span class="code-keyword">else</span>
{
<span class="code-comment">//</span><span class="code-comment"> Generate artificial sample for testing
</span>
_signalGenerator = <span class="code-keyword">new</span> SignalGenerator();
_signalGenerator.SetWaveform(<span class="code-string">"</span><span class="code-string">Sine"</span>);
_signalGenerator.SetSamplingRate(<span class="code-digit">44100</span>);
_signalGenerator.SetSamples(<span class="code-digit">16384</span>);
_signalGenerator.SetFrequency(<span class="code-digit">5000</span>);
_signalGenerator.SetAmplitude(<span class="code-digit">32768</span>);
_waveLeft = _signalGenerator.GenerateSignal();
_waveRight = _signalGenerator.GenerateSignal();
}
<span class="code-comment">//</span><span class="code-comment"> Generate frequency domain data in decibels
</span>
_fftLeft = FourierTransform.FFTDb(<span class="code-keyword">ref</span> _waveLeft);
_fftRight = FourierTransform.FFTDb(<span class="code-keyword">ref</span> _waveRight);
}
<span class="code-SummaryComment">///</span><span class="code-comment"> <span class="code-SummaryComment"><</span><span class="code-SummaryComment">summary</span><span class="code-SummaryComment">></span>
</span>
<span class="code-SummaryComment">///</span><span class="code-comment"> Render time domain to PictureBox
</span>
<span class="code-SummaryComment">///</span><span class="code-comment"> <span class="code-SummaryComment"><</span><span class="code-SummaryComment">/</span><span class="code-SummaryComment">summary</span><span class="code-SummaryComment">></span>
</span>
<span class="code-SummaryComment">///</span><span class="code-comment"> <span class="code-SummaryComment"><</span><span class="code-SummaryComment">param</span> <span class="code-SummaryComment">name="pictureBox"</span><span class="code-SummaryComment">></span><span class="code-SummaryComment"><</span><span class="code-SummaryComment">/</span><span class="code-SummaryComment">param</span><span class="code-SummaryComment">></span>
</span>
<span class="code-keyword">public</span> <span class="code-keyword">void</span> RenderTimeDomain(<span class="code-keyword">ref</span> PictureBox pictureBox)
{
<span class="code-comment">//</span><span class="code-comment"> Set up for drawing
</span>
_canvasTimeDomain = <span class="code-keyword">new</span> Bitmap(pictureBox.Width, pictureBox.Height);
Graphics offScreenDC = Graphics.FromImage(_canvasTimeDomain);
SolidBrush brush = <span class="code-keyword">new</span> System.Drawing.SolidBrush
(Color.FromArgb(<span class="code-digit">0</span>, <span class="code-digit">0</span>, <span class="code-digit">0</span>));
Pen pen = <span class="code-keyword">new</span> System.Drawing.Pen(Color.WhiteSmoke);
<span class="code-comment">//</span><span class="code-comment"> Determine channel boundaries
</span>
<span class="code-keyword">int</span> width = _canvasTimeDomain.Width;
<span class="code-keyword">int</span> center = _canvasTimeDomain.Height / <span class="code-digit">2</span>;
<span class="code-keyword">int</span> height = _canvasTimeDomain.Height;
offScreenDC.DrawLine(pen, <span class="code-digit">0</span>, center, width, center);
<span class="code-keyword">int</span> leftLeft = <span class="code-digit">0</span>;
<span class="code-keyword">int</span> leftTop = <span class="code-digit">0</span>;
<span class="code-keyword">int</span> leftRight = width;
<span class="code-keyword">int</span> leftBottom = center - <span class="code-digit">1</span>;
<span class="code-keyword">int</span> rightLeft = <span class="code-digit">0</span>;
<span class="code-keyword">int</span> rightTop = center + <span class="code-digit">1</span>;
<span class="code-keyword">int</span> rightRight = width;
<span class="code-keyword">int</span> rightBottom = height;
<span class="code-comment">//</span><span class="code-comment"> Draw left channel
</span>
<span class="code-keyword">double</span> yCenterLeft = (leftBottom - leftTop) / <span class="code-digit">2</span>;
<span class="code-keyword">double</span> yScaleLeft = <span class="code-digit">0</span>.<span class="code-digit">5</span> * (leftBottom - leftTop) / <span class="code-digit">32768</span>;
<span class="code-comment">//</span><span class="code-comment"> a 16 bit sample has values from -32768 to 32767
</span>
<span class="code-keyword">int</span> xPrevLeft = <span class="code-digit">0</span>, yPrevLeft = <span class="code-digit">0</span>;
<span class="code-keyword">for</span> (<span class="code-keyword">int</span> xAxis = leftLeft; xAxis < leftRight; xAxis++)
{
<span class="code-keyword">int</span> yAxis = (<span class="code-keyword">int</span>)(yCenterLeft + (_waveLeft[_waveLeft.Length /
(leftRight - leftLeft) * xAxis] * yScaleLeft));
<span class="code-keyword">if</span> (xAxis == <span class="code-digit">0</span>)
{
xPrevLeft = <span class="code-digit">0</span>;
yPrevLeft = yAxis;
}
<span class="code-keyword">else</span>
{
pen.Color = Color.LimeGreen;
offScreenDC.DrawLine(pen, xPrevLeft, yPrevLeft, xAxis,yAxis);
xPrevLeft = xAxis;
yPrevLeft = yAxis;
}
}
<span class="code-comment">//</span><span class="code-comment"> Draw right channel
</span>
<span class="code-keyword">int</span> xCenterRight = rightTop + ((rightBottom - rightTop) / <span class="code-digit">2</span>);
<span class="code-keyword">double</span> yScaleRight = <span class="code-digit">0</span>.<span class="code-digit">5</span> * (rightBottom - rightTop) / <span class="code-digit">32768</span>;
<span class="code-comment">//</span><span class="code-comment"> a 16 bit sample has values from -32768 to 32767
</span>
<span class="code-keyword">int</span> xPrevRight = <span class="code-digit">0</span>, yPrevRight = <span class="code-digit">0</span>;
<span class="code-keyword">for</span> (<span class="code-keyword">int</span> xAxis = rightLeft; xAxis < rightRight; xAxis++)
{
<span class="code-keyword">int</span> yAxis = (<span class="code-keyword">int</span>)(xCenterRight + (_waveRight[_waveRight.Length /
(rightRight - rightLeft) * xAxis] * yScaleRight));
<span class="code-keyword">if</span> (xAxis == <span class="code-digit">0</span>)
{
xPrevRight = <span class="code-digit">0</span>;
yPrevRight = yAxis;
}
<span class="code-keyword">else</span>
{
pen.Color = Color.LimeGreen;
offScreenDC.DrawLine
(pen, xPrevRight, yPrevRight, xAxis, yAxis);
xPrevRight = xAxis;
yPrevRight = yAxis;
}
}
<span class="code-comment">//</span><span class="code-comment"> Clean up
</span>
pictureBox.Image = _canvasTimeDomain;
offScreenDC.Dispose();
}
<span class="code-SummaryComment">///</span><span class="code-comment"> <span class="code-SummaryComment"><</span><span class="code-SummaryComment">summary</span><span class="code-SummaryComment">></span>
</span>
<span class="code-SummaryComment">///</span><span class="code-comment"> Render frequency domain to PictureBox
</span>
<span class="code-SummaryComment">///</span><span class="code-comment"> <span class="code-SummaryComment"><</span><span class="code-SummaryComment">/</span><span class="code-SummaryComment">summary</span><span class="code-SummaryComment">></span>
</span>
<span class="code-SummaryComment">///</span><span class="code-comment"> <span class="code-SummaryComment"><</span><span class="code-SummaryComment">param</span> <span class="code-SummaryComment">name="pictureBox"</span><span class="code-SummaryComment">></span><span class="code-SummaryComment"><</span><span class="code-SummaryComment">/</span><span class="code-SummaryComment">param</span><span class="code-SummaryComment">></span>
</span>
<span class="code-keyword">public</span> <span class="code-keyword">void</span> RenderFrequencyDomain(<span class="code-keyword">ref</span> PictureBox pictureBox)
{
<span class="code-comment">//</span><span class="code-comment"> Set up for drawing
</span>
_canvasFrequencyDomain = <span class="code-keyword">new</span> Bitmap
(pictureBox.Width, pictureBox.Height);
Graphics offScreenDC = Graphics.FromImage(_canvasFrequencyDomain);
SolidBrush brush = <span class="code-keyword">new</span> System.Drawing.SolidBrush
(Color.FromArgb(<span class="code-digit">0</span>, <span class="code-digit">0</span>, <span class="code-digit">0</span>));
Pen pen = <span class="code-keyword">new</span> System.Drawing.Pen(Color.WhiteSmoke);
<span class="code-comment">//</span><span class="code-comment"> Determine channel boundaries
</span>
<span class="code-keyword">int</span> width = _canvasFrequencyDomain.Width;
<span class="code-keyword">int</span> center = _canvasFrequencyDomain.Height / <span class="code-digit">2</span>;
<span class="code-keyword">int</span> height = _canvasFrequencyDomain.Height;
offScreenDC.DrawLine(pen, <span class="code-digit">0</span>, center, width, center);
<span class="code-keyword">int</span> leftLeft = <span class="code-digit">0</span>;
<span class="code-keyword">int</span> leftTop = <span class="code-digit">0</span>;
<span class="code-keyword">int</span> leftRight = width;
<span class="code-keyword">int</span> leftBottom = center - <span class="code-digit">1</span>;
<span class="code-keyword">int</span> rightLeft = <span class="code-digit">0</span>;
<span class="code-keyword">int</span> rightTop = center + <span class="code-digit">1</span>;
<span class="code-keyword">int</span> rightRight = width;
<span class="code-keyword">int</span> rightBottom = height;
<span class="code-comment">//</span><span class="code-comment"> Draw left channel
</span>
<span class="code-keyword">for</span> (<span class="code-keyword">int</span> xAxis = leftLeft; xAxis < leftRight; xAxis++)
{
<span class="code-keyword">double</span> amplitude = (<span class="code-keyword">int</span>)_fftLeft[(<span class="code-keyword">int</span>)(((<span class="code-keyword">double</span>)(_fftLeft.Length)
/ (<span class="code-keyword">double</span>)(width)) * xAxis)];
<span class="code-keyword">if</span> (amplitude < <span class="code-digit">0</span>) <span class="code-comment">//</span><span class="code-comment"> Drop negative values
</span>
amplitude = <span class="code-digit">0</span>;
<span class="code-keyword">int</span> yAxis = (<span class="code-keyword">int</span>)(leftTop +
((leftBottom - leftTop) * amplitude) / <span class="code-digit">100</span>);
<span class="code-comment">//</span><span class="code-comment"> Arbitrary factor
</span>
pen.Color = Color.FromArgb(<span class="code-digit">0</span>, <span class="code-digit">0</span>, (<span class="code-keyword">int</span>)amplitude % <span class="code-digit">255</span>);
offScreenDC.DrawLine(pen, xAxis, leftTop, xAxis, yAxis);
}
<span class="code-comment">//</span><span class="code-comment"> Draw right channel
</span>
<span class="code-keyword">for</span> (<span class="code-keyword">int</span> xAxis = rightLeft; xAxis < rightRight; xAxis++)
{
<span class="code-keyword">double</span> amplitude = (<span class="code-keyword">int</span>)_fftRight[(<span class="code-keyword">int</span>)(((<span class="code-keyword">double</span>)
(_fftRight.Length) / (<span class="code-keyword">double</span>)(width)) * xAxis)];
<span class="code-keyword">if</span> (amplitude < <span class="code-digit">0</span>)
amplitude = <span class="code-digit">0</span>;
<span class="code-keyword">int</span> yAxis = (<span class="code-keyword">int</span>)(rightBottom -
((rightBottom - rightTop) * amplitude) / <span class="code-digit">100</span>);
pen.Color = Color.FromArgb(<span class="code-digit">0</span>, <span class="code-digit">0</span>, (<span class="code-keyword">int</span>)amplitude % <span class="code-digit">255</span>);
offScreenDC.DrawLine(pen, xAxis, rightBottom, xAxis, yAxis);
}
<span class="code-comment">//</span><span class="code-comment"> Clean up
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -