From fb0abfcd086265a0c96666759dcf2442e20203aa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 18 Feb 2020 21:44:21 +0100 Subject: [PATCH] - removed Windows CD Audio support. Better get rid of this legacy baggage now, before it is too later. --- include/zmusic.h | 11 - source/CMakeLists.txt | 4 - source/musicformats/music_cd.cpp | 210 ------ source/musicformats/win32/helperthread.cpp | 292 -------- source/musicformats/win32/helperthread.h | 85 --- source/musicformats/win32/i_cd.cpp | 762 --------------------- source/musicformats/win32/i_cd.h | 72 -- source/zmusic/zmusic.cpp | 29 - 8 files changed, 1465 deletions(-) delete mode 100644 source/musicformats/music_cd.cpp delete mode 100644 source/musicformats/win32/helperthread.cpp delete mode 100644 source/musicformats/win32/helperthread.h delete mode 100644 source/musicformats/win32/i_cd.cpp delete mode 100644 source/musicformats/win32/i_cd.h diff --git a/include/zmusic.h b/include/zmusic.h index f82aca7..2cbb853 100644 --- a/include/zmusic.h +++ b/include/zmusic.h @@ -301,7 +301,6 @@ extern "C" ZMUSIC_DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSong(ZMusicCustomReader* reader, EZMusicMidiDevice device, const char* Args); ZMUSIC_DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSongFile(const char *filename, EZMusicMidiDevice device, const char* Args); ZMUSIC_DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSongMem(const void *mem, size_t size, EZMusicMidiDevice device, const char* Args); - ZMUSIC_DLL_IMPORT ZMusic_MusicStream ZMusic_OpenCDSong(int track, int cdid); ZMUSIC_DLL_IMPORT zmusic_bool ZMusic_FillStream(ZMusic_MusicStream stream, void* buff, int len); ZMUSIC_DLL_IMPORT zmusic_bool ZMusic_Start(ZMusic_MusicStream song, int subsong, zmusic_bool loop); @@ -335,16 +334,6 @@ extern "C" ZMUSIC_DLL_IMPORT const ZMusicMidiOutDevice *ZMusic_GetMidiDevices(int *pAmount); ZMUSIC_DLL_IMPORT int ZMusic_GetADLBanks(const char* const** pNames); - // Direct access to the CD drive. - ZMUSIC_DLL_IMPORT void ZMusic_CD_Stop(); - ZMUSIC_DLL_IMPORT void ZMusic_CD_Pause(); - ZMUSIC_DLL_IMPORT zmusic_bool ZMusic_CD_Resume(); - ZMUSIC_DLL_IMPORT void ZMusic_CD_Eject(); - ZMUSIC_DLL_IMPORT zmusic_bool ZMusic_CD_UnEject(); - ZMUSIC_DLL_IMPORT void ZMusic_CD_Close(); - ZMUSIC_DLL_IMPORT zmusic_bool ZMusic_CD_Enable(const char* drive); - - #ifdef __cplusplus } diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 0c76769..0e425eb 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -62,8 +62,6 @@ include_directories( "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/ if (WIN32) set( PLAT_SOURCES mididevices/music_win_mididevice.cpp - musicformats/win32/i_cd.cpp - musicformats/win32/helperthread.cpp ) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") if (ALSA_FOUND) @@ -81,7 +79,6 @@ file( GLOB HEADER_FILES mididevices/*.h midisources/*.h musicformats/*.h - musicformats/win32/*.h decoder/*.h streamsources/*.h ../thirdparty/*.h @@ -112,7 +109,6 @@ set( all_files streamsources/music_xa.cpp musicformats/music_stream.cpp musicformats/music_midi.cpp - musicformats/music_cd.cpp decoder/sounddecoder.cpp decoder/sndfile_decoder.cpp decoder/mpg123_decoder.cpp diff --git a/source/musicformats/music_cd.cpp b/source/musicformats/music_cd.cpp deleted file mode 100644 index 04adb98..0000000 --- a/source/musicformats/music_cd.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* -** music_cd.cpp -** -**--------------------------------------------------------------------------- -** Copyright 1999-2003 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#include "zmusic/zmusic_internal.h" -#include "zmusic/musinfo.h" - -#ifdef _WIN32 - -#include "zmusic/m_swap.h" -#include "win32/i_cd.h" - - -// CD track/disk played through the multimedia system ----------------------- - -class CDSong : public MusInfo -{ -public: - CDSong(int track, int id); - ~CDSong(); - void Play(bool looping, int subsong); - void Pause(); - void Resume(); - void Stop(); - bool IsPlaying(); - bool IsValid() const { return m_Inited; } - -protected: - CDSong() : m_Inited(false) {} - - int m_Track; - bool m_Inited; -}; - -// CD track on a specific disk played through the multimedia system --------- - -class CDDAFile : public CDSong -{ -public: - CDDAFile(MusicIO::FileInterface* reader); -}; - - - -void CDSong::Play (bool looping, int subsong) -{ - m_Status = STATE_Stopped; - m_Looping = looping; - if (m_Track != 0 ? CD_Play (m_Track, looping) : CD_PlayCD (looping)) - { - m_Status = STATE_Playing; - } -} - -void CDSong::Pause () -{ - if (m_Status == STATE_Playing) - { - ZMusic_CD_Pause (); - m_Status = STATE_Paused; - } -} - -void CDSong::Resume () -{ - if (m_Status == STATE_Paused) - { - if (ZMusic_CD_Resume ()) - m_Status = STATE_Playing; - } -} - -void CDSong::Stop () -{ - if (m_Status != STATE_Stopped) - { - m_Status = STATE_Stopped; - ZMusic_CD_Stop (); - } -} - -CDSong::~CDSong () -{ - Stop (); - m_Inited = false; -} - -CDSong::CDSong (int track, int id) -{ - bool success; - - m_Inited = false; - - if (id != 0) - { - success = CD_InitID (id); - } - else - { - success = CD_Init (-1); - } - - if (success && (track == 0 || CD_CheckTrack (track))) - { - m_Inited = true; - m_Track = track; - } -} - -bool CDSong::IsPlaying () -{ - if (m_Status == STATE_Playing) - { - if (CD_GetMode () != CDMode_Play) - { - Stop (); - } - } - return m_Status != STATE_Stopped; -} - -CDDAFile::CDDAFile (MusicIO::FileInterface* reader) - : CDSong () -{ - uint32_t chunk; - uint16_t track; - uint32_t discid; - auto endpos = reader->tell() + reader->filelength() - 8; - - // ZMusic_OpenSong already identified this as a CDDA file, so we - // just need to check the contents we're interested in. - reader->seek(12, SEEK_CUR); - - while (reader->tell() < endpos) - { - reader->read(&chunk, 4); - if (chunk != (('f')|(('m')<<8)|(('t')<<16)|((' ')<<24))) - { - reader->read(&chunk, 4); - reader->seek(LittleLong(chunk), SEEK_CUR); - } - else - { - reader->seek(6, SEEK_CUR); - reader->read(&track, 2); - reader->read(&discid, 4); - - if (CD_InitID (LittleLong(discid)) && CD_CheckTrack (LittleShort(track))) - { - m_Inited = true; - m_Track = track; - } - return; - } - } -} - -MusInfo* CD_OpenSong(int track, int id) -{ - return new CDSong(track, id); -} - -MusInfo* CDDA_OpenSong(MusicIO::FileInterface* reader) -{ - return new CDDAFile(reader); -} - -#else - -MusInfo* CD_OpenSong(int track, int id) -{ - return nullptr; -} - -MusInfo* CDDA_OpenSong(MusicIO::FileInterface* reader) -{ - return nullptr; -} - - -#endif diff --git a/source/musicformats/win32/helperthread.cpp b/source/musicformats/win32/helperthread.cpp deleted file mode 100644 index ef6d0d3..0000000 --- a/source/musicformats/win32/helperthread.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* -** helperthread.cpp -** -** Implements FHelperThread, the base class for helper threads. Includes -** a message queue for passing messages from the main thread to the -** helper thread. (Only used by the CD Audio player) -** -**--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#include "helperthread.h" - -//========================================================================== -// -// ---Constructor--- -// -//========================================================================== - -FHelperThread::FHelperThread () -{ - ThreadHandle = NULL; - ThreadID = 0; - Thread_Events[0] = Thread_Events[1] = 0; - memset (Messages, 0, sizeof(Messages)); - MessageHead = 0; - MessageTail = 0; -} - -//========================================================================== -// -// ---Destructor--- -// -//========================================================================== - -FHelperThread::~FHelperThread () -{ - DestroyThread (); -} - -//========================================================================== -// -// LaunchThread -// -//========================================================================== - -bool FHelperThread::LaunchThread () -{ - int i; - - MessageHead = MessageTail = 0; - for (i = 0; i < MSG_QUEUE_SIZE; i++) - { - if ((Messages[i].CompletionEvent = CreateEvent (NULL, FALSE, i > 0, NULL)) == NULL) - break; - } - if (i < MSG_QUEUE_SIZE) - { - for (; i >= 0; i--) - { - CloseHandle (Messages[i].CompletionEvent); - } - return false; - } - InitializeCriticalSection (&Thread_Critical); - if ((Thread_Events[0] = CreateEvent (NULL, TRUE, FALSE, NULL))) - { - if ((Thread_Events[1] = CreateEvent (NULL, TRUE, FALSE, NULL))) - { - if ((ThreadHandle = CreateThread (NULL, 0, ThreadLaunch, (LPVOID)this, 0, &ThreadID))) - { - HANDLE waiters[2] = { Messages[0].CompletionEvent, ThreadHandle }; - - if (WaitForMultipleObjects (2, waiters, FALSE, INFINITE) == WAIT_OBJECT_0+1) - { // Init failed, and the thread exited - DestroyThread (); - return false; - } -#if defined(_MSC_VER) && defined(_DEBUG) - // Give the thread a name in the debugger - struct - { - DWORD type; - LPCSTR name; - DWORD threadID; - DWORD flags; - } info = - { - 0x1000, ThreadName(), ThreadID, 0 - }; - __try - { - RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (ULONG_PTR *)&info ); - } - __except(EXCEPTION_CONTINUE_EXECUTION) - { - } -#endif - - return true; - } - CloseHandle (Thread_Events[1]); - } - CloseHandle (Thread_Events[0]); - } - DeleteCriticalSection (&Thread_Critical); - for (i = 0; i < MSG_QUEUE_SIZE; i++) - { - CloseHandle (Messages[i].CompletionEvent); - } - return false; -} - -//========================================================================== -// -// DestroyThread -// -//========================================================================== - -void FHelperThread::DestroyThread () -{ - int i; - - if (ThreadHandle == NULL) - return; - - SetEvent (Thread_Events[THREAD_KillSelf]); - // 5 seconds should be sufficient. If not, then we'll crash, but at - // least that's better than hanging indefinitely. - WaitForSingleObject (ThreadHandle, 5000); - CloseHandle (ThreadHandle); - - EnterCriticalSection (&Thread_Critical); - - for (i = 0; i < 8; i++) - { - CloseHandle (Messages[i].CompletionEvent); - } - CloseHandle (Thread_Events[0]); - CloseHandle (Thread_Events[1]); - - LeaveCriticalSection (&Thread_Critical); - DeleteCriticalSection (&Thread_Critical); - - ThreadHandle = NULL; -} - -//========================================================================== -// -// HaveThread -// -//========================================================================== - -bool FHelperThread::HaveThread () const -{ - return ThreadHandle != NULL; -} - -//========================================================================== -// -// SendMessage -// -//========================================================================== - -DWORD FHelperThread::SendMessage (DWORD method, - DWORD parm1, DWORD parm2, DWORD parm3, bool wait) -{ - for (;;) - { - EnterCriticalSection (&Thread_Critical); - if (MessageHead - MessageTail == MSG_QUEUE_SIZE) - { // No room, so wait for oldest message to complete - HANDLE waitEvent = Messages[MessageTail].CompletionEvent; - LeaveCriticalSection (&Thread_Critical); - WaitForSingleObject (waitEvent, 1000); - } - - int head = MessageHead++ % MSG_QUEUE_SIZE; - Messages[head].Method = method; - Messages[head].Parm1 = parm1; - Messages[head].Parm2 = parm2; - Messages[head].Parm3 = parm3; - ResetEvent (Messages[head].CompletionEvent); - LeaveCriticalSection (&Thread_Critical); - - SetEvent (Thread_Events[THREAD_NewMessage]); - - if (wait) - { - WaitForSingleObject (Messages[head].CompletionEvent, INFINITE); - return Messages[head].Return; - } - return 0; - } -} - -//========================================================================== -// -// ThreadLaunch (static) -// -//========================================================================== - -DWORD WINAPI FHelperThread::ThreadLaunch (LPVOID me) -{ - return ((FHelperThread *)me)->ThreadLoop (); -} - -//========================================================================== -// -// ThreadLoop -// -//========================================================================== - -DWORD FHelperThread::ThreadLoop () -{ - if (!Init ()) - { - ExitThread (0); - } - else - { - SetEvent (Messages[0].CompletionEvent); - } - - for (;;) - { - switch (MsgWaitForMultipleObjects (2, Thread_Events, - FALSE, INFINITE, QS_ALLEVENTS)) - { - case WAIT_OBJECT_0+1: - // We should quit now. - Deinit (); - ExitThread (0); - break; - - case WAIT_OBJECT_0: - // Process any new messages. MessageTail is not updated until *after* - // the message is finished processing. - for (;;) - { - EnterCriticalSection (&Thread_Critical); - if (MessageHead == MessageTail) - { - ResetEvent (Thread_Events[0]); - LeaveCriticalSection (&Thread_Critical); - break; // Resume outer for (Wait for more messages) - } - int spot = MessageTail % MSG_QUEUE_SIZE; - LeaveCriticalSection (&Thread_Critical); - - Messages[spot].Return = Dispatch (Messages[spot].Method, - Messages[spot].Parm1, Messages[spot].Parm2, - Messages[spot].Parm3); - - // No need to enter critical section, because only the CD thread - // is allowed to touch MessageTail or signal the CompletionEvent - SetEvent (Messages[spot].CompletionEvent); - MessageTail++; - } - break; - - default: - DefaultDispatch (); - } - } -} diff --git a/source/musicformats/win32/helperthread.h b/source/musicformats/win32/helperthread.h deleted file mode 100644 index 45ca9a7..0000000 --- a/source/musicformats/win32/helperthread.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -** helperthread.h -** -**--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#ifndef __HELPERTHREAD_H__ -#define __HELPERTHREAD_H__ - -#define WIN32_LEAN_AND_MEAN -#include - -class FHelperThread -{ - struct Message - { - DWORD Method; - DWORD Parm1, Parm2, Parm3; - HANDLE CompletionEvent; // Set to signalled when message is finished processing - DWORD Return; - }; - - enum { MSG_QUEUE_SIZE = 8 }; - -public: - FHelperThread (); - virtual ~FHelperThread (); - void DestroyThread (); - - bool LaunchThread (); - DWORD SendMessage (DWORD method, DWORD parm1, DWORD parm2, - DWORD parm3, bool wait); - bool HaveThread () const; - -protected: - enum EThreadEvents { THREAD_NewMessage, THREAD_KillSelf }; - virtual bool Init () { return true; } - virtual void Deinit () {} - virtual void DefaultDispatch () {} - virtual DWORD Dispatch (DWORD method, DWORD parm1=0, DWORD parm2=0, DWORD parm3=0) = 0; - virtual const char *ThreadName () = 0; - - HANDLE ThreadHandle; - DWORD ThreadID; - HANDLE Thread_Events[2]; - CRITICAL_SECTION Thread_Critical; - Message Messages[MSG_QUEUE_SIZE]; - DWORD MessageHead; - DWORD MessageTail; - -private: - void ReleaseSynchronizers (); - static DWORD WINAPI ThreadLaunch (LPVOID me); - - DWORD ThreadLoop (); -}; - -#endif //__HELPERTHREAD_H__ diff --git a/source/musicformats/win32/i_cd.cpp b/source/musicformats/win32/i_cd.cpp deleted file mode 100644 index 5c0f83d..0000000 --- a/source/musicformats/win32/i_cd.cpp +++ /dev/null @@ -1,762 +0,0 @@ -/* -** i_cd.cpp -** Functions for controlling CD playback -** -**--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include "zmusic_internal.h" -#include "helperthread.h" -#include "i_cd.h" - -enum -{ - CDM_Init, // parm1 = device - CDM_Close, - CDM_Play, // parm1 = track, parm2 = 1:looping - CDM_PlayCD, // parm1 = 1:looping - CDM_Replay, // Redos the most recent CDM_Play(CD) - CDM_Stop, - CDM_Eject, - CDM_UnEject, - CDM_Pause, - CDM_Resume, - CDM_GetMode, - CDM_CheckTrack, // parm1 = track - CDM_GetMediaIdentity, - CDM_GetMediaUPC -}; - -class FCDThread : public FHelperThread -{ -public: - FCDThread (); - -protected: - bool Init (); - void Deinit (); - const char *ThreadName (); - DWORD Dispatch (DWORD method, DWORD parm1=0, DWORD parm2=0, DWORD parm3=0); - void DefaultDispatch (); - - bool IsTrackAudio (DWORD track) const; - DWORD GetTrackLength (DWORD track) const; - DWORD GetNumTracks () const; - - static LRESULT CALLBACK CD_WndProc (HWND hWnd, UINT message, - WPARAM wParam, LPARAM lParam); - - WNDCLASS CD_WindowClass; - HWND CD_Window; - ATOM CD_WindowAtom; - - bool Looping; - DWORD PlayFrom; - DWORD PlayTo; - UINT DeviceID; -}; - -#define NOT_INITED ((signed)0x80000000) - -static FCDThread *CDThread; -static int Inited = NOT_INITED; -static int Enabled = false; - -//========================================================================== -// -// ---Constructor--- -// -//========================================================================== - -FCDThread::FCDThread () -{ - memset (&CD_WindowClass, 0, sizeof(CD_WindowClass)); - CD_Window = NULL; - CD_WindowAtom = 0; - Inited = NOT_INITED; - Looping = false; - PlayFrom = 0; - PlayTo = 0; - DeviceID = 0; - LaunchThread (); -} - -//========================================================================== -// -// ThreadName -// -//========================================================================== - -const char *FCDThread::ThreadName () -{ - return "CD Player"; -} - -//========================================================================== -// -// Init -// -//========================================================================== - -bool FCDThread::Init () -{ - CD_WindowClass.style = CS_NOCLOSE; - CD_WindowClass.lpfnWndProc = CD_WndProc; - CD_WindowClass.hInstance = GetModuleHandle(nullptr); - CD_WindowClass.lpszClassName = L"ZMusic CD Player"; - CD_WindowAtom = RegisterClass (&CD_WindowClass); - - if (CD_WindowAtom == 0) - return false; - - CD_Window = CreateWindow ( - (LPCTSTR)(INT_PTR)(int)CD_WindowAtom, - CD_WindowClass.lpszClassName, - 0, - 0, 0, 10, 10, - NULL, - NULL, - CD_WindowClass.hInstance, - NULL); - - if (CD_Window == NULL) - { - UnregisterClass ((LPCTSTR)(INT_PTR)(int)CD_WindowAtom, CD_WindowClass.hInstance); - CD_WindowAtom = 0; - return false; - } - -#ifdef _WIN64 - SetWindowLongPtr (CD_Window, GWLP_USERDATA, (LONG_PTR)this); -#else - SetWindowLong (CD_Window, GWL_USERDATA, (LONG)(LONG_PTR)this); -#endif - SetThreadPriority (ThreadHandle, THREAD_PRIORITY_LOWEST); - return true; -} - -//========================================================================== -// -// Deinit -// -//========================================================================== - -void FCDThread::Deinit () -{ - if (CD_Window) - { - DestroyWindow (CD_Window); - CD_Window = NULL; - } - if (CD_WindowAtom) - { - UnregisterClass ((LPCTSTR)(INT_PTR)(int)CD_WindowAtom, GetModuleHandle(nullptr)); - CD_WindowAtom = 0; - } - if (DeviceID) - { - Dispatch (CDM_Close); - } -} - -//========================================================================== -// -// DefaultDispatch -// -//========================================================================== - -void FCDThread::DefaultDispatch () -{ - MSG wndMsg; - - while (PeekMessage (&wndMsg, NULL, 0, 0, PM_REMOVE)) - { - DispatchMessage (&wndMsg); - } -} - -//========================================================================== -// -// Dispatch -// -// Does the actual work of implementing the public CD interface -// -//========================================================================== - -DWORD FCDThread::Dispatch (DWORD method, DWORD parm1, DWORD parm2, DWORD parm3) -{ - MCI_OPEN_PARMS mciOpen; - MCI_SET_PARMS mciSetParms; - MCI_PLAY_PARMS playParms; - MCI_STATUS_PARMS statusParms; - MCI_INFO_PARMS infoParms; - DWORD firstTrack, lastTrack, numTracks; - DWORD length; - DWORD openFlags; - wchar_t ident[32]; - - switch (method) - { - case CDM_Init: - mciOpen.lpstrDeviceType = (LPCWSTR)MCI_DEVTYPE_CD_AUDIO; - openFlags = MCI_OPEN_SHAREABLE|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_WAIT; - if ((signed)parm1 >= 0) - { - ident[0] = (char)(parm1 + 'A'); - ident[1] = ':'; - ident[2] = 0; - mciOpen.lpstrElementName = ident; - openFlags |= MCI_OPEN_ELEMENT; - } - - while (mciSendCommand (0, MCI_OPEN, openFlags, (DWORD_PTR)&mciOpen) != 0) - { - if (!(openFlags & MCI_OPEN_ELEMENT)) - { - return FALSE; - } - openFlags &= ~MCI_OPEN_ELEMENT; - } - - DeviceID = mciOpen.wDeviceID; - mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF; - if (mciSendCommand (DeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)&mciSetParms) == 0) - { - return TRUE; - } - - mciSendCommand (DeviceID, MCI_CLOSE, 0, 0); - return FALSE; - - case CDM_Close: - Dispatch (CDM_Stop); - mciSendCommand (DeviceID, MCI_CLOSE, 0, 0); - DeviceID = 0; - return 0; - - case CDM_Play: - if (!IsTrackAudio (parm1)) - { - //Printf ("Track %d is not audio\n", track); - return FALSE; - } - - length = GetTrackLength (parm1); - - if (length == 0) - { // Couldn't get length of track, so won't be able to play last track - PlayTo = MCI_MAKE_TMSF (parm1+1, 0, 0, 0); - } - else - { - PlayTo = MCI_MAKE_TMSF (parm1, - MCI_MSF_MINUTE(length), - MCI_MSF_SECOND(length), - MCI_MSF_FRAME(length)); - } - PlayFrom = MCI_MAKE_TMSF (parm1, 0, 0, 0); - Looping = parm2 & 1; - - // intentional fall-through - - case CDM_Replay: - playParms.dwFrom = PlayFrom; - playParms.dwTo = PlayTo; - playParms.dwCallback = (DWORD_PTR)CD_Window; - - return mciSendCommand (DeviceID, MCI_PLAY, MCI_FROM | MCI_TO | MCI_NOTIFY, - (DWORD_PTR)&playParms); - - case CDM_PlayCD: - numTracks = GetNumTracks (); - if (numTracks == 0) - return FALSE; - - for (firstTrack = 1; firstTrack <= numTracks && !IsTrackAudio (firstTrack); firstTrack++) - ; - for (lastTrack = firstTrack; lastTrack <= numTracks && IsTrackAudio (lastTrack); lastTrack++) - ; - - if (firstTrack > numTracks) - return FALSE; - if (lastTrack > numTracks) - lastTrack = numTracks; - - length = GetTrackLength (lastTrack); - if (length == 0) - return FALSE; - - Looping = parm1 & 1; - PlayFrom = MCI_MAKE_TMSF (firstTrack, 0, 0, 0); - PlayTo = MCI_MAKE_TMSF (lastTrack, - MCI_MSF_MINUTE(length), - MCI_MSF_SECOND(length), - MCI_MSF_FRAME(length)); - - playParms.dwFrom = PlayFrom; - playParms.dwTo = PlayTo; - playParms.dwCallback = (DWORD_PTR)CD_Window; - - return mciSendCommand (DeviceID, MCI_PLAY, MCI_FROM|MCI_TO|MCI_NOTIFY, - (DWORD_PTR)&playParms); - - case CDM_Stop: - return mciSendCommand (DeviceID, MCI_STOP, 0, 0); - - case CDM_Eject: - return mciSendCommand (DeviceID, MCI_SET, MCI_SET_DOOR_OPEN, 0); - - case CDM_UnEject: - return mciSendCommand (DeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, 0); - - case CDM_Pause: - return mciSendCommand (DeviceID, MCI_PAUSE, 0, 0); - - case CDM_Resume: - playParms.dwTo = PlayTo; - playParms.dwCallback = (DWORD_PTR)CD_Window; - return mciSendCommand (DeviceID, MCI_PLAY, MCI_TO | MCI_NOTIFY, (DWORD_PTR)&playParms); - - case CDM_GetMode: - statusParms.dwItem = MCI_STATUS_MODE; - if (mciSendCommand (DeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&statusParms)) - { - return CDMode_Unknown; - } - else - { - switch (statusParms.dwReturn) - { - case MCI_MODE_NOT_READY: return CDMode_NotReady; - case MCI_MODE_PAUSE: return CDMode_Pause; - case MCI_MODE_PLAY: return CDMode_Play; - case MCI_MODE_STOP: return CDMode_Stop; - case MCI_MODE_OPEN: return CDMode_Open; - default: return CDMode_Unknown; - } - } - - case CDM_CheckTrack: - return IsTrackAudio (parm1) ? TRUE : FALSE; - - case CDM_GetMediaIdentity: - case CDM_GetMediaUPC: - wchar_t ident[32]; - - infoParms.lpstrReturn = ident; - infoParms.dwRetSize = sizeof(ident); - if (mciSendCommand (DeviceID, MCI_INFO, - method == CDM_GetMediaIdentity ? MCI_WAIT|MCI_INFO_MEDIA_IDENTITY - : MCI_WAIT|MCI_INFO_MEDIA_UPC, (DWORD_PTR)&infoParms)) - { - return 0; - } - else - { - return wcstoul (ident, NULL, 0); - } - - default: - return 0; - } -} - -//========================================================================== -// -// KillThread -// -//========================================================================== - -static void KillThread () -{ - if (CDThread != NULL) - { - CDThread->DestroyThread (); - Inited = NOT_INITED; - delete CDThread; - } -} - -//========================================================================== -// -// CD_Init -// -//========================================================================== - -DLL_EXPORT zmusic_bool ZMusic_CD_Enable (const char *cd_drive) -{ - if (!cd_drive) - { - // lock the CD system. - Enabled = false; - ZMusic_CD_Close(); - return false; - } - Enabled = true; // this must have been called at least once to consider the use of the CD system - if ((cd_drive)[0] == 0 || (cd_drive)[1] != 0) - { - return CD_Init (-1); - } - else - { - char drive = toupper ((cd_drive)[0]); - - if (drive >= 'A' && drive <= 'Z' && !CD_Init(drive - 'A')) - { - return CD_Init(-1); - } - } - return true; -} - -bool CD_Init (int device) -{ - if (!Enabled) return false; - - if (CDThread == NULL) - { - CDThread = new FCDThread; - atexit (KillThread); - } - - if (Inited != device) - { - ZMusic_CD_Close (); - - if (CDThread->SendMessage (CDM_Init, device, 0, 0, true)) - { - Inited = device; - return true; - } - else - { - return false; - } - } - return true; -} - -//========================================================================== -// -// CD_InitID -// -//========================================================================== - -bool CD_InitID (unsigned int id, int guess) -{ - char drive; - - if (guess < 0 && Inited != NOT_INITED) - guess = Inited; - - if (guess >= 0 && CD_Init (guess)) - { - if (CDThread->SendMessage (CDM_GetMediaIdentity, 0, 0, 0, true) == id || - CDThread->SendMessage (CDM_GetMediaUPC, 0, 0, 0, true) == id) - { - return true; - } - ZMusic_CD_Close (); - } - - for (drive = 'V'; drive < 'Z'; drive++) - { - if (CD_Init (drive - 'A')) - { - // I don't know which value is stored in a CDDA file, so I try - // them both. All the CDs I've tested have had the same value - // for both, so it probably doesn't matter. - if (CDThread->SendMessage (CDM_GetMediaIdentity, 0, 0, 0, true) == id || - CDThread->SendMessage (CDM_GetMediaUPC, 0, 0, 0, true) == id) - { - return true; - } - ZMusic_CD_Close (); - } - } - return false; -} - -//========================================================================== -// -// ZMusic_CD_Close -// -//========================================================================== - -DLL_EXPORT void ZMusic_CD_Close () -{ - if (Inited != NOT_INITED) - { - CDThread->SendMessage (CDM_Close, 0, 0, 0, true); - Inited = NOT_INITED; - } -} - -//========================================================================== -// -// ZMusic_CD_Eject -// -//========================================================================== - -DLL_EXPORT void ZMusic_CD_Eject () -{ - if (Inited != NOT_INITED) - CDThread->SendMessage (CDM_Eject, 0, 0, 0, false); -} - -//========================================================================== -// -// ZMusic_CD_UnEject -// -//========================================================================== - -DLL_EXPORT zmusic_bool ZMusic_CD_UnEject () -{ - if (Inited == NOT_INITED) - return false; - - return CDThread->SendMessage (CDM_UnEject, 0, 0, 0, true) == 0; -} - -//========================================================================== -// -// ZMusic_CD_Stop -// -//========================================================================== - -DLL_EXPORT void ZMusic_CD_Stop () -{ - if (Inited != NOT_INITED) - CDThread->SendMessage (CDM_Stop, 0, 0, 0, false); -} - -//========================================================================== -// -// CD_Play -// -//========================================================================== - -bool CD_Play (int track, bool looping) -{ - if (Inited == NOT_INITED) - return false; - - return CDThread->SendMessage (CDM_Play, track, looping ? 1 : 0, 0, true) == 0; -} - -//========================================================================== -// -// CD_PlayNoWait -// -//========================================================================== - -void CD_PlayNoWait (int track, bool looping) -{ - if (Inited != NOT_INITED) - CDThread->SendMessage (CDM_Play, track, looping ? 1 : 0, 0, false); -} - -//========================================================================== -// -// CD_PlayCD -// -//========================================================================== - -bool CD_PlayCD (bool looping) -{ - if (Inited == NOT_INITED) - return false; - - return CDThread->SendMessage (CDM_PlayCD, looping ? 1 : 0, 0, 0, true) == 0; -} - -//========================================================================== -// -// CD_PlayCDNoWait -// -//========================================================================== - -void CD_PlayCDNoWait (bool looping) -{ - if (Inited != NOT_INITED) - CDThread->SendMessage (CDM_PlayCD, looping ? 1 : 0, 0, 0, false); -} - -//========================================================================== -// -// ZMusic_CD_Pause -// -//========================================================================== - -DLL_EXPORT void ZMusic_CD_Pause () -{ - if (Inited != NOT_INITED) - CDThread->SendMessage (CDM_Pause, 0, 0, 0, false); -} - -//========================================================================== -// -// ZMusic_CD_Resume -// -//========================================================================== - -DLL_EXPORT zmusic_bool ZMusic_CD_Resume () -{ - if (Inited == NOT_INITED) - return false; - - return CDThread->SendMessage (CDM_Resume, 0, 0, 0, false) == 0; -} - -//========================================================================== -// -// CD_GetMode -// -//========================================================================== - -ECDModes CD_GetMode () -{ - if (Inited == NOT_INITED) - return CDMode_Unknown; - - return (ECDModes)CDThread->SendMessage (CDM_GetMode, 0, 0, 0, true); -} - -//========================================================================== -// -// CD_CheckTrack -// -//========================================================================== - -bool CD_CheckTrack (int track) -{ - if (Inited == NOT_INITED) - return false; - - return CDThread->SendMessage (CDM_CheckTrack, track, 0, 0, true) != 0; -} - -// Functions called only by the helper thread ------------------------------- - -//========================================================================== -// -// IsTrackAudio -// -//========================================================================== - -bool FCDThread::IsTrackAudio (DWORD track) const -{ - MCI_STATUS_PARMS statusParms; - - statusParms.dwItem = MCI_CDA_STATUS_TYPE_TRACK; - statusParms.dwTrack = track; - if (mciSendCommand (DeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK, - (DWORD_PTR)&statusParms)) - { - return FALSE; - } - return statusParms.dwReturn == MCI_CDA_TRACK_AUDIO; -} - -//========================================================================== -// -// GetTrackLength -// -//========================================================================== - -DWORD FCDThread::GetTrackLength (DWORD track) const -{ - MCI_STATUS_PARMS statusParms; - - statusParms.dwItem = MCI_STATUS_LENGTH; - statusParms.dwTrack = track; - if (mciSendCommand (DeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK, - (DWORD_PTR)&statusParms)) - { - return 0; - } - else - { - return (DWORD)statusParms.dwReturn; - } -} - -//========================================================================== -// -// GetNumTracks -// -//========================================================================== - -DWORD FCDThread::GetNumTracks () const -{ - MCI_STATUS_PARMS statusParms; - - statusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; - if (mciSendCommand (DeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&statusParms)) - { - return 0; - } - else - { - return (DWORD)statusParms.dwReturn; - } -} - -//========================================================================== -// -// CD_WndProc (static) -// -// Because MCI (under Win 9x anyway) can't notify windows owned by another -// thread, the helper thread creates its own window. -// -//========================================================================== - -LRESULT CALLBACK FCDThread::CD_WndProc (HWND hWnd, UINT message, - WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case MM_MCINOTIFY: - if (wParam == MCI_NOTIFY_SUCCESSFUL) - { - FCDThread *self = (FCDThread *)(LONG_PTR)GetWindowLongPtr (hWnd, GWLP_USERDATA); - // Using SendMessage could deadlock, so don't do that. - self->Dispatch (self->Looping ? CDM_Replay : CDM_Stop); - } - return 0; - - default: - return DefWindowProc (hWnd, message, wParam, lParam); - } -} diff --git a/source/musicformats/win32/i_cd.h b/source/musicformats/win32/i_cd.h deleted file mode 100644 index 6640d10..0000000 --- a/source/musicformats/win32/i_cd.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -** i_cd.h -** Defines the CD interface -** -**--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#ifndef __I_CD_H__ -#define __I_CD_H__ - -enum ECDModes -{ - CDMode_Unknown, - CDMode_NotReady, - CDMode_Pause, - CDMode_Play, - CDMode_Stop, - CDMode_Open -}; - -// Opens a CD device. If device is non-negative, it specifies which device -// to open. 0 is drive A:, 1 is drive B:, etc. If device is not specified, -// the user's preference is used to decide which device to open. -bool CD_Init (int device = -1); - -// Open a CD device containing a specific CD. Tries device guess first. -bool CD_InitID (unsigned int id, int guess=-1); - -// Plays a single track, possibly looping -bool CD_Play (int track, bool looping); - -// Plays the first block of audio tracks on a CD, possibly looping -bool CD_PlayCD (bool looping); - -// Versions of the above that return as soon as possible -void CD_PlayNoWait (int track, bool looping); -void CD_PlayCDNoWait (bool looping); - -// Get the CD drive's status (mode) -ECDModes CD_GetMode (); - -// Check if a track exists and is audio -bool CD_CheckTrack (int track); - -#endif //__I_CD_H__ diff --git a/source/zmusic/zmusic.cpp b/source/zmusic/zmusic.cpp index b7653ae..57834b1 100644 --- a/source/zmusic/zmusic.cpp +++ b/source/zmusic/zmusic.cpp @@ -63,8 +63,6 @@ class MusInfo; MusInfo *OpenStreamSong(StreamSource *source); const char *GME_CheckFormat(uint32_t header); -MusInfo* CDDA_OpenSong(MusicIO::FileInterface* reader); -MusInfo* CD_OpenSong(int track, int id); MusInfo* CreateMIDIStreamer(MIDISource *source, EZMusicMidiDevice devtype, const char* args); //========================================================================== @@ -225,13 +223,6 @@ static MusInfo *ZMusic_OpenSongInternal (MusicIO::FileInterface *reader, EZMusi info = CreateMIDIStreamer(source, device, Args? Args : ""); } - // Check for CDDA "format" - else if ((id[0] == MAKE_ID('R', 'I', 'F', 'F') && id[2] == MAKE_ID('C', 'D', 'D', 'A'))) - { - // This is a CDDA file - info = CDDA_OpenSong(reader); - } - // Check for various raw OPL formats else { @@ -336,26 +327,6 @@ DLL_EXPORT ZMusic_MusicStream ZMusic_OpenSong(ZMusicCustomReader* reader, EZMusi } -//========================================================================== -// -// play CD music -// -//========================================================================== - -DLL_EXPORT MusInfo *ZMusic_OpenCDSong (int track, int id) -{ - MusInfo *info = CD_OpenSong (track, id); - - if (info && !info->IsValid ()) - { - delete info; - info = nullptr; - SetError("Unable to open CD Audio"); - } - - return info; -} - //========================================================================== // // streaming callback