//////////////////////////////////////////////////////////////////////////// // by Norma Antonanzas-Barroso // c 1996 The Regents of the University of California // All rights reserved. You may redistribute this program without restriction, // provided 1) this copyright notice appears on all copies; and 2) no fee // is charged. Note that technical support is not avilable for this code. //////////////////////////////////////////////////////////////////////////// // This is a program to test DirectDSP in Windows // It opens a dialog box with a button control to PLAY and an edit // control to enter the file number to play. // doitview.cpp : implementation file // // DSPower-HwLib / DirectDSP™ software package include files #include "enmgr.h" // Engine Manager #include "hwmgr.h" // Hardware Manager #include "hwlib.h" // Hardware Library #include "stdafx.h" #include "doit.h" #include "doitview.h" #include "fcntl.h" #include "sys\types.h" #include "sys\stat.h" #include "io.h" ///////////////////////////////////////////////////////////////////////////// // CDoitView IMPLEMENT_DYNCREATE(CDoitView, CFormView) CDoitView::CDoitView() : CFormView(CDoitView::IDD) { //{{AFX_DATA_INIT(CDoitView) m_FNumber = "1"; //}}AFX_DATA_INIT m_hBuf = NULL; m_hBoard = NULL; m_fBoardInitialized = FALSE; m_pBuf = NULL; } CDoitView::~CDoitView() { if ( m_fBoardInitialized ) DSDisableBoard ( m_hBoard ); if ( m_hBoard != NULL ) { DSCancelWaitBuffer ( m_hBoard, 0 ); DSResetProcessor ( m_hBoard, 0x01 ); DSFreeBoard ( m_hBoard ); } if ( hEngine != NULL ) { DSUnregisterEngineMsgWnd ( hEngine, DS_REMW_SETDSPDATARDYMSG ); DSEngineClose ( hEngine ); } if ( m_hBuf != NULL ) GlobalFree ( m_hBuf ); close ( m_file ); } void CDoitView::DoDataExchange(CDataExchange* pDX) { CFormView::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDoitView) DDX_Text(pDX, IDC_EDIT_FILENUMBER, m_FNumber); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDoitView, CFormView) ON_MESSAGE(WM_DSPENGINE_BUFRDY, OnDspEngineBufferReady) //{{AFX_MSG_MAP(CDoitView) ON_BN_CLICKED(IDC_BUTTON_PLAY, OnButtonPlay) ON_WM_CREATE() ON_EN_CHANGE(IDC_EDIT_FILENUMBER, OnChangeEditFilenumber) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDoitView message handlers void CDoitView::OnButtonPlay() { unsigned int np; char tmpstr[100]; short int ChanList[MAXCHAN] = { 0, 0, 0, 0, 0, 0, 0, 0 }; DWORD dwFsMode; float FsActual; int i; short int NumChan = 1; HWND hwndDoit = NULL; short * temp = NULL; WORD wBoardClass; unsigned int ni; unsigned int nb; // INITIALIZATION. This has to be repeated every time it plays, it cannot go // just in CREATE. // interrogate engine for board type values wBoardClass = DSGetBoardClass(m_hBoard); // send down some important variables: DSPutDSPProperty(m_hBoard, DSP_BOARDCLASS, wBoardClass & 0x0ff); // main type in low byte DSPutDSPProperty(m_hBoard, DSP_BOARDSUBCLASS, wBoardClass >> 8); // subtype in high byte DSPutDSPProperty(m_hBoard, DSP_OPMODE, 1); // play back is mode 1 // acquisition is mode 0 DSPutDSPProperty(m_hBoard, DSP_SCALEOUT, 256L); DSPutDSPProperty(m_hBoard, DSP_FILTTYPE1, 0); // disable trace 1 real-time filter DSPutDSPProperty(m_hBoard, DSP_FILTTYPE2, 0); // disable trace 2 real-time filter DSPutDSPProperty(m_hBoard, DSP_TRIGLEVEL, 0); // free-run triggering DSPutDSPProperty(m_hBoard, DSP_TRIGCHANLIST, 0); DSPutDSPProperty(m_hBoard, DSP_BUFLEN, BUFFSIZE); // buffer size, the real one DSPutDSPProperty(m_hBoard, DSP_HOSTBUFNUM, 0); // starting buffer numbers DSPutDSPProperty(m_hBoard, DSP_BUFNUM, 0); DSPutDSPProperty(m_hBoard, DSP_NUMCHAN, NumChan ); // number of channels DWORD dw = 0; ChanList[0] = 0; DSPutDSPProperty(m_hBoard, DSP_CHANLIST, dw); // channel list DSPutDSPProperty(m_hBoard, DSP_GAINLIST, 0); // gain list // determine sampling rate ctrl. reg. value, and actual rate (closest rate possible to desired); // CalcSampFreq returns ctrl. reg. value directly, uses ptr to return actual sampling frequency (in Hz) FsActual = 20000.; dwFsMode = DSCalcSampFreq(m_hBoard, FsActual, NumChan, (short far*)&ChanList, &FsActual); DSPutDSPProperty(m_hBoard, DSP_FSMODE, dwFsMode); // sampling rate control register (mode value) DSPutDSPProperty(m_hBoard, DSP_FSVALUE, *((long*)&FsActual)); // actual sampling rate (in Hz) // END INITIALIZATION // Get the pointer to the allocated memory, read data into host buffer // in two instances because it only takes unsigend int and we are reading // 80000 bytes. if ( m_FileNumber >200 ) { MessageBox ( "too large file number", "1 Doit Test Prog: read failed", MB_OK); AfxGetMainWnd()->PostMessage ( WM_CLOSE ); return; } temp = new short[BUFFSIZE/2]; if ( temp == NULL ) { MessageBox ( "new failed", "Doit Test Prog", MB_OK); delete[] temp; AfxGetMainWnd()->PostMessage ( WM_CLOSE ); return; } m_pBuf = (short huge*) GlobalLock ( m_hBuf ); if ( m_pBuf == NULL ) { MessageBox ( "GlobalLock failed", "Doit Test Prog", MB_OK); delete[] temp; AfxGetMainWnd()->PostMessage ( WM_CLOSE ); return; } lseek ( m_file, 1024L + ( m_FileNumber - 1 ) * sizeof ( short ) * 50000L, SEEK_SET ); ni = (unsigned int) BUFFSIZE / 2; nb = ni * (unsigned int)sizeof(short); np = (unsigned int )_read ( m_file, temp, nb ); if ( np != nb ) { GlobalUnlock ( m_hBuf ); MessageBox ( "data < BUFFSIZE", "1 Doit Test Prog: read failed", MB_OK); delete[] temp; AfxGetMainWnd()->PostMessage ( WM_CLOSE ); return; } for ( i = 0; i < BUFFSIZE/2; i++ ) m_pBuf[i] = temp[i]; np = (unsigned int )_read ( m_file, temp, nb ); if ( np != nb ) { GlobalUnlock ( m_hBuf ); MessageBox ( "data < BUFFSIZE", "2 Doit Test Prog: read failed", MB_OK); delete[] temp; AfxGetMainWnd()->PostMessage ( WM_CLOSE ); return; } for ( i = 0; i < BUFFSIZE/2; i++ ) m_pBuf[i+BUFFSIZE/2] = temp[i]; delete[] temp; // move the data to the board memory, send BUFFSIZE 0's at the end to // give time for the data ready message to be issued if ( ( DSPutMem ( m_hBoard, DS_GM_LINEAR_DATA, m_dwBufferBaseAddr, DS_GM_SIZE16, m_pBuf,(DWORD) ( BUFFSIZE*2 ) ) ) == NULL ) { itoa ( DSGetEngineErrorStatus ( hEngine ), tmpstr, 10 ); MessageBox ( tmpstr, "Doit Test Prog: DSLoadFileProcessor failed", MB_OK); AfxGetMainWnd()->PostMessage ( WM_CLOSE ); return; } // start to play DSRunProcessor ( m_hBoard, 0x01 ); // initialize wait for buffer: send a WM_DSPENGINE_BUFRDY message when it // finished playing one buffer DSWaitForBuffer( m_hBoard, 0, NULL, DS_WFB_POLLED); // free the pointer GlobalUnlock ( m_hBuf ); return; } ///////////////////////////////////////////////////////////////////////// void CDoitView::OnChangeEditFilenumber() { UpdateData (TRUE); m_FileNumber = (UINT) atoi ( m_FNumber ); } ///////////////////////////////////////////////////////////////////////// // Board sends this message when finished reading BUFFSIZE points, the // remaining zeros in the buffer guaranty silence between the issue of // the message and the response by this function LRESULT CDoitView::OnDspEngineBufferReady ( WPARAM, LPARAM ) { // reset DSPboard, processor 0 only DSResetProcessor ( m_hBoard, 0x01 ); return 0L; } ///////////////////////////////////////////////////////////////////////// void CDoitView::OnInitialUpdate ( void ) { // SIGNALOGIC requirements here: DWORD dwMemSize; HWND hwndDoit = NULL; char tmpstr[100]; short int ChanList[MAXCHAN] = { 0, 0, 0, 0, 0, 0, 0, 0 }; short int NumChan = 1; m_hBuf = NULL; m_hBoard = NULL; m_fBoardInitialized = FALSE; m_pBuf = NULL; strcpy ( m_szBoard, "SIG32C-L" ); // board designator hwndDoit = GetSafeHwnd (); // get window handler if ( hwndDoit == NULL ) { MessageBox ( "NULL window handle", "Doit Test Prog", MB_OK); AfxGetMainWnd()->PostMessage ( WM_CLOSE ); } DSShowEngMgrStatusWindow(); // debugging: show status window hEngine = DSEngineOpen(DS_EO_HSA, NULL); // open HyperSignal-Acoustics if ( !hEngine ) { itoa ( DSGetHWLibErrorStatus(), tmpstr, 10 ); MessageBox ( tmpstr, "Doit Test Prog: DSEngineOpen failed", MB_OK); AfxGetMainWnd()->PostMessage ( WM_CLOSE ); } // assign a board handle: engine handle, board designator string, instruction set, IO base addr, Mem base addr m_hBoard = DSAssignBoard ( hEngine, m_szBoard, NULL, NULL, NULL ); // use defaults if ( m_hBoard == NULL ) { itoa ( DSGetHWLibErrorStatus(), tmpstr, 10 ); MessageBox ( tmpstr, "Doit Test Prog: DSAssignBoard", MB_OK); AfxGetMainWnd()->PostMessage ( WM_CLOSE ); } // initialize the board; make sure it's installed and responded m_fBoardInitialized = DSInitBoard(m_hBoard); if ( !m_fBoardInitialized ) { itoa ( DSGetEngineErrorStatus ( hEngine ), tmpstr, 10 ); MessageBox ( tmpstr, "Doit Test Prog: DSInitBoard failed", MB_OK); AfxGetMainWnd()->PostMessage ( WM_CLOSE ); } // load executable DSP code file if (!DSLoadFileProcessor ( m_hBoard, NULL, 1 ) ) { itoa ( DSGetEngineErrorStatus ( hEngine ), tmpstr, 10 ); MessageBox ( tmpstr, "Doit Test Prog: DSLoadFileProcessor failed", MB_OK); AfxGetMainWnd()->PostMessage ( WM_CLOSE ); } // get the memory size in 16 bits words dwMemSize = DSGetMemSize ( m_hBoard, 0x01 ); if ( dwMemSize < 2*BUFFSIZE ) { MessageBox ( "buffer size < BUFFSIZE", "Doit Test Prog", MB_OK); AfxGetMainWnd()->PostMessage ( WM_CLOSE ); } // get address of output time domain data m_dwBufferBaseAddr = DSGetDSPProperty ( m_hBoard, DSP_TIMDATAADDR ); // reset DSPboard, processor 0 only DSResetProcessor ( m_hBoard, 0x01 ); // register callback window for buffer ready messages UINT ret = DSRegisterEngineMsgWnd ( hEngine, DS_REMW_SETDSPDATARDYMSG, hwndDoit ); if ( !ret ) { itoa ( DSGetEngineErrorStatus ( hEngine ), tmpstr, 10 ); MessageBox ( tmpstr, "Doit Test Prog: DSRegisterEngine failed", MB_OK); AfxGetMainWnd()->PostMessage ( WM_CLOSE ); } // allocate some memory to hold board buffers DWORD nbytes = 2 * (DWORD )BUFFSIZE * ( DWORD )sizeof ( short ); m_hBuf = GlobalAlloc ( GMEM_ZEROINIT | GMEM_MOVEABLE, nbytes ); if ( m_hBuf == NULL ) { MessageBox ( "GlobalAlloc failed", "Doit Test Prog", MB_OK); AfxGetMainWnd()->PostMessage ( WM_CLOSE ); } // open the file char myfile[] = "doit.voi"; m_file = _open ( myfile, _O_BINARY | _O_RDONLY ); if ( m_file == -1 ) { MessageBox ( "Cannot open", "Doit Test Prog", MB_OK); AfxGetMainWnd()->PostMessage ( WM_CLOSE ); } UpdateData ( FALSE ); m_FileNumber = (UINT) atoi ( m_FNumber ); }