62944 (588866), страница 4
Текст из файла (страница 4)
sizeof(WAVEHDR)); if (mmr) (MMERR(mmr); return FALSE;}
mmr = waveInAdabuffer(m_hInDev, phdr, sizeof(WAVEHDR)); if (mmr) {MMERR(rnmr);
return FALSE;} (3.1)
phdr = (WAVEHDR*)malloc(sizeof(WAVEHDR));
ASSERT(phdr);
memset(phdr, 0, sizeof(WAVEHDR)); phdr->lpData = (char*)malloc(iBlockSize); ASSERT(phdr->lpData); phdr->dwBufferLength = iBlockSize; phdr->dwUser = (DWORD)(void*)pWave;
mmr = waveInPrepareHeader(m_hInDev, phdr, sizeof(WAVEHDR)); if (mmr) {MMERR(mmr); return FALSE;}
mmr = waveInAddBufTer(m_hInDev, phdr, sizeof(WAVEHDR)); if (mmr) (MMERR(mmr); return FALSE;}
mmr = wavelnS tart(m_h InDe v); if (mmr) {MMERR(mmr); return FALSE;} return TRUE;}
Прежде всего, проверяется, открыто ли устройство. Если открыто, то проверяется, поддерживает ли оно выбранный формат. Если не поддерживает, то выводится сообщение, что устройство уже открыто, но такой формат оно не поддерживает. Если устройство закрыто, то предпринимается попытка открыть какое-либо устройство, поддерживающее данный формат. Если не удалось открыть устройство, поддерживающее данный формат, то выводится сообщение, что никакое устройство не поддерживает данный формат. Устанавливаем два буфера и отправляем их в драйвер устройства. Устанавливаем заголовок. Опустошаем заголовок. Подготавливаем заголовок. Начинаем запись
До тех пор, пока не будет нажата кнопка Stop, будет производиться запись. После этого при нажатии на кнопку Play можно прослушать весь записанный сигнал. При наличии претензий к записанному сигналу, его
можно переписать, повторно нажав на кнопку Record. Все ранее записанные данные при этом теряются
Для обработки полученных данных необходимо нажать на кнопку OpenData, которая вызывает функцию обработки данных. После нажатия на кнопку OpenData, в программе устанавливается режим работы программы -обработка данных, находящихся в буфере.
Ни же приведена функция, обеспечивающая обработку данных, находящихся в буфере.
BOOL CWaveOutDevice::OpenData(CWave *pWave,CClientDC *curDC) (int count=0;
CWaveBlockList* pBL = pWave->GetBlockList(); if(!pBL) return FALSE; POSITION pos = pBL->GetHeadPositionO; if(!pos) return FALSE;
if (pWave->m_bAutoDestruct) pWave->AddRef(); while (pos)
{CWaveBlock* pBlock = pBL->GetNext(pos); ASSERT(pBlock);
WAVEHDR* phdr = (WAVEHDR*)malloc(sizeof(WAVEHDR)); ASSERT(phdr);
memset(phdr, 0, sizeof(WAVEHDR)); phdr->lpData = (char*) pBlock->GetSamples(); phdr->dwBufferLength = pBlock->GetSize(); phdr->dwUser = (DWORD)(void*)pWave; CString ss("");
ss.Format(_T("%s"),pBlock->m_pSamples); int iw = ss.GetLengthO;
intnum=0; (3.2)
for(long h=0;h<4096;h++)
{num=count*4096+h; bunker[num]=(int)ss. GetAt(O); CString s("");
s.Format(_T("%f "),bunker[num]);
ss.Delete(0,l);}
count-H-;
len=4096*count;}
Noise(bunker,len,0);
Filter(bun,l);
Hamming(fнl,l);
Furje(ham,l);
СИр(пЦ);
AfxMessageBox("Data are..."); return TRUE;}
Прежде всего, обнуляем номер буфера. Далее берём список блоков данных из функции GetBlockList(). Если это невозможно, выходим из функции. Определяем позицию первого элемента в блоке данных. При невозможности выполнения действия, выходим из функции. Наращиваем счётчик ref, если мы его используем. До тех пор, пока существует pos, выполняем следующий цикл. Определяем позицию следующего элемента. Устанавливаем заголовок. Очищаем заголовок. Передаём в параметр IpData значения элементов. Определяем длину буфера. Объявляем строку. В эту строку записываем данные о звуке из pBlock. Определяем длину строки. Объявляем и обнуляем счётчик для массива, в который будем записывать данные о звуке. Т.к. буфер ограничен числом 4096, в цикле от 0 до 4096 записываем данные из строки в массив. Номер элемента массива определяется как номер буфера умноженный на его длину плюс номер элемента в буфере. Непосредственно сама запись из строки в массив. Переопределяем тип данных массива. Увеличиваем номер массива.
Рассчитываем длину массива. Вызываем функцию избавления от шумов. Вызываем функцию обработки с помощью фильтра. Вызываем функцию обработки в окне Хэмминга. Вызываем функцию выполнения преобразования Фурье. Вызываем функцию проведения клиппирования. Выводим на экран сообщение, что данные успешно обработаны. Выходим из функции.
После появления сообщения о том, что данные успешно обработаны, можно воспроизвести звуковую информацию, находящуюся в буфере, просмотреть графики функций, записать новую информацию (при этом теряется обработанная) или выйти из программы с сохранением звуковой информации, нажав Ok, или без него, нажав Cancel.
Для просмотра графиков, представляющих результаты обработки данных, в этом окне расположены кнопки, при нажатии на каждую из которых появляется окно, в котором есть кнопка, нажав на которую, получаем график интересующей нас зависимости.
3.3 Реализация функции распознавания голосовых команд голосового управления промышленным роботом
Для реализации функции распознавания голосовых команд голосового управления промышленным роботом была создана функция OpenData. После того, как данные о записанной информации занесены в массив, функция вызывает функции, отвечающие за преобразование этого массива. Прежде всего, вызывается функция Noise, которая на основании разделения вокализованного звука и невокализованного переписывает массив с данными о звуке в новый массив, содержащий лишь участки вокализованного звука.
После этого проводится обработка в окне Хэмминга. График полученный в результате этого преобразования приведен на рис 3.3.
Рисунок 3.3 – График функции, после обработки в окне Хэмминга
Далее выполняется преобразование Фурье для коэффициентов, взвешенных окном Хэмминга После этого производится фильтрация. Затем проводится обратное преобразование Фурье. Далее следует операция клигширования, на основании графика которой делается вывод о том, какое слово было произнесено. На рис. 3.4 приведены графики сигнала для слова «вперёд».
Рисунок 3.5 - Графики сигнала для слова «назад» (а - график вокализованной части сигнала; б - график сигнала после обработки в окне Хэмминга; в -график сигнала после клиппирования)
На рис. 3.6 приведены графики сигнала для слова «стоп».
Рисунок 3.6 – Графики сигнала для слова «стоп» (а - график вокализованной части сигнала; б - график сигнала после обработки в окне Хэмминга; в -график сигнала после клиппирования)
На рис. 3.11 приведены графики сигнала для слова «пять».
Рисунок 3.11 – Графики сигнала для слова «пять» (а - график вокализованной части сигнала; б - график сигнала после обработки в окне Хэмминга; в - график сигнала после клиппирования)
Недостатком предложенного метода распознавания слова является необучаемость программы, отнесение всех произнесенных слов к какому-то из заложенных в программе, а также невозможность настройки в конкретном помещении без специалиста. К достоинствам программы можно отнести независимость программы от диктора, кроме случаев дефекта дикции.
3.4 Реализация голосового управления трёхмерными моделями промышленного робота
Библиотека OpenGL представляет собой интерфейс программирования трехмерной графики - это её основное предназначение. Библиотека представляет собой программный интерфейс для аппаратного обеспечения машинной графики. Этот интерфейс состоит приблизительно из 250 отдельных команд (почти 200 команд в ядре OpenGL и еще 50 команд в библиотеке утилит OpenGL), которые используются для того, чтобы определить объекты и операции, необходимые для создания интерактивных трехмерных прикладных программ.
Единицей информации является вершина, из них состоят более сложные объекты. При создании заданной модели необходимо создать вершины, указать, как их соединять (линиями или многоугольниками), установить координаты и параметры камеры и ламп, а библиотека OpenGL создает изображения на экране [16].
Исходя из вышеуказанных причин было принято решение реализовать моделирование функционирования промышленного робота с помощью средств библиотеки OpenGL.
Для создания требуемой модели робота используются различные трехмерные объекты. Каждая трехмерная модель имеет две разновидности: каркас (wireframe) без поверхностных нормалей и объемная модель (solid) с закраской и поверхностными нормалями. При создании программного обеспечения использовались каркасные модели.
Преобразование вида и моделирование сложно связаны в OpenGL и в действительности объединены в одну матрицу видового преобразования (modelview matrix). Существуют три подпрограммы OpenGL для преобразований модели: glTranslate(), glRotate(), glScale(). Эти подпрограммы выполняют преобразование объекта (или системы координат) с помощью его параллельного переноса (moving), поворота (rotating), растягивания (stretching), сжатия (shrinking) или зеркального отражения (reflecting). Все три команды эквивалентны созданию соответствующей матрицы параллельного переноса (translation), поворота (rotation) или
масштабирования {scaling), а затем вызову команды glMultMatrixQ с этой матрицей в качестве аргумента. Однако использование этих трех подпрограмм должно быть быстрее использования команды glMultMatrixQ. OpenGL автоматически вычисляет эти матрицы для пользователя [17].
Все преобразования в программе осуществлены с помощью указанных подпрограмм.
Ниже приведена функция, обеспечивающая моделирование функционирования промышленного робота.
void CMain::OnOpenGLFirst()
{glPushMatrixQ;
glTranslatef(k*per,-3.0,0.0);
glRotatef(360.0* vspos/100,0,1,0);
glRotatef(l 80,0,0,1);
glLineWidth(2.0);
glPushMatrix();
glRotatef(90.0,1.0,0.0,0.0);
glColor3f(0.0,0.0,1.0);
auxWireCone(1.5,1.0);
glPopMatrix();
glTranslatef(0.0,-l.0,0.0);
glColor3f(0.0,0.5,0.5);
auxWireCylinder(0.6,4.0);
glPushMatrix();
glTranslatef(0.0,-3.0,0.0);
glRotatef(90.0,1.0,0.0,0.0);
glColor3f(l.0,0.0,0.0);
auxWireCylinder(0.6,2.0);
glRotatef(180.0*hspos/100,0.0,1.0,0.0);
glTranslatef(l.0,0.5,0.0); (3.3)
Прежде всего, перемещаем сцену. Далее задаём вращение вокруг оси ъ. Задаём переменную, которая будет обеспечивать перемещение робота согласно голосовым командам. Запоминаем положение основы робота. Строим его основу – конус, поднимаемся к его вершине. Строим колонну робота и перемещаемся к её вершине, поворачиваемся на 90 градусов относительно оси х. Строим цилиндр – крепление плеча. Задаём движение
плеча горизонтальной прокруткой. Перемещаемся в конец крепления плеча и создаём плечо –- строим призму. Перемещаемся к её концу, поворачиваемся на 90 градусов и создаём цилиндр – локоть. Далее после перемещения к концу этого цилиндра строим призму – основание схвата, поворачиваемся на 90 градусов и строим первый и второй пальцы.
Результат моделирования робота приведен на рис. 3.1
Рисунок 3.1 Результат моделирования функционирования промышленного робота
Выводы
Организация управления промышленными роботами (ПР) продолжает оставаться актуальной задачей робототехники. Управление роботами реализуется различными способами. К ним относятся: управление при помощи пультов ручного управления, командное управление от управляющих компьютеров, дистанционное управление при помощи внешних вычислительных систем. С точки зрения повышения эффективности обучения ПР одним из наиболее перспективных способов является голосовое управление.
Во время написания магистерской аттестационной работы были проанализированы методы цифровой обработки звуковых сигналов и их использование в системах распознавания речи, выполнен анализ цифровой фильтрации и особенностей акустической фонетики и её учёт при обработке цифровых сигналов.
В работе рассмотрены гомоморфная обработка речи, кодирование речи на основе линейного предсказания и цифровая её обработка в системах речевого общения человека с машиной, особенности различных систем распознавания речи.
Первоначальной задачей являлось создание интерфейса записи и воспроизведения звукового сигнала. Это было выполнено с использованием встроенной библиотеки mmsystem операционной системы Windows. Далее были добавлены функции, обеспечивающие обработку записанного сигнала: выделение вокализованных участков речи, взвешивание коэффициентов дискретного сигнала с помощью окна Хэмминга, преобразование Фурье, фильтрация, обратное преобразование Фурье, а также клиппирование и вычисление кепстра.
На основании проведенного анализа сигнала создана функция распознавания слова-команды. При помощи графической библиотеки OpenGL была обеспечена визуализация выполнения трёхмерной моделью ПР
распознанной голосовой команды. Применение библиотеки OpenGL позволяет моделировать любой из как уже существующих, так и разрабатываемых видов ПР.
Сложность решаемой задачи обуславливалась тем, что даже один и тот же человек не может два раза произнести одно и то же слово абсолютно одинаково и возникает разница в скорости произнесения слова и амплитуде звукового смгнала. При этом возникает необходимость выделения зависимости фонем (сочетания элементарных звуков), присущих одному слову, а потом описания этих зависимостей в виде, понятном для распознавания. Выделение этих зависимостей - является достаточно сложно реализуемой задачей.
Основным достоинством программы является её независимость от оператора: при условиях достаточно чёткого произношения команды, пол и возраст диктора не имеет влияния на распознавание слова. Её применение целесообразно для адаптации промышленного робота к условиям производственной среды, а также для создания информационного потока управления роботом. Возможными перспективами улучшения программы являются увеличение словаря, добавление возможности обучения и улучшение гибкости цифрового представления звукового сигнала.
Перечень ссылок
-
Рабинер Л. Р., Шафер Р. В. Цифровая обработка речевых сигналов: Пер. с англ./Под ред. М. В. Назарова и Ю. Н. Прохорова. - М.: Радио и связь, 1981.-496 с.
-
Рабинер Л. Р., Гоулд Б. Теория и применение цифровой обработки сигналов: Пер. с англ./Под ред. Александрова Ю. Н. - М.: Мир, 1978. -848 с.
-
А. V. Oppenhehn and R. W. Schafer, Digital Signal Processing,, Prentice-Hall, Inc., Englewood Cliffs, N.J., 1975. - 436 p.
-
A. Peled and B. Liu, Digital Signal Processing. Theory, Design and Implementation, John Wiley and Sons.New York, 1976. - 675 p.
-
J. W. Cooley and J. W. Tukey, "An Algorithm for the Machine Computation of Complex Fourier.Series," Math Computation, Vol. 19, 1965. - 452 p.
-
Бондарев В. H., Трёстер Г., Чернега В. С. Цифровая обработка сигналов: методы и средства. Учеб. Пособие для вузов. 2-е изд. - X.: Конус, 2001. -398 с.
-
Марпл С. Л. Цифровой спектральный анализ и его приложения. - М.: Мир, 1990.-584 с.
-
Бендат Дж., Пирсол А. Применения корреляционного и спектрального анализа. -М.: Мир, 1983. -312 с.
-
Гольденберг Л. М., Матюшкин Б. Д., Поляк М. Н. Цифровая обработка сигналов: Справочник. -М.: Радио и связь, 1985. - 312 с.
-
Гутников В. С. Фильтрация измерительных сигналов. - Л.: Энергоатомиздат, Ленингр. отд-ние, 1990. - 192 с.
-
J. Н. McClellan, Т. W. Parks, and L. R. Rabiner, "A Computer Program for Designing Optimum FIR Linear Phase Digital Filters," IEEE Trans. Audio and Electro acoustics, Vol. AU-21, 1973. - 347 p.
-
Цифровые фильтры в электросвязи и радиотехнике/ А. В. Брунченко, Ю.Г. Бутыльский, Л. М. Гольденберг и др.: под ред. Л. М. Гольденберга.
- M.: радио и связь, 1982. - 224 с.
-
J. L. Ftanagan, С. H. Coker, L. R. Rabiner, R. W. Schafer, and N. Umeda, "Synthetic Voices for Computers," IEEE Spectrum, Vol. 7, No. 10, October 1970.-536 p.
-
MFC и Visual С++. Энциклопедия программиста: Пер. с англ./ Юджин Олафсен, Кенн Скрайбнер, К. Дэвид Уайт и др. - СПб.: ООО «ДиаСофтЮП», 2004. - 992с.
-
Шилдт Герберт. MFC: основы программирования. - К.: Издательская группа BHV, 1997. - 560 с.
-
Тихомиров Ю.В. OpenGL. Программирование трехмерной графики. -СПб.: БХВ-Петербург, 2002.-304 с.
-
OpenGL. Официальное руководство программиста: Пер. с англ. / Мейсон By, Джеки Нейдер, Том Девис, Дейв Шрайнер. - СПб: ООО «ДиаСофтЮП», 2002. - 592 с.
Приложение А. Элементы текстов программного кода
// recorddlh: header file class CRecordDlg;
class CRecDlgNotifyObj: public CWaveNotifyObj {public:
CRecDlgNotifyObjO; -CRecDlgNotifyObjO; void Attach(CRecordDlg* pDlg) {m_pDlg = pDlg;}
virtual void NewData(CWave *pWave, CWaveBIock* pBlock);
virtual void EndPlayback(CWave *pWave);
CRecordDlg* m_pDlg;};
class CFilterDlg. public CDialog
{public. CWaveOutDevice* m_pOutDev;
CFilterDlg(CWnd* pParent = NULL);
enum { IDD = IDD_FILTERDLG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); protected:
afxmsg void OnFilter(); DECLAREMESSAGEMAPOJ; class CRecordDlg: public CDialog {public:
CRecordDlg(CWnd* pParent = NULL); ~CRecordDlg();
void NewData(CWave *pWave, CWaveBIock* pBlock);
void EndPlayback(CWave *pWave);
enum { IDD = IDD_RECORDDLG };
CButtonmbtnOpenData;
CComboBox mcbSource;
CComboBox mcbFormat;
CStatic mwndFrame;
CButton mbtnPause;
CButton mbtnPlay;
CButton mbtnRecord;
CButton mbtnOK;
CButton mbtnStop;
CString mstrFormat;
CString m_strSource;
public:
void UDdatdTJClientDC *curDC>:
CFilterDIg* m_pFUter; CWave* m_pWave; private:
enum MODE {IDLE, SAMPLING,PLAYTNG,RECORDING,OPEN };
CVUMeter m_VU;
int mJNumDevs;
WAVEINCAPS* m_pDevCaps;
CWavelnDevice mlnDev;
CWave mSampleWave;
CRecDlgNotifyObj m_NotifyObj;
int mJMode;
void FillDeviceList();
void FillFormatListQ;
void SetMode(MODE m);
void BuildFormat(PCMWAVEFORMAT& fmt, DWORD dwFormat); protected:
virtual void DoDataExchange(CDataExchange* pDX);
virtual BOOL OnlnitDialogO;
afxmsg void OnSelchangeFormat();
afxmsg void OnClickedPlay();
afxjmsg void OnClickedRecordO;
afxmsg void OnClickedStop();
afxmsg void OnSelchangeSource();
virtual void OnCancel();
virtual void OnOK();
afxmsg void OnDrawItem(int nlDCtl, LPDRAW1TEMSTRUCT IpDrawItemStruct); afxmsg void OnMeasureItem(int rJDCtl, LPMEASUREITEMSTRUCT IpMeasureltemStruct); afxmsg void OnClickedOpenData(); afxmsg void OnUpdate();
afxmsg void OnHScroll(UTNT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnGraphicQ;
afxmsg void OnHamming();
afxmsg void OnFilterQ;
afxmsg void OnFurjeQ;
afx_msg void OnObrfurje();
afxmsg void OnClip();
DECLARE_MESSAGE_MAP()};
class CGraphicDlg: public CDialog
{public:
CWaveOutDevice* mjOutDev; CGraphicDlg(CWnd* pParent = NULL); enum { IDD = IDD GRAPHIC };
protected:
virtual void DoDataExchange(CDataExchange* pDX); protected:
afxmsg void OnGraphicQ; DECLAREMESS AGE_MAP()}; class CHammingDlg: public CDialog {public:
CWaveOutDevice* m_pOutDev; CHammingDlg(CWnd* pParent = NULL); enum {IDD = IDD HAMMING }; protected:
virtual void DoDataExchange(CDataExchange* pDX); protected:
afxmsg void OnHammingO; DECLAREMESSAGEMAPO); class CFurjeDlg. public CDialog {public:
CWaveOutDevice* m_pOutDev; CFurjeDlg(CWnd* pParent = NULL); enum {IDD = IDDFURJE }; protected:
virtual void DoDataExchange(CDataExchange* pDX); protected:
afxmsg void OnFurjeO; DECLAREMESSAGEMAPO}; class CObrFurjeDlg: public CDialog {public:
CWaveOutDevice* m_pOutDev; CObrFurjeDlg(CWnd* pParent = NULL); enum { IDD = IDD OBRFURJE }; protected:
virtual void DoDataExchange(CDataExchange* pDX); protected:
afxmsg void OnObrfurje(); DECLAREMESSAGEMAPO}; class CClipDlg. public CDialog {public:
CWaveOutDevice* m_pOutDev; CClipDlg(CWnd* pParent = NULL); enum { IDD = EDDCLIP }; protected:
virtual void DoDataExchange(CDataExchange* pDX);
ON_BN_CLICKED(IDC_GRAPHIC, OnGraphic) ON_BN_CLICKED(IDC_HAMMrNG, OnHamming) ON_BN_CLICKED(IDC_FILTER OnFilter) ON_BN_CLICKED(IDC_FURJE, OnFurje) ON_BN_CLICKED(IDC_OBRFURJE, OnObrfurje) ON_BN_CLICKED(IDC_CLIP, OnClip) END_MESSAGE_MAP() BOOL CRecordDlg::OnInitDialog() {CDialog::OnInitDialog(); ASSERT(mjpWave = NULL); CRect rcVU;
m_wndFrame.GetWindowRect(&rcVU); ScreenToClient(&rcVU);
m_VU.Create(nVU",WS_CHILD | WS_VISIBLE,rcVU,this,l);
m_VU.SetValue(0> 0);
FillDeviceListQ;
FillFormatListO;
SetMode(SAMPLLNG);
return TRUE; }
void CRecordDlg::OnSelchangeFormatO
{OnClickedStopO;}
void CRecordDlg::OnClickedPIayO
{SetMode(PLAYING);
CClientDCdc(this);}
void CRecordDlg. OnClickedRecordO
{ SetMode(RECORDLNG);}
void CRecordDlg. OnClickedStopO
{SetMode(S AMPLING);}
void CRecordDlg::OnSelchangeSource()
{OnClickedStopO;
FillFormatListO;}
void CRecordDlg::OnCancelO
{ OnClickedStopO;
SetMode(IDLE);
mVU.DestroyWindowO;
if (m_pWave) {delete m_pWave;
m_pWave = NULL;}
CDialog::OnCancel();}
void CRecordDlg. OnOKO
{ OnClickedStopO;
SetMode(IDLE);
mVU.DestroyWindowO;
CDialog::OnOK();}
void CRecordDlg::FillDeviceList()
{miNumDevs = wavelnGetNumDevsO;
if (miNumDevs == 0) {
AfxMessageBox("There are no suitable input devices");
EndDialog(IDCANCEL);
return;}
if (m_pDevCaps) delete m_pDevCaps;
m_pDevCaps = new WAVEINCAPSfmiNumDevs];
m_cbSource.ResetContent();
for (int i=0; KmiNumDevs; i++) {
waveInGetDevCaps(i,&m_pDevCaps[i],sizeof(WAVEINCAPS)); m_pDevCaps[i].wMid = i;
m_cbSource.AddString((LPCSTR)&m_pDevCaps[i]);}
mcbSource. SetCurSel(0);}
void CRecordDlg.:FillFormatList()
{ mcbFormat.ResetContentO;
int iSel = m_cbSource.GetCurSel();
if(iSel = CBERR) return;
WAVEINCAPS* pCaps = (WAVEINCAPS*) m_cbSource.GetItemData(iSel);
ASSERT(pCaps);
DWORD dwMask = 0x00000001;
for(inti=0; i<12; i++) {
if (pCaps->dwFormats & dwMask) {
m_cbFormat.AddString((LPCSTR)dwMask);}
dwMask = dwMask « 1; }
mcbFormat. SetCurSel(O);}
void CRecordDlg.OnDrawItem(int nlDCtl, LPDRAWITEMSTRUCT pDI) {char* pszText = NULL; switch (nlDCtl) { case IDC_SOURCE: {
WAVEINCAPS* pCaps = (WAVEINCAPS*)(pDI->itemData); pszText = pCaps->szPname; } break;
case IDC FORMAT: { switch(pDI->itemData) { case WAVE_FORMAT_1M08: pszText = "11.025 kHz, 8 bit, mono"; break;
case WAVE_FORMAT_1S08: pszText = "11.025 kHz, 8 bit, stereo"; break;
case WAVE_FORMAT_lM16: pszText = "11.025 kHz, 16 bit, mono"; break;
case WAVE_F0RMAT_1S16. pszText = "22.05 kHz, 16 bit, stereo"; break;
case WAVE_FORMAT_2M08: pszText = "22.05 kHz, 8 bit, mono"; break;
case WAVE_FORMAT_2S08: pszText = "22.05 kHz, 8 bit, stereo"; break;
case WAVE_FORMAT_2M16: pszText = "22.05 kHz, 16 bit, mono"; break;
case WAVEJFORMATJ2S16. pszText = "22.05 kHz, 16 bit, stereo"; break;
case WAVEJ?ORMAT_4M08: pszText = "44.1 kHz, 8 bit, mono"; break;
case WAVE_FORMAT_4S08: pszText = "44.1 kHz, 8 bit, stereo"; break;
case WAVE_FORMAT_4M16: pszText = "44.1 kHz, 16 bit, mono"; break;
case WAVE_FORMAT_4S16:
pszText = "44.1 kHz, 16 bit, stereo";
break; default:
pszText = "Unknown";
break;} } break; default:
break;} if (IpszText) return;
: ^rawTextCpDI^hDC^szText.-L&CpDI^rcItem), DTLEFT | DTVCENTER); if (pDI->itemState & ODSSELECTED) {
::InvertRect(pDI->hDC, &(pDI->rcItem));} if (PDI->itemState & ODS_FOCUS) {
::DrawFocusRect(pDI->hDC, &(pDI->rdtem)); }}
void CRecordDlg::OnMeasureItem(int ruDCtl, LPMEASUREITEMSTRUCT lpMeasureltemStruct) { CClientDC dc (this);
4096>12>