home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of Windows 95.com 1996 September
/
WIN95_09964.iso
/
sound
/
mpw32-5s.zip
/
MP2WIN.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-31
|
38KB
|
1,449 lines
#define STRICT
#define WIN32_LEAN_AND_MEAN
#define NOMCX
#define NOIME
// #define NOGDI
// #define NOUSER
#define NOSOUND
#define NOCOMM
#define NODRIVERS
#define OEMRESOURCE
#define NONLS
#define NOSERVICE
#define NOKANJI
#define NOMINMAX
#define NOLOGERROR
#define NOPROFILER
#define NOMEMMGR
#define NOLFILEIO
#define NOOPENFILE
//#define NORESOURCE
#define NOATOM
#define NOLANGUAGE
//#define NOLSTRING
#define NODBCS
#define NOKEYBOARDINFO
#define NOGDICAPMASKS
#define NOCOLOR
#define NOGDIOBJ
#define NODRAWTEXT
#define NOTEXTMETRIC
#define NOSCALABLEFONT
//#define NOBITMAP
#define NORASTEROPS
#define NOMETAFILE
#define NOSYSMETRICS
#define NOSYSTEMPARAMSINFO
// #define NOMSG
//#define NOWINSTYLES
#define NOWINOFFSETS
#define NOSHOWWINDOW
#define NODEFERWINDOWPOS
#define NOVIRTUALKEYCODES
#define NOKEYSTATES
#define NOWH
//#define NOMENUS
//#define NOSCROLL
#define NOCLIPBOARD
//#define NOICONS
//#define NOMB
#define NOSYSCOMMANDS
#define NOMDI
//#define NOCTLMGR
//#define NOWINMESSAGES
#define NOHELP
//#define _WINUSER_
#define __oleidl_h__
#define _OLE2_H_
#include <windows.h>
#include <mmsystem.h>
#include "commctrl.h"
#include <commdlg.h>
#include <stdlib.h>
#include "crc.h"
#include "ibitstr.h"
#include "header.h"
#include "mp2win.h"
#include "args.h"
#include <fstream.h>
#include "subband.h"
#define _export
#define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
#define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
#define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
/* Interface for maplay written by Jeff Tsay. E-mail address:
ctsay@pasteur.eecs.berkeley.edu. Basic sound file player with
file open, command line capability, pause, stop, and MPEG
properties. Also added play list and seeking functionality. Uses
threads, so will NOT work on Win32s! */
/* Adapted from the Sounder sample application distributed on the
Borland C++ CD */
// Argument containers
DWORD maplay(MPEG_Args *);
DWORD mciplay(MCI_Args *);
// data initialized by first instance
typedef struct tagSETUPDATA
{
char szAppName[20]; // name of application
} SETUPDATA;
SETUPDATA SetUpData;
// Data that can be referenced throughout the
// program but not passed to other instances
char szName[256]; // Name of sound file
char FileTitle[256];
char TitleText[64];
char command[384]; // MCI command string
char scratch[64];
char Buffer[1024]; // MCI response string
char *PlayList[256];
OPENFILENAME ofnTemp;
LPSTR szTemp = "MPEG Audio Files (*.mp*)\0*.mp*\0WAV Files \
(*.wav)\0*.wav\0MIDI Files \ (*.mid)\0*.mid\0Playlists (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
int Cur_Index;
int Max_Index;
int scroll_range=0;
// int predecode=0; // not implemented yet
BOOL ListMode = FALSE;
BOOL MPEG = FALSE;
BOOL Repeat = FALSE;
BOOL CMDLINE = FALSE;
BOOL paused = FALSE;
BOOL can_play = FALSE;
BOOL can_pause = FALSE;
BOOL can_stop = FALSE;
BOOL playing = FALSE;
BOOL scrolling = FALSE;
enum e_channels mode=both;
HWAVEOUT *phwo=new HWAVEOUT;
HANDLE MPEG_Thread=NULL;
HANDLE MCI_Thread=NULL;
MPEG_Args *maplay_args=new MPEG_Args();
MCI_Args *mci_args = new MCI_Args();
Args* args;
DWORD dwThreadId;
HINSTANCE hInst; // hInstance of application
HWND hWnd; // hWnd of main window
// Buttons
HWND openbut, playbut, pausebut, stopbut, aboutbut;
HWND rewbut, ffbut, prevbut, repbut, nextbut;
// Track bar
int line_size;
HWND tracker;
// Status bar
int panes[4]= {54, 200, 244, -1};
char playlist_filename[64];
HWND status_bar;
// Menu
HMENU mainmenu;
HDC hdc;
DRAWITEMSTRUCT *dis;
// Function prototypes
int PASCAL WinMain(HINSTANCE,HINSTANCE,LPSTR,int);
void InitSound(HINSTANCE,HINSTANCE,LPSTR,int);
void InitSoundFirst(HINSTANCE);
void InitSoundEvery(HINSTANCE,int);
// Helper procedures
BOOL AppFileOpen();
void clear_sound();
void ok_play();
void no_play();
void no_stop();
BOOL reinit_MPEG();
BOOL reinit_MCI();
BOOL WaveP(LPSTR);
BOOL ListP(LPSTR);
LPSTR Proper_Filename(LPSTR s);
void DisplayName(LPSTR);
BOOL MPEG_play();
BOOL MCI_play();
BOOL Get_File_List(LPSTR);
BOOL File_Init();
void Next_Song();
void Init_List();
void no_list();
char *time_string(int ms, char *dest);
void update_timewin(int num);
// Menu procedures
void file_open();
void audio_play();
void audio_pause();
void audio_stop();
void audio_properties();
void gotop_List(int n);
void about();
void leave();
// Procedures for options dialog box
void leave_options(HWND hDlg);
LRESULT APIENTRY SounderWndProc(HWND,UINT,WPARAM,LPARAM);
BOOL WINAPI Options(HWND hDlg, UINT message, WPARAM wParam,
LPARAM lParam);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int cmdShow)
{
MSG msg;
// Go init this application.
InitSound(hInstance, hPrevInstance,
lpszCmdLine, cmdShow);
if (lstrlen(lpszCmdLine)>1) {
CMDLINE=TRUE;
if (WaveP(lpszCmdLine))
PostMessage(hWnd, WM_CMDLINEFILE, 0,
(LPARAM) lpszCmdLine);
else
PostMessage(hWnd, WM_CMDLINEFILE, 1,
(LPARAM) lpszCmdLine);
}
// Get and dispatch messages for this applicaton.
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(msg.wParam);
}
//*******************************************************************
// InitSound - init the Sound application
//
// paramaters:
// hInstance - The instance of this instance of this
// application.
// hPrevInstance - The instance of the previous instance
// of this application. This will be 0
// if this is the first instance.
// lpszCmdLine - A long pointer to the command line that
// started this application.
// cmdShow - Indicates how the window is to be shown
// initially. ie. SW_SHOWNORMAL, SW_HIDE,
// SW_MIMIMIZE.
//
//*******************************************************************
#pragma argsused
void InitSound(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int cmdShow)
{
InitSoundFirst(hInstance);
InitSoundEvery(hInstance, cmdShow); // initialization for all instances
}
//*******************************************************************
// InitSoundFirst - done only for first instance of Sounder
//
// paramaters:
// hInstance - The instance of this instance of this
// application.
//
//*******************************************************************
void InitSoundFirst(HINSTANCE hInstance)
{
WNDCLASS wcSoundClass;
// Get string from resource with application name.
LoadString(hInstance, IDS_NAME, (LPSTR) SetUpData.szAppName, 20);
// Define the window class for this application.
wcSoundClass.lpszClassName = SetUpData.szAppName;
wcSoundClass.hInstance = hInstance;
wcSoundClass.lpfnWndProc = SounderWndProc;
wcSoundClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wcSoundClass.hIcon = LoadIcon(hInstance,
MAKEINTRESOURCE(ICON_2));
wcSoundClass.lpszMenuName = MAKEINTRESOURCE(MENU_1);
wcSoundClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wcSoundClass.style = CS_HREDRAW | CS_VREDRAW;
wcSoundClass.cbClsExtra = 0;
wcSoundClass.cbWndExtra = 0;
// Register the class
RegisterClass(&wcSoundClass);
}
//*******************************************************************
// InitSoundEvery - done for every instance of Sound
//
// parameters:
// hInstance - The instance of this instance of this
// application.
// cmdShow - Indicates how the window is to be shown
// initially. ie. SW_SHOWNORMAL, SW_HIDE,
// SW_MIMIMIZE.
//
//*******************************************************************
void InitSoundEvery(HINSTANCE hInstance, int cmdShow)
{
int i;
for(i=0; i<256; i++)
PlayList[i]=NULL;
Cur_Index=0;
Max_Index=0;
hInst = hInstance; // save for use by window procs
InitCommonControls();
// Create applications main window.
hWnd = CreateWindow(
SetUpData.szAppName, // window class name
SetUpData.szAppName, // window title
WS_OVERLAPPED | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU |
WS_THICKFRAME, // type of window
100, // x window location
100, // y
283, // cx and size
135, // cy
NULL, // no parent for this window
NULL, // use the main menu
hInstance, // who created this window
NULL // no parms to pass on
);
// Update display of main window.
mainmenu=GetMenu(hWnd);
ShowWindow(hWnd, cmdShow);
UpdateWindow(hWnd);
/*
Note the initialization method of the above string. The GetOpenFileName()
function expects to find a string in the OPENFILENAME structure that has
a '\0' terminator between strings and an extra '\0' that terminates the
entire filter data set. Using the technique shown below will fail because
"X" is really 'X' '\0' '\0' '\0' in memory. When the GetOpenFileName()
function scans szTemp it will stop after finding the extra trailing '\0'
characters.
char szTemp[][4] = { "X", "*.*", "ABC", "*.*", "" };
The string should be "X\0*.*\0ABC\0*.*\0".
Remember that in C or C++ a quoted string is automatically terminated with
a '\0' character so char "X\0"; would result in 'X' '\0' '\0' which
provides the extra '\0' that GetOpenFileName() needs to see in order to
terminate the scan of the string. Just 'char ch "X";' would result in 'X'
'\0' and GetOpenFileName() would wander off in memory until it lucked into
a '\0' '\0' character sequence.
*/
/*
Some Windows structures require the size of themselves in an effort to
provide backward compatibility with future versions of Windows. If the
lStructSize member is not set the call to GetOpenFileName() will fail.
*/
ofnTemp.lStructSize = sizeof( OPENFILENAME );
ofnTemp.hwndOwner = hWnd; // An invalid hWnd causes non-modality
ofnTemp.hInstance = 0;
ofnTemp.lpstrFilter = (LPSTR)szTemp; // See previous note concerning string
ofnTemp.lpstrCustomFilter = NULL;
ofnTemp.nMaxCustFilter = 0;
ofnTemp.nFilterIndex = 1;
ofnTemp.lpstrFile = (LPSTR)szName; // Stores the result in this variable
ofnTemp.nMaxFile = sizeof( szName );
ofnTemp.lpstrFileTitle = FileTitle;
ofnTemp.nMaxFileTitle = sizeof(FileTitle);
ofnTemp.lpstrInitialDir = NULL;
ofnTemp.lpstrTitle = "Open Sound File"; // Title for dialog
ofnTemp.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
ofnTemp.nFileOffset = 0;
ofnTemp.nFileExtension = 0;
ofnTemp.lpstrDefExt = "MP2";
ofnTemp.lCustData = 0L;
ofnTemp.lpfnHook = NULL;
ofnTemp.lpTemplateName = NULL;
}
BOOL AppFileOpen()
{
DWORD Errval;
/*
If the call to GetOpenFileName() fails you can call CommDlgExtendedError()
to retrieve the type of error that occured.
*/
if(!GetOpenFileName( (LPOPENFILENAME) &ofnTemp ))
{
Errval=CommDlgExtendedError();
if(Errval!=0) // 0 value means user selected Cancel
{
MessageBox(hWnd,"Could not open file.","WARNING",MB_OK|MB_ICONSTOP);
}
return(FALSE);
}
return(TRUE);
}
char *time_string(int ms, char *dest)
{
int i, j, nmlength;
int seconds, minutes;
char second_str[4];
char minute_str[4];
minutes = ms / 60000;
seconds = ms / 1000 - minutes * 60;
itoa(minutes, minute_str, 10);
itoa(seconds, second_str, 10);
nmlength = 3 - lstrlen(minute_str);
for (i=0; i < nmlength ; i++)
dest[i] = '0';
for (i = nmlength, j=0; i<3; i++, j++)
dest[i] = minute_str[j];
dest[3] = ':';
nmlength = 6 - lstrlen(second_str);
for (i=4; i < nmlength ; i++)
dest[i] = '0';
for (i=nmlength, j=0; i<6; i++, j++)
dest[i] = second_str[j];
dest[6]='\0';
return (dest);
}
void clear_sound()
{
scrolling = FALSE;
if (MPEG) {
if (MPEG_Thread) {
TerminateThread(MPEG_Thread,0L);
CloseHandle(MPEG_Thread);
MPEG_Thread=NULL;
}
waveOutReset(*phwo);
waveOutClose(*phwo);
if (maplay_args->stream) {
delete maplay_args->stream;
maplay_args->stream = NULL;
delete maplay_args->MPEGheader;
maplay_args->MPEGheader = NULL;
delete maplay_args->crc;
maplay_args->crc = NULL;
}
} else {
if (MCI_Thread) {
TerminateThread(MCI_Thread, 0L);
CloseHandle(MCI_Thread);
MCI_Thread = NULL;
}
mciSendString ((LPSTR)"stop sounder", NULL, 0, NULL);
mciSendString ((LPSTR)"close sounder", NULL, 0, NULL);
}
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Stopped");
SendMessage(status_bar, SB_SETTEXT, 2, (WPARAM) "000:00");
return;
}
void ok_play()
{
can_play=TRUE;
can_pause=FALSE;
playing=FALSE;
EnableMenuItem(mainmenu,CM_AUDIOPLAY, MF_ENABLED);
EnableWindow(playbut, TRUE);
EnableMenuItem(mainmenu,CM_AUDIOPAUSE, MF_GRAYED);
EnableWindow(pausebut, FALSE);
return;
}
void no_play()
{
can_play=FALSE;
can_pause=TRUE;
can_stop=TRUE;
playing=TRUE;
EnableMenuItem(mainmenu,CM_AUDIOPLAY, MF_GRAYED);
EnableWindow(playbut, FALSE);
EnableMenuItem(mainmenu,CM_AUDIOPAUSE, MF_ENABLED);
EnableWindow(pausebut, TRUE);
EnableMenuItem(mainmenu,CM_AUDIOSTOP, MF_ENABLED);
EnableWindow(stopbut, TRUE);
return;
}
void no_stop()
{
can_stop=FALSE;
EnableMenuItem(mainmenu,CM_AUDIOSTOP, MF_GRAYED);
EnableWindow(stopbut, FALSE);
return;
}
BOOL reinit_MPEG()
{
MPEG = TRUE;
args = maplay_args;
maplay_args->stream= new Ibitstream(szName, hWnd);
maplay_args->MPEGheader= new Header;
maplay_args->crc = new Crc16;
maplay_args->phwo=phwo;
maplay_args->hWnd=hWnd;
maplay_args->which_c=mode;
maplay_args->position_change = FALSE;
if (!maplay_args->MPEGheader->read_header (maplay_args->stream,
&maplay_args->crc)) {
MessageBox(hWnd, "No header found!",
"File format error", MB_OK|MB_ICONSTOP);
return(FALSE);
}
scroll_range = maplay_args->MPEGheader->min_number_of_frames(maplay_args->stream);
line_size = scroll_range >> 3;
SendMessage(tracker, TBM_SETRANGEMIN, FALSE, 0);
SendMessage(tracker, TBM_SETRANGEMAX, FALSE, scroll_range);
SendMessage(tracker, TBM_SETPOS, TRUE, 0);
SendMessage(tracker, TBM_SETTICFREQ, scroll_range>>4, 1);
SendMessage(tracker, TBM_SETLINESIZE, 0, line_size);
EnableMenuItem(mainmenu,CM_AUDIOPROPERTIES, MF_ENABLED);
EnableMenuItem(mainmenu,CM_OPTIONS, MF_ENABLED);
EnableWindow(tracker, TRUE);
return(TRUE);
}
BOOL reinit_MCI()
{
MPEG=FALSE;
EnableMenuItem(mainmenu,CM_AUDIOPROPERTIES, MF_GRAYED);
EnableMenuItem(mainmenu,CM_OPTIONS, MF_GRAYED);
lstrcpy(command, "open ");
lstrcat(command, szName);
lstrcat(command, " alias sounder wait");
mciSendString ((LPSTR)command, Buffer, 1024, NULL);
mciSendString("set sounder time format ms wait", Buffer, 1024, NULL);
mciSendString("status sounder length wait", Buffer, 1024, NULL);
scroll_range = atoi(Buffer);
line_size = scroll_range >> 3;
args = mci_args;
mci_args->playing = FALSE;
mci_args->position_change = FALSE;
mci_args->desired_position = 0;
mci_args->hWnd = hWnd;
SendMessage(tracker, TBM_SETRANGEMIN, FALSE, 0);
SendMessage(tracker, TBM_SETRANGEMAX, FALSE, scroll_range);
SendMessage(tracker, TBM_SETPOS, TRUE, 0);
SendMessage(tracker, TBM_SETTICFREQ, scroll_range>>4, 1);
SendMessage(tracker, TBM_SETLINESIZE, 0, line_size);
EnableWindow(tracker, TRUE);
return (TRUE);
}
BOOL WaveP(LPSTR t)
// Check if the file is a format the Windows multimedia system supports.
{
return ((lstrcmp(t + lstrlen(t)-3, "WAV")==0) ||
(lstrcmp(t + lstrlen(t)-3, "wav")==0) ||
(lstrcmp(t + lstrlen(t)-3, "MID")==0) ||
(lstrcmp(t + lstrlen(t)-3, "mid")==0));
}
BOOL ListP(LPSTR t)
{
return ((lstrcmp(t + lstrlen(t)-3, "TXT")==0) ||
(lstrcmp(t + lstrlen(t)-3, "txt")==0));
}
LPSTR Proper_Filename(LPSTR s)
{
int i;
int length=lstrlen(s);
for(i=length; i>=0; --i)
if (s[i]=='\\')
return (s+i+1);
return(s);
}
void DisplayName(LPSTR name)
{
LoadString(hInst, IDS_NAME, (LPSTR) TitleText, 64);
lstrcat(TitleText, " - [");
if (name)
lstrcat(TitleText, Proper_Filename(name));
else
lstrcat(TitleText, FileTitle);
lstrcat(TitleText, "]");
SetWindowText(hWnd, (LPCTSTR) TitleText);
return;
}
BOOL MPEG_play()
// Assumes stream, MPEGheader, crc are already initialized
{
BOOL t;
MPEG_Thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) maplay,
maplay_args,0,&dwThreadId);
t=SetThreadPriority(MPEG_Thread, THREAD_PRIORITY_ABOVE_NORMAL);
return(t);
}
BOOL MCI_play()
{
mci_args->playing = TRUE;
mciSendString ((LPSTR)"play sounder notify", Buffer, 1024, hWnd);
MCI_Thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) mciplay,
mci_args, 0, &dwThreadId);
return(TRUE);
}
BOOL Get_File_List(LPSTR listname)
{
ifstream f((const char *) listname);
Max_Index=0;
while(!(f.bad() || f.eof() || f.fail() || Max_Index>255)) {
if (PlayList[Max_Index]) {
delete PlayList[Max_Index];
}
PlayList[Max_Index]=new char [256];
f.getline(PlayList[Max_Index], 256, '\n');
if ((lstrlen(PlayList[Max_Index])>1) &&
(GetFileAttributes(PlayList[Max_Index])!=0xFFFFFFFF))
Max_Index++;
}
f.close();
lstrcpy(playlist_filename, "Track 1: ");
lstrcat(playlist_filename, Proper_Filename(PlayList[0]));
SendMessage(status_bar,SB_SETTEXT, 1,(LPARAM) playlist_filename);
return(TRUE);
}
BOOL File_Init()
{
return (WaveP(szName) ? reinit_MCI() : reinit_MPEG());
}
void Next_Song()
{
if (++Cur_Index<Max_Index) {
lstrcpy(szName, PlayList[Cur_Index]);
if (File_Init()) {
ok_play();
no_stop();
lstrcpy(playlist_filename, "Track ");
lstrcat(playlist_filename, itoa(Cur_Index + 1, scratch, 10));
lstrcat(playlist_filename, ": ");
lstrcat(playlist_filename, Proper_Filename(szName));
SendMessage(status_bar,SB_SETTEXT, 1,(LPARAM) playlist_filename);
audio_play();
}
} else {
if (CMDLINE)
leave();
lstrcpy(playlist_filename, "Track 1: ");
lstrcat(playlist_filename, Proper_Filename(PlayList[0]));
SendMessage(status_bar,SB_SETTEXT, 1,(LPARAM) playlist_filename);
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Ready");
Cur_Index = 0;
lstrcpy(szName, PlayList[0]);
if (File_Init()) {
ok_play();
no_stop();
if (Repeat)
audio_play();
}
}
return;
}
void Init_List()
{
ListMode=TRUE;
EnableMenuItem(mainmenu,CM_LISTPREV, MF_ENABLED);
EnableWindow(prevbut, TRUE);
EnableMenuItem(mainmenu,CM_LISTREPEAT, MF_ENABLED);
EnableWindow(repbut, TRUE);
EnableMenuItem(mainmenu,CM_LISTNEXT, MF_ENABLED);
EnableWindow(nextbut, TRUE);
return;
}
void gotop_List(int n)
{
CMDLINE=FALSE;
clear_sound();
Cur_Index+=n;
if (Cur_Index>=Max_Index)
Cur_Index-=Max_Index;
else if (Cur_Index<-1)
Cur_Index+=Max_Index;
Next_Song();
}
void no_list()
{
int i;
ListMode=FALSE;
EnableMenuItem(mainmenu,CM_LISTPREV, MF_GRAYED);
EnableWindow(prevbut, FALSE);
EnableMenuItem(mainmenu,CM_LISTREPEAT, MF_GRAYED);
EnableWindow(repbut, FALSE);
EnableMenuItem(mainmenu,CM_LISTNEXT, MF_GRAYED);
EnableWindow(nextbut, FALSE);
SendMessage(status_bar,SB_SETTEXT, 1, NULL);
for(i=0; i<Max_Index; i++)
delete PlayList[i];
Cur_Index=0;
Max_Index=0;
}
void update_timewin(int num)
{
if (MPEG)
SendMessage(status_bar, SB_SETTEXT, 2,
(LPARAM) time_string((int) (num * maplay_args->MPEGheader->ms_per_frame()),
scratch));
else
SendMessage(status_bar, SB_SETTEXT, 2,
(LPARAM) time_string(num, scratch));
return;
}
void file_open()
{
CMDLINE=FALSE;
if (AppFileOpen()) {
clear_sound();
ListMode=FALSE;
if (ListP(szName)) {
Init_List();
Get_File_List(szName);
lstrcpy(szName, PlayList[0]);
} else
no_list();
if (!File_Init())
return;
ok_play();
no_stop();
EnableMenuItem(mainmenu,CM_AUDIOREPEAT, MF_ENABLED);
DisplayName(NULL);
EnableWindow(rewbut, TRUE);
EnableMenuItem(mainmenu, CM_AUDIOREWIND, MF_ENABLED);
EnableWindow(ffbut, TRUE);
EnableMenuItem(mainmenu, CM_AUDIOFAST_FORWARD, MF_ENABLED);
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Ready");
SendMessage(status_bar, SB_SETTEXT, 2, (WPARAM) "000:00");
}
return;
}
void leave()
{
clear_sound();
delete maplay_args;
delete mci_args;
delete phwo;
DestroyWindow(hWnd);
return;
}
void audio_play()
{
if (can_play) {
no_play();
if (MPEG) {
if (paused && MPEG_Thread!=NULL) {
paused=FALSE;
waveOutRestart(*phwo);
ResumeThread(MPEG_Thread);
} else
MPEG_play();
} else {
MCI_play();
}
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Playing...");
}
return;
}
void audio_pause()
{
paused=TRUE;
CMDLINE=FALSE;
if (MPEG) {
SuspendThread(MPEG_Thread);
waveOutPause(*phwo);
} else {
mci_args->playing = FALSE;
mciSendString ((LPSTR)"pause sounder", NULL, 0, NULL);
}
ok_play();
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Paused");
return;
}
void audio_stop()
{
paused=FALSE;
CMDLINE=FALSE;
clear_sound();
File_Init();
ok_play();
no_stop();
return;
}
void audio_properties ()
{
char MPEGinfo[1024];
lstrcpy(MPEGinfo, "Layer : ");
lstrcat(MPEGinfo, maplay_args->MPEGheader->layer_string());
lstrcat(MPEGinfo, "Checksums? : ");
lstrcat(MPEGinfo, maplay_args->MPEGheader->checksums() ?
"Yes" : "No");
lstrcat(MPEGinfo, "\nMode : ");
lstrcat(MPEGinfo, maplay_args->MPEGheader->mode_string());
lstrcat(MPEGinfo, "Original? : ");
lstrcat(MPEGinfo, maplay_args->MPEGheader->original() ?
"Yes" : "No");
lstrcat(MPEGinfo, "\nSample Frequency : ");
lstrcat(MPEGinfo, maplay_args->MPEGheader->sample_frequency_string ());
lstrcat(MPEGinfo, "Copyright? : ");
lstrcat(MPEGinfo, maplay_args->MPEGheader->copyright() ?
"Yes" : "No");
lstrcat(MPEGinfo, "\nBitrate: ");
lstrcat(MPEGinfo, maplay_args->MPEGheader->bitrate_string());
lstrcat(MPEGinfo, "\n\nFrames : ");
lstrcat(MPEGinfo, itoa(scroll_range, scratch, 10));
lstrcat(MPEGinfo, "\nFile Size : ");
lstrcat(MPEGinfo, itoa(maplay_args->stream->file_size() >> 10,
scratch, 10));
lstrcat(MPEGinfo, " KB");
MessageBox(hWnd, MPEGinfo, "MPEG Properties",
MB_OK | MB_ICONINFORMATION );
}
void about()
{
MessageBox(hWnd,
"maplay 1.2+ for Win32 version 1.70 (08/01/96) - Pentium build.\n\n \
A Full Quality MPEG Audio \
Layer 1 and 2 Decoder for Windows 95 and NT.\n\nCopyright (C) 1993, 1994 \
Tobias Bading (bading@cs.tu-berlin.de)\nBerlin University of Technology \
\nCreated: 6/23/94 14:12:46\n\nInterface and Win32 port by Jeff \
Tsay (ctsay@pasteur.eecs.berkeley.edu).\n\nThis program is free software. \
See the GNU General Public License in the \nfile COPYING for more details.",
"About maplay 1.2+ for Win32", MB_OK);
return;
}
#pragma argsused
LRESULT APIENTRY SounderWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
BOOL disabled, selected;
int new_pos;
switch (message)
{
case WM_CREATE:
openbut= CreateWindow ("BUTTON", NULL,
WS_CHILD| WS_VISIBLE | WS_TABSTOP |
BS_OWNERDRAW | BS_PUSHBUTTON,
5, 5, 24, 24,
hWnd, (HMENU)CM_FILEOPEN, hInst, NULL);
playbut= CreateWindow ("BUTTON", NULL,
WS_CHILD | WS_VISIBLE | WS_DISABLED |
WS_TABSTOP | BS_OWNERDRAW | BS_PUSHBUTTON,
45, 5, 24, 24,
hWnd, (HMENU)CM_AUDIOPLAY, hInst,
NULL);
pausebut= CreateWindow ("BUTTON", NULL,
WS_CHILD| WS_VISIBLE| WS_DISABLED |
WS_TABSTOP | BS_OWNERDRAW | BS_PUSHBUTTON,
69, 5, 24, 24,
hWnd, (HMENU)CM_AUDIOPAUSE, hInst, NULL);
stopbut= CreateWindow ("BUTTON", NULL,
WS_CHILD| WS_VISIBLE | WS_DISABLED |
WS_TABSTOP | BS_OWNERDRAW | BS_PUSHBUTTON,
93, 5, 24, 24,
hWnd, (HMENU)CM_AUDIOSTOP, hInst, NULL);
rewbut= CreateWindow ("BUTTON", NULL,
WS_CHILD| WS_VISIBLE | WS_DISABLED |
WS_TABSTOP | BS_PUSHBUTTON | BS_OWNERDRAW,
157, 5, 24, 24,
hWnd, (HMENU)CM_AUDIOREWIND, hInst, NULL);
/* repbut= CreateWindow ("BUTTON", NULL,
WS_CHILD| WS_VISIBLE | WS_DISABLED |
WS_TABSTOP | BS_PUSHBUTTON | BS_OWNERDRAW,
157, 5, 24, 24,
hWnd, (HMENU)CM_LISTREPEAT, hInst, NULL); */
ffbut= CreateWindow ("BUTTON", NULL,
WS_CHILD| WS_VISIBLE | WS_DISABLED |
WS_TABSTOP | BS_PUSHBUTTON | BS_OWNERDRAW,
181, 5, 24, 24,
hWnd, (HMENU)CM_AUDIOFAST_FORWARD, hInst, NULL);
prevbut= CreateWindow ("BUTTON", NULL,
WS_CHILD| WS_VISIBLE | WS_DISABLED |
WS_TABSTOP | BS_PUSHBUTTON | BS_OWNERDRAW,
133, 5, 24, 24,
hWnd, (HMENU)CM_LISTPREV, hInst, NULL);
nextbut= CreateWindow ("BUTTON", NULL,
WS_CHILD| WS_VISIBLE | WS_DISABLED |
WS_TABSTOP | BS_PUSHBUTTON | BS_OWNERDRAW,
205, 5, 24, 24,
hWnd, (HMENU)CM_LISTNEXT, hInst, NULL);
aboutbut= CreateWindow ("BUTTON", NULL,
WS_CHILD| WS_VISIBLE | WS_TABSTOP |
BS_PUSHBUTTON | BS_OWNERDRAW,
245, 5, 24, 24,
hWnd, (HMENU)CM_HELPABOUT, hInst, NULL);
tracker= CreateWindow(TRACKBAR_CLASS, NULL,
WS_CHILD | WS_VISIBLE | WS_TABSTOP |
WS_DISABLED | TBS_AUTOTICKS,
5, 34, 263, 30, hWnd, (HMENU) 8, hInst, NULL);
status_bar= CreateStatusWindow(WS_CHILD | WS_VISIBLE | SBT_NOBORDERS,
"No file", hWnd, 0);
SendMessage(status_bar, SB_SETPARTS, 4, (LPARAM) panes);
return(DefWindowProc(hWnd, message, wParam, lParam));
case WM_DRAWITEM:
hdc=GetDC(hWnd);
dis = (DRAWITEMSTRUCT *) lParam;
disabled = (dis->itemState & ODS_DISABLED) == ODS_DISABLED;
selected = (dis->itemState & ODS_SELECTED) == ODS_SELECTED;
switch (dis->CtlType) {
case ODT_BUTTON:
if (dis->hwndItem==openbut)
if (selected)
DrawIcon(hdc, 5, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_9)));
else
DrawIcon(hdc, 5, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_12)));
else if (dis->hwndItem == playbut)
if (disabled)
DrawIcon(hdc, 45, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_14)));
else
if (selected)
DrawIcon(hdc, 45, 5, LoadIcon(hInst,MAKEINTRESOURCE(ICON_18)));
else
DrawIcon(hdc, 45, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_13)));
else if (dis->hwndItem == pausebut)
if (disabled)
DrawIcon(hdc, 69, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_4)));
else
if (selected)
DrawIcon(hdc, 69, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_24)));
else
DrawIcon(hdc, 69, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_6)));
else if (dis->hwndItem == stopbut)
if (disabled)
DrawIcon(hdc, 93, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_3)));
else
if (selected)
DrawIcon(hdc, 93, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_10)));
else
DrawIcon(hdc, 93, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_5)));
else if (dis->hwndItem == aboutbut)
if (selected)
DrawIcon(hdc, 245, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_21)));
else
DrawIcon(hdc, 245, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_15)));
else if (dis->hwndItem == rewbut)
if (disabled)
DrawIcon(hdc, 157, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_8)));
else
if (selected)
DrawIcon(hdc, 157, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_22)));
else
DrawIcon(hdc, 157, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_7)));
/* else if (dis->hwndItem == repbut)
if (disabled)
DrawIcon(hdc, 157, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_19)));
else
if (selected)
DrawIcon(hdc, 157, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_11)));
else
DrawIcon(hdc, 157, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_25))); */
else if (dis->hwndItem == ffbut)
if (disabled)
DrawIcon(hdc, 181, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_17)));
else
if (selected)
DrawIcon(hdc, 181, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_23)));
else
DrawIcon(hdc, 181, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_16)));
else if (dis->hwndItem == prevbut)
if (disabled)
DrawIcon(hdc, 133, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_26)));
else
if (selected)
DrawIcon(hdc, 133, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_27)));
else
DrawIcon(hdc, 133, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_20)));
else if (dis->hwndItem == nextbut)
if (disabled)
DrawIcon(hdc, 205, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_29)));
else
if (selected)
DrawIcon(hdc, 205, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_30)));
else
DrawIcon(hdc, 205, 5, LoadIcon(hInst, MAKEINTRESOURCE(ICON_28)));
break;
}
ReleaseDC(hWnd, hdc);
return(DefWindowProc(hWnd, message, wParam, lParam));
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case CM_FILEOPEN:
file_open();
break;
case CM_FILEEXIT:
leave();
break;
case CM_AUDIOPLAY:
audio_play();
break;
case CM_AUDIOPAUSE:
audio_pause();
break;
case CM_AUDIOSTOP:
audio_stop();
break;
case CM_AUDIOREWIND:
CMDLINE = FALSE;
scrolling = TRUE;
new_pos = SendMessage(tracker, TBM_GETPOS, 0, 0);
if ((new_pos -= line_size) < 0)
new_pos = 0;
args->desired_position = new_pos;
if (!args->position_change) {
args->position_change = TRUE;
if (!paused && playing)
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Seeking...");
}
SendMessage(tracker, TBM_SETPOS, (WPARAM) TRUE, new_pos);
break;
case CM_AUDIOFAST_FORWARD:
CMDLINE = FALSE;
new_pos = SendMessage(tracker, TBM_GETPOS, 0, 0);
if ((new_pos += line_size) < scroll_range) {
args->desired_position = new_pos;
scrolling = TRUE;
if (!args->position_change) {
args->position_change = TRUE;
if (!paused && playing)
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Seeking...");
}
SendMessage(tracker, TBM_SETPOS, (WPARAM) TRUE, new_pos);
}
break;
case CM_AUDIOREPEAT:
CMDLINE=FALSE;
// Beautiful C++ style, but Borland doesn't like this:
if (Repeat=!Repeat) {
CheckMenuItem(mainmenu, CM_AUDIOREPEAT, MF_CHECKED);
SendMessage(status_bar,SB_SETTEXT, 3,(LPARAM) "R");
} else {
CheckMenuItem(mainmenu, CM_AUDIOREPEAT, MF_UNCHECKED);
SendMessage(status_bar,SB_SETTEXT, 3,(LPARAM) NULL);
}
break;
case CM_OPTIONS:
if (DialogBox(hInst, MAKEINTRESOURCE(OPTIONS), hWnd,
Options)==-1)
MessageBox(hWnd, "Unable to open options dialog box.",
"Error Opening Dialog Box", MB_OK);
break;
case CM_AUDIOPROPERTIES:
audio_properties();
break;
case CM_LISTPREV:
gotop_List(-2);
break;
case CM_LISTREPEAT:
gotop_List(-1);
break;
case CM_LISTNEXT:
gotop_List(0);
break;
case CM_HELPABOUT:
about();
break;
default:
break;
}
break;
case WM_HSCROLL:
// Process scroll messages by sending notification to
// appropriate thread.
LRESULT new_pos;
switch (LOWORD(wParam)) {
case TB_LINEUP:
case TB_LINEDOWN:
case TB_PAGEDOWN:
case TB_PAGEUP:
CMDLINE = FALSE;
new_pos = SendMessage(tracker, TBM_GETPOS, 0, 0);
if ((new_pos < scroll_range) && (new_pos>=0)) {
scrolling = TRUE;
args->desired_position = new_pos;
if (!args->position_change) {
args->position_change = TRUE;
if (!paused && playing)
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Seeking...");
}
}
break;
case TB_THUMBTRACK:
scrolling = TRUE; // We are scrolling, don't allow
// scroll position changes by threads.
new_pos = SendMessage(tracker, TBM_GETPOS, 0, 0);
update_timewin((int) new_pos);
break;
case TB_THUMBPOSITION: // Scroll box placed somewhere
args->desired_position = SendMessage(tracker, TBM_GETPOS, 0, 0);
if(!args->position_change) {
args->position_change = TRUE;
if (!paused && playing)
SendMessage(status_bar,SB_SETTEXT, 0, (LPARAM) "Seeking...");
}
break;
}
return(0L);
case SCROLL_POS: // Process new position data from threads.
if (!scrolling && (wParam <=scroll_range)) {
SendMessage(tracker, TBM_SETPOS, TRUE, wParam);
update_timewin((int) wParam);
}
return(0L);
case SEEK_ACK: // Seek completed, allow scroll changes.
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Playing...");
scrolling = FALSE;
return(0L);
case MM_MCINOTIFY:
switch (wParam) {
case MCI_NOTIFY_SUCCESSFUL:
clear_sound();
if (ListMode) {
Next_Song();
return(0L);
}
reinit_MCI();
ok_play();
no_stop();
if (Repeat) {
no_play();
MCI_play();
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Playing...");
} else {
playing=FALSE;
if (CMDLINE)
leave();
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Stopped");
}
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0); // this is the end...
break;
case WM_CLOSE:
// Tell windows to destroy our window.
leave();
break;
case WM_THREADEND:
clear_sound();
if (ListMode) {
Next_Song();
return(0L);
}
if (CMDLINE)
leave();
else {
playing=FALSE;
reinit_MPEG(); // We know file is ok already.
if (Repeat) {
MPEG_play();
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Playing...");
} else {
ok_play();
no_stop();
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Stopped");
}
}
break;
case WM_CMDLINEFILE:
lstrcpy(szName, (LPSTR) lParam);
if (wParam == 0) {
playing=TRUE;
no_play();
reinit_MCI();
MCI_play();
} else {
clear_sound();
if (!reinit_MPEG())
return(1L);
playing=FALSE;
no_play();
MPEG_play();
}
SendMessage(status_bar,SB_SETTEXT, 0,(LPARAM) "Playing...");
DisplayName(szName);
EnableWindow(rewbut, TRUE);
EnableMenuItem(mainmenu, CM_AUDIOREWIND, MF_ENABLED);
EnableWindow(ffbut, TRUE);
EnableMenuItem(mainmenu, CM_AUDIOFAST_FORWARD, MF_ENABLED);
break;
case WM_CHAR:
switch(wParam) {
case 'o':
file_open();
break;
case ' ':
audio_play();
break;
case 's':
audio_stop();
break;
case '"':
case 'p':
audio_pause();
break;
case '?':
about();
break;
case 'x':
case 'q':
leave();
break;
}
break;
case 312: // CTLCOLOR message for trackbar
if ((HWND) lParam == tracker)
return((DWORD) GetStockObject(LTGRAY_BRUSH));
default:
// Let windows handle all messages we choose to ignore.
return(DefWindowProc(hWnd, message, wParam, lParam));
}
return(0L);
}
void leave_options(HWND hDlg)
{
enum e_channels old_mode=mode;
if (IsDlgButtonChecked(hDlg, IDC_STEREO))
mode=both;
else if (IsDlgButtonChecked(hDlg, IDC_LEFT))
mode=left;
else
mode=right;
if ((mode!=old_mode) && !(playing || paused))
reinit_MPEG();
EndDialog(hDlg, TRUE);
return;
}
#pragma argsused
BOOL WINAPI Options(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_INITDIALOG:
switch (mode) {
case both:
CheckRadioButton(hDlg, IDC_STEREO, IDC_RIGHT, IDC_STEREO);
break;
case left:
CheckRadioButton(hDlg, IDC_STEREO, IDC_RIGHT, IDC_LEFT);
break;
case right:
CheckRadioButton(hDlg, IDC_STEREO, IDC_RIGHT, IDC_RIGHT);
break;
}
return(TRUE);
case WM_CLOSE:
leave_options(hDlg);
return(TRUE);
case WM_COMMAND:
{
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK:
leave_options(hDlg);
return(TRUE);
default:
return(TRUE);
}
}
case WM_CTLCOLORDLG:
return((DWORD) GetStockObject(LTGRAY_BRUSH));
default:
return(FALSE);
}
}