Свежие обсуждения
Измерения

LC-метр из звуковой карты

1 63 68

Михалыч А: Я делаю каждому из трех байтов NOT операцию (~) и всё, минус нужно ещё потом не забыть добавить.

Я знаю одного дядьку, который десятилетиями читая курсы по SIMATIC, был убежден, что "минус единица" в двоичном представлении -- это "10000001".

(PS. минусование -- это инвертирование и прибавление 1)

 

Кстати о частоте дискретизации - у себя заметил, что для правильной работы программ нужно устанавливать одинаковые частоты и в винде и в проге иначе появляются комбинационные частоты (не гармоники сигнала), это же слышно и в музыкальных проигрывателях

 

Значит, после калибровки на 24-х битах и 192 КГерцах у меня у smd резистора (корпус 0805) получаются реактивные составляющие 0.0х микроГенри или 0.х...0.0х пикоФарад. Я себя утешаю мыслью, что измерения правильно происходят.
Да, и когда я измеряю опорное сопротивление (в моей схеме оно используется при калибровке, а при измерении не используется), я не могу измерить его с точностью 0.1 Ом.

 

не могли бы вы выложить пример использования WAVEFORMATEXTENSIBLE для работы с 24 битами

 

Выложу, когда мне удобно будет. 24-битная карта у меня только в одном системном блоке (новом), а интернет в старом системном блоке, чтобы новый комп антивирусом и фаерволом не нагружать.

Но там же без комментариев мало что понятно будет, а всё сводится к заполнению WAVEFORMATEXTENSIBLE как майкрософт рекомендует, а при открытии устройства воспроизведения и записи структура WAVEFORMATEXTENSIBLE явно преобразовывается в WAVEFORMATEX. Если этого не делать - ничего не получается.

 

Ноу вас же получилось, может и у меня тоже получится, хотя я до сих пор не верю в реальные 24 бита, даже 20 бит сомнительно.

 

Вот на Дельфи могу дать пример кода для WAVEFORMATEXTENSIBLE

with FFormatExt.Format do begin
wFormatTag:= WAVE_FORMAT_EXTENSIBLE;
wBitsPerSample:= 24;
nChannels = 2;
nSamplesPerSec:= 48000;
nBlockAlign:= (wBitsPerSample div 8) * nChannels;
nAvgBytesPerSec:= nSamplesPerSec * nBlockAlign;
cbSize:= 22;
end;
FFormatExt.Samples.wValidBitsPerSample:= 24;
FFormatExt.ChannelMask:= 3;
FFormatExt.SubFormat:= KSDATAFORMAT_SUBTYPE_PCM;

Это для записи, причём FFormatExt.ChannelMask можно и 0 делать - ничего не меняет.
Для воспроизведения не проверял.

Шумит у меня больше чем 16 битное разрешение. На 24 битах шум получается более качественный, натуральный такой, дискретизации совсем не видать, только амплитуда у него остается такой же как и на 16 битах...

 

Для asmvvv1

#include <windows.h>
#include <mmsystem.h>
#include <Mmreg.h>
#include <Ks.h>
#include <KsMedia.h>

int size, WaitTime, ii ;
char msg[300];
DWORD WAITTIMEOUT;
WAVEFORMATEXTENSIBLE ExFmt;
HANDLE hEvent_play; // объект-событие для определения окончания воспроизведения звука
HANDLE hEvent_rec;
HWAVEOUT hPlay; // структура - описатель будущего открытого устройства воспроизведения
HWAVEIN hRec; // структура - описатель будущего открытого устройства записи
SYSTEM_INFO si;
WAVEHDR HeadPlay [1] ; // структура - описатель блока данных для вопроизведения
WAVEHDR HeadRec [1] ; // структура - описатель блока данных для записи
void WaveOutCheck (MMRESULT result);

void Play_24bit ( char* X, char* Y, UINT Fdiskre, int BlockSize)
{
UINT SampleRate = Fdiskre;
UINT BitsPerSample = 24;
UINT Channels = 2;
ii = 0;
int BytesPerSample = (BitsPerSample + 7) / 8;
ZeroMemory ( &ExFmt, sizeof (ExFmt) );
ExFmt.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
ExFmt.Format.nChannels = (WORD) Channels;
ExFmt.Format.wBitsPerSample = (WORD) BitsPerSample;
ExFmt.Format.nBlockAlign = (WORD) (Channels * BytesPerSample);
ExFmt.Format.nSamplesPerSec = SampleRate;
ExFmt.Format.nAvgBytesPerSec = ExFmt.Format.nSamplesPerSec * ExFmt.Format.nBlockAlign;
ExFmt.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
ExFmt.Samples.wValidBitsPerSample = 24;
//ExFmt.Samples.wEffects = 0;
ExFmt.dwChannelMask = SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT;
ExFmt.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
WaitTime = 2*BlockSize*9000/ExFmt.Format.nAvgBytesPerSec;
WAITTIMEOUT = 0;

hEvent_play = CreateEvent(0, FALSE , FALSE, 0);
hEvent_rec = CreateEvent(0, FALSE, FALSE, 0);
GetSystemInfo(&si);
ZeroMemory (HeadPlay, sizeof(HeadPlay));
ZeroMemory (HeadRec, sizeof(HeadRec));
WaveOutCheck (waveOutOpen(&hPlay, WAVE_MAPPER, (WAVEFORMATEX*) &ExFmt, (DWORD) hEvent_play, 0, CALLBACK_EVENT));
WaveOutCheck (waveInOpen(&hRec, WAVE_MAPPER, (WAVEFORMATEX*) &ExFmt, (DWORD) hEvent_rec, 0, CALLBACK_EVENT));

HeadPlay[0]. lpData = X;
HeadPlay[0].dwBufferLength = int (BlockSize*2);
HeadPlay[0].dwBytesRecorded = 0;
HeadPlay[0].dwUser = 0;
HeadPlay[0].dwFlags = 0;
HeadPlay[0].dwLoops = 0;
HeadPlay[0].lpNext = 0;
HeadPlay[0].reserved = 0;

HeadRec[0]. lpData = Y;
HeadRec[0].dwBufferLength = int (BlockSize*2);
HeadRec[0].dwBytesRecorded = 0;
HeadRec[0].dwUser = 0;
HeadRec[0].dwFlags = 0;
HeadRec[0].dwLoops = 0;
HeadRec[0].lpNext = 0;
HeadRec[0].reserved = 0;

WaveOutCheck (waveOutPrepareHeader(hPlay, HeadPlay, sizeof(WAVEHDR)));
WaveOutCheck (waveInPrepareHeader(hRec, HeadRec, sizeof(WAVEHDR)));
ResetEvent(hEvent_play);

WAVEHDR *curhdr = HeadPlay+((ii++)&1) ;
curhdr->dwBufferLength = (DWORD) BlockSize*2;
WaveOutCheck (waveInAddBuffer(hRec, HeadRec, sizeof(WAVEHDR)));
ResetEvent(hEvent_rec);
WaveOutCheck (waveOutWrite (hPlay, curhdr, sizeof(WAVEHDR)));
WaveOutCheck (waveInStart(hRec));
WAITTIMEOUT = WaitForSingleObject (hEvent_play, WaitTime);
//Sleep (100);
waveInReset(hRec);
waveOutReset (hPlay);
WaveOutCheck (waveOutUnprepareHeader (hPlay, HeadPlay, sizeof(WAVEHDR)));
WaveOutCheck (waveInUnprepareHeader (hRec, HeadRec, sizeof(WAVEHDR))) ;
waveOutClose(hPlay);
waveInClose(hRec);
CloseHandle(hEvent_rec);
CloseHandle(hEvent_play);
Sleep (100);
}
void WaveOutCheck (MMRESULT result) throw(char*)
{
switch (result)
{
case MMSYSERR_NOERROR:
return;
case MMSYSERR_ALLOCATED:
throw "Драйвер уже открыт";
case MMSYSERR_BADDEVICEID:
throw "Неверный идентификатор устройства";
case MMSYSERR_NODRIVER:
throw "Отсутствует драйвер устройства";
case MMSYSERR_NOMEM:
throw "Невозможно распределить или зафиксировать память";
case WAVERR_BADFORMAT:
throw "Неверный формат данных";
case WAVERR_SYNC:
throw "Попытка воспроизведения на синхронном устройстве";
case MMSYSERR_INVALHANDLE:
throw "Неверный описатель устройства";
case WAVERR_UNPREPARED:
throw "Попытка воспроизведения неподготовленного блока данных";
case WAVERR_STILLPLAYING: // код ошибки 33
throw "Блок данных находится в очереди на воспроизведение";

}

}

 

В процессе вставки уголок влево заменился на <

 

Михалыч А
Я так понял, вы делаете по одному буферу одинакового размера на воспроизведение и на запись, запускаете их обоих, и когда они отработались, то вы всё останавливаете? Вы же массивы из хедеров задумывали, только размеры почему то единичный поставили. А то можно было-бы конвеер организовать: пока один заполняется - другой обрабатывается...