Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added WAV capturing option #49

Merged
merged 4 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/bgmlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "ebmusv2.h"
#include "id.h"

#define IDC_ROM_FILE 17
#define IDC_ORIG_ROM_FILE 18
Expand Down Expand Up @@ -121,8 +122,10 @@ void load_instruments() {
sample_ptr_base = 0x6C00;
decode_samples(&spc[sample_ptr_base]);
inst_base = 0x6E00;
if (samp[0].data == NULL)
song_playing = FALSE;
if (samp[0].data == NULL) {
stop_playing();
EnableMenuItem(hmenu, ID_PLAY, MF_ENABLED);
}
initialize_state();
}

Expand Down
15 changes: 14 additions & 1 deletion src/ebmusv2.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#ifndef EBMUSV2_H
#define EBMUSV2_H

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "structs.h"

Expand Down Expand Up @@ -45,6 +49,7 @@ extern HWND tab_hwnd[NUM_TABS];
#define hwndInstruments tab_hwnd[1]
#define hwndEditor tab_hwnd[2]
#define hwndPackList tab_hwnd[3]
char *open_dialog(BOOL (WINAPI *func)(LPOPENFILENAME), char *filter, char *extension, DWORD flags);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How terrible of an idea is it to include <commdlg.h> here, instead of just in sound.c and main.c? This declaration adds a lot of warning noise, at least with the compiler flags I have CodeBlocks set to, because it thinks LPOPENFILENAME is a parameter name and not a type.

BOOL get_original_rom(void);
BOOL save_all_packs(void);

Expand Down Expand Up @@ -151,6 +156,7 @@ void free_metadata(void);

// misc.c
void enable_menu_items(const BYTE *list, int flags);
void update_menu_item(UINT item, LPTSTR label);
#ifdef CreateWindow
void set_up_hdc(HDC hdc);
void reset_hdc(HDC hdc);
Expand Down Expand Up @@ -223,7 +229,12 @@ void order_delete(int pos);
// sound.c
extern int mixrate;
extern int chmask;
extern BOOL song_playing;
BOOL is_playing(void);
BOOL start_playing(void);
void stop_playing(void);
BOOL is_capturing_audio(void);
BOOL start_capturing_audio(void);
void stop_capturing_audio(void);
extern int timer_speed;
int sound_init(void);
void winmm_message(unsigned int uMsg);
Expand All @@ -246,3 +257,5 @@ void editor_command(int id);
#endif
void format_status(int part, const char* format, ...);
void set_tracker_status(int part, BYTE *code);

#endif // EBMUSV2_H
3 changes: 2 additions & 1 deletion src/id.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
#define ID_OPTIONS 130
#define ID_PLAY 131
#define ID_STOP 132
#define ID_CLEAR_SONG 133
#define ID_CAPTURE_AUDIO 133
#define ID_CLEAR_SONG 134
#define ID_ZOOM_IN 140
#define ID_ZOOM_OUT 141
#define ID_STATUS_BAR 142
Expand Down
9 changes: 6 additions & 3 deletions src/inst.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <windows.h>
#include <mmsystem.h>
#include <commctrl.h>
#include "id.h"
#include "ebmusv2.h"

#define IDC_SAMPLIST_CAPTION 1
Expand Down Expand Up @@ -225,8 +226,7 @@ LRESULT CALLBACK InstrumentsWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
SendMessage(instlist, LB_ADDSTRING, 0, (LPARAM)buf);
*p++ = i;
}
if (sound_init())
song_playing = TRUE;
start_playing();
timer_speed = 0;
memset(&state.chan, 0, sizeof state.chan);
for (int ch = 0; ch < 8; ch++) {
Expand Down Expand Up @@ -255,6 +255,7 @@ LRESULT CALLBACK InstrumentsWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
closeMidiInDevice();
openMidiInDevice(midiDevice, MidiInProc);

EnableMenuItem(hmenu, ID_STOP, MF_GRAYED);
break;
}
case WM_COMMAND: {
Expand Down Expand Up @@ -288,14 +289,16 @@ LRESULT CALLBACK InstrumentsWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
move_controls(hWnd, &inst_list_template, lParam);
break;
case WM_DESTROY:
song_playing = FALSE;
stop_playing();
state = pattop_state;
timer_speed = 500;
chmask = prev_chmask;
closeMidiInDevice();

// Store the current selected instrument.
selectedInstrument = SendMessage(instlist, LB_GETCURSEL, 0, 0);

EnableMenuItem(hmenu, ID_PLAY, MF_ENABLED);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
Expand Down
2 changes: 1 addition & 1 deletion src/loadrom.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ BOOL close_rom() {
// This protects from crashes if an SPC was playing.
free_samples();
free_song(&cur_song);
song_playing = FALSE;
stop_playing();
initialize_state();

memset(packs_loaded, 0xFF, 3);
Expand Down
51 changes: 42 additions & 9 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ HWND hwndStatus;
HMENU hmenu, hcontextmenu;
HWND tab_hwnd[NUM_TABS];

static const int INST_TAB = 1;
static int current_tab;
static const char *const tab_class[NUM_TABS] = {
"ebmused_bgmlist",
Expand All @@ -68,10 +69,9 @@ static const WNDPROC tab_wndproc[NUM_TABS] = {
PackListWndProc,
};


static char filename[MAX_PATH];
static OPENFILENAME ofn;
static char *open_dialog(BOOL (WINAPI *func)(LPOPENFILENAME),
char *open_dialog(BOOL (WINAPI *func)(LPOPENFILENAME),
char *filter, char *extension, DWORD flags)
{
*filename = '\0';
Expand Down Expand Up @@ -593,6 +593,18 @@ BOOL save_all_packs() {
return success;
}

static BOOL validate_playable(void) {
if (cur_song.order_length == 0) {
MessageBox2("No song loaded", "Play", MB_ICONEXCLAMATION);
return FALSE;
} else if (samp[0].data == NULL) {
MessageBox2("No instruments loaded", "Play", MB_ICONEXCLAMATION);
return FALSE;
} else {
return TRUE;
}
}

LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case 0x3BB: case 0x3BC: case 0x3BD: // MM_WOM_OPEN, CLOSE, DONE
Expand Down Expand Up @@ -672,17 +684,38 @@ LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
editor_command(id);
break;
case ID_PLAY:
if (cur_song.order_length == 0)
MessageBox2("No song loaded", "Play", MB_ICONEXCLAMATION);
else if (samp[0].data == NULL)
MessageBox2("No instruments loaded", "Play", MB_ICONEXCLAMATION);
else {
if (sound_init()) song_playing = TRUE;
if (validate_playable()) {
start_playing();
EnableMenuItem(hmenu, ID_STOP, MF_ENABLED);
}
break;
case ID_STOP:
song_playing = FALSE;
if (current_tab == INST_TAB) {
stop_capturing_audio();
} else {
stop_playing();
EnableMenuItem(hmenu, ID_PLAY, MF_ENABLED);
}
break;
case ID_CAPTURE_AUDIO: {
if (current_tab == INST_TAB) {
if (is_capturing_audio()) {
stop_capturing_audio();
} else {
start_capturing_audio();
}
} else {
if (is_capturing_audio()) {
stop_capturing_audio();
} else {
if (validate_playable() && start_capturing_audio()) {
start_playing();
EnableMenuItem(hmenu, ID_STOP, MF_ENABLED);
}
}
}
break;
}
case ID_OCTAVE_1: case ID_OCTAVE_1+1: case ID_OCTAVE_1+2:
case ID_OCTAVE_1+3: case ID_OCTAVE_1+4:
octave = id - ID_OCTAVE_1;
Expand Down
8 changes: 8 additions & 0 deletions src/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ void enable_menu_items(const BYTE *list, int flags) {
while (*list) EnableMenuItem(hmenu, *list++, flags);
}

void update_menu_item(UINT item, LPTSTR label) {
MENUITEMINFO menuiteminfo = { sizeof(MENUITEMINFO) };
GetMenuItemInfo(hmenu, item, FALSE, &menuiteminfo);
menuiteminfo.fMask = MIIM_STRING;
menuiteminfo.dwTypeData = label;
SetMenuItemInfo(hmenu, item, FALSE, &menuiteminfo);
}

HFONT oldfont;
COLORREF oldtxt, oldbk;

Expand Down
9 changes: 6 additions & 3 deletions src/play.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <stdio.h>
#include <string.h>
#include "ebmusv2.h"
#include "id.h"

BYTE spc[65536];
int inst_base = 0x6E00;
Expand Down Expand Up @@ -315,7 +316,8 @@ void load_pattern() {
state.repeat_count = cur_song.repeat;
if (state.repeat_count == 0) {
state.ordnum--;
song_playing = FALSE;
stop_playing();
EnableMenuItem(hmenu, ID_PLAY, MF_ENABLED);
return;
}
state.ordnum = cur_song.repeat_pos;
Expand Down Expand Up @@ -512,7 +514,7 @@ BOOL do_timer() {
state.cycle_timer -= 256;
while (!do_cycle(&state)) {
load_pattern();
if (!song_playing) return FALSE;
if (!is_playing()) return FALSE;
load_pattern_into_tracker();
}
} else {
Expand All @@ -539,6 +541,7 @@ void initialize_state() {
load_pattern();
} else {
pattop_state = state;
song_playing = FALSE;
stop_playing();
EnableMenuItem(hmenu, ID_PLAY, MF_ENABLED);
}
}
3 changes: 2 additions & 1 deletion src/resource.rc
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ BEGIN
POPUP "&Song"
BEGIN
MENUITEM "&Play\tCtrl+P", ID_PLAY
MENUITEM "&Stop\tEsc", ID_STOP
MENUITEM "&Stop\tEsc", ID_STOP, GRAYED
MENUITEM "Capture &Audio...", ID_CAPTURE_AUDIO
MENUITEM SEPARATOR
MENUITEM "&Clear", ID_CLEAR_SONG, GRAYED
END
Expand Down
84 changes: 83 additions & 1 deletion src/sound.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <stdlib.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commdlg.h>
#include <mmsystem.h>
#include "id.h"
#include "ebmusv2.h"
Expand All @@ -11,7 +12,23 @@ int bufsize = 2205;
int chmask = 255;
int timer_speed = 500;
HWAVEOUT hwo;
BOOL song_playing;
static BOOL song_playing = FALSE;
FILE* wav_file = NULL;

BOOL is_playing(void) { return song_playing; }
BOOL start_playing(void) {
if (sound_init()) {
song_playing = TRUE;
EnableMenuItem(hmenu, ID_PLAY, MF_GRAYED);
}

return song_playing;
}
void stop_playing(void) {
stop_capturing_audio();
song_playing = FALSE;
EnableMenuItem(hmenu, ID_STOP, MF_GRAYED);
}

static WAVEHDR wh[2], *curbuf = &wh[0];
static int bufs_used;
Expand Down Expand Up @@ -46,9 +63,70 @@ int sound_init() {
wh[1].dwBufferLength = bufsize*4;
waveOutPrepareHeader(hwo, &wh[0], sizeof *wh);
waveOutPrepareHeader(hwo, &wh[1], sizeof *wh);

return 1;
}

BOOL is_capturing_audio(void) {
return wav_file ? TRUE : FALSE;
}

BOOL start_capturing_audio(void) {
if (song_playing || sound_init()) {
char *file = open_dialog(GetSaveFileName, "WAV files (*.wav)\0*.wav\0", "wav", OFN_OVERWRITEPROMPT);
if (file) {
stop_capturing_audio();
wav_file = fopen(file, "wb");

if (wav_file) {
update_menu_item(ID_CAPTURE_AUDIO, "Stop C&apturing");
EnableMenuItem(hmenu, ID_STOP, MF_ENABLED);

DWORD size_placeholder = 0;
DWORD format_header_size = 16;
WORD formatTag = WAVE_FORMAT_PCM;
WORD num_channels = 2;
DWORD sample_rate = mixrate;
DWORD avg_byte_rate = mixrate*4;
WORD block_alignment = 4;
WORD bit_depth = 16;

fputs("RIFF", wav_file);
fwrite(&size_placeholder, sizeof size_placeholder, 1, wav_file);
fputs("WAVE", wav_file);
fputs("fmt ", wav_file);
fwrite(&format_header_size, sizeof format_header_size, 1, wav_file);
fwrite(&formatTag, sizeof formatTag, 1, wav_file);
fwrite(&num_channels, sizeof num_channels, 1, wav_file);
fwrite(&sample_rate, sizeof sample_rate, 1, wav_file);
fwrite(&avg_byte_rate, sizeof avg_byte_rate, 1, wav_file);
fwrite(&block_alignment, sizeof block_alignment, 1, wav_file);
fwrite(&bit_depth, sizeof bit_depth, 1, wav_file);
fputs("data", wav_file);
fwrite(&size_placeholder, sizeof size_placeholder, 1, wav_file);
}
}
}

return wav_file ? TRUE : FALSE;
}

void stop_capturing_audio(void) {
if (wav_file) {
update_menu_item(ID_CAPTURE_AUDIO, "Capture &Audio...");

int size = ftell(wav_file) - 8;
fseek(wav_file, 4, SEEK_SET);
fwrite(&size, sizeof size, 1, wav_file);

fseek(wav_file, 40, SEEK_SET);
size -= 36;
fwrite(&size, sizeof size, 1, wav_file);
fclose(wav_file);
wav_file = NULL;
}
}

static void sound_uninit() {
waveOutUnprepareHeader(hwo, &wh[0], sizeof *wh);
waveOutUnprepareHeader(hwo, &wh[1], sizeof *wh);
Expand Down Expand Up @@ -232,6 +310,10 @@ static void fill_buffer() {
putchar(219);
putchar('\n');
}*/
if (wav_file) {
fwrite(curbuf->lpData, curbuf->dwBufferLength, 1, wav_file);
}

waveOutWrite(hwo, curbuf, sizeof *wh);
bufs_used++;
curbuf = &wh[(curbuf - wh) ^ 1];
Expand Down