Código Delphi
[-]uses Windows, Messages, MMSystem, Types;
var
Buffer: array [0..31] of Byte;
hWnd, hCanvas, hBrush, hWhite, hGray: Cardinal;
WaveInHdr: TWaveHdr = (lpData: @Buffer; dwBufferLength: SizeOf(Buffer));
function WndProc(hWnd, Msg, wParam, lParam: Integer): Integer; stdcall;
var PaintStruct: TPaintStruct;
begin
Result := 0;
case Msg of
WM_ERASEBKGND: Result := 1;
WM_PAINT: begin
BeginPaint(hWnd, PaintStruct);
BitBlt(PaintStruct.hdc, 0, 0, SizeOf(Buffer) * 3, $FF, hCanvas, 0, 0, SRCCOPY);
EndPaint(hWnd, PaintStruct);
end;
WM_DESTROY: PostQuitMessage(0);
else
Result := DefWindowProc(hWnd, Msg, wParam, lParam);
end
end;
procedure waveInProc(waveIn, uMsg, dwInstance, lParam, wParam: Cardinal); stdcall;
begin
if uMsg = WIM_DATA then
begin
waveInAddBuffer(waveIn, PWaveHdr(lParam), SizeOf(TWaveHdr));
FillRect(hCanvas, Rect(0, 0, SizeOf(Buffer) * 3, $FF), hBrush);
SelectObject(hCanvas, hGray);
waveIn := SizeOf(Buffer);
repeat Dec(waveIn);
if Abs(Buffer[waveIn] - 128) = 1 then Buffer[waveIn] := 128;
MoveToEx(hCanvas, waveIn * 3, 0, nil);
LineTo(hCanvas, waveIn * 3, $FF);
until waveIn = 0;
SelectObject(hCanvas, hWhite);
waveIn := High(Buffer);
MoveToEx(hCanvas, waveIn * 3, Buffer[waveIn], nil);
repeat Dec(waveIn);
LineTo(hCanvas, waveIn * 3, Buffer[waveIn]);
until waveIn = 0;
repeat
if Abs(Buffer[waveIn] - 128) > 1 then
begin
MoveToEx(hCanvas, waveIn * 3, 128, nil);
LineTo(hCanvas, waveIn * 3, Buffer[waveIn]);
end;
Inc(waveIn);
until waveIn = SizeOf(Buffer);
InvalidateRect(hWnd, nil, True);
end;
end;
var
hScreen, waveIn: Cardinal;
WndClass: TWndClass = (lpfnWndProc: @WndProc; cbWndExtra: 4; lpszClassName: 'Waves');
Rect: TRect;
Value: Cardinal = 0;
Controls: array [0..1] of TMixerControl;
MixerLine: TMixerLine = (cbStruct: SizeOf(TMixerLine); dwDestination: 1; dwComponentType: MIXERLINE_COMPONENTTYPE_DST_WAVEIN);
LineControls: tMixerLineControls = (cbStruct: SizeOf(TMixerLineControls); dwControlType: MIXERCONTROL_CONTROLTYPE_VOLUME; cbmxctrl: SizeOf(TMixerControl); pamxctrl: @Controls);
Details: TMixerControlDetails = (cbStruct: SizeOf(TMixerControlDetails); cChannels: 1; cbDetails: SizeOf(Value); paDetails: @Value);
FormatEx: TWaveFormatEx = (wFormatTag: WAVE_FORMAT_PCM; nChannels: 2; nSamplesPerSec: 100; nAvgBytesPerSec: 100; nBlockAlign: 1; wBitsPerSample: 8);
Msg: TMsg;
begin
hScreen := GetDC(0);
hCanvas := CreateCompatibleDC(0);
SelectObject(hCanvas, CreateCompatibleBitmap(hScreen, SizeOf(Buffer) * 3, $FF));
hWhite := CreatePen(PS_SOLID, 1, $FFFFFF);
hGray := CreatePen(PS_SOLID, 1, $404040);
ReleaseDC(0, hScreen);
WndClass.hCursor := CreateCursor(HInstance, 5, 5, 9, 9, PChar(#255#255#255#255#255#255#255#255#247#255#255#255#255#255#255#255#255#255), PChar(#8#8#8#8#8#8#28#28#255#128#28#8#8#8#8#8#8#0));
RegisterClass(WndClass);
hBrush := CreateSolidBrush(0);
hWnd := CreateWindowEx(WS_EX_TOOLWINDOW + WS_EX_LAYERED, WndClass.lpszClassName, WndClass.lpszClassName, WS_VISIBLE, 0, 0, 0, $FF, 0, 0, hInstance, nil);
GetClientRect(hWnd, Rect);
SetWindowPos(hWnd, HWND_TOPMOST, 6, 6, SizeOf(Buffer) * 3 + 4, $FF + ($FF - Rect.Bottom), 0);
SetLayeredWindowAttributes(hWnd, 0, 224, LWA_ALPHA);
mixerOpen(@waveIn, 0, 0, 0, MIXER_OBJECTF_WAVEIN);
mixerGetLineInfo(waveIn, @MixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE);
LineControls.dwLineID := MixerLine.dwLineID;
LineControls.cControls := MixerLine.cControls;
mixerGetLineControls(waveIn, @LineControls, MIXER_GETLINECONTROLSF_ALL);
Details.dwControlID := Controls[0].dwControlID;
Value := Byte(Controls[0].dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME) * $FFFF;
MixerSetControlDetails(waveIn, @Details, MIXER_SETCONTROLDETAILSF_VALUE);
Details.dwControlID := Controls[1].dwControlID;
Value := Byte(Controls[1].dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME) * $FFFF;
MixerSetControlDetails(waveIn, @Details, MIXER_SETCONTROLDETAILSF_VALUE);
mixerClose(waveIn);
waveInOpen(@waveIn, WAVE_MAPPER, @FormatEx, Cardinal(@WaveInProc), HInstance, CALLBACK_FUNCTION);
waveInPrepareHeader(waveIn, @WaveInHdr, SizeOf(WaveInHdr));
waveInAddBuffer(waveIn, @WaveInHdr, SizeOf(WaveInHdr));
waveInStart(waveIn);
repeat GetMessage(Msg, 0, 0, 0);
DispatchMessage(Msg);
until Msg.message = WM_QUIT;
end.
Esta es una pequeña prueba que creé hace algún tiempo, es un osciloscopio (scope ~ oscilloscope), de la salida de sonido. No funciona adecuadamente en algunos ordenadores pero en la mayoría si. Tampoco esta "afinada" pero cuanto tenga más tiempo libre lo haré!
Nota; El
Stereo Mix NO debe estar en silencio. Les adjunto la fuente compilada para que lo prueben en caso de no poder compilarlo.
PD; Espero ésto deje de ser un monologo
Saludos