-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 0fd17f8
Showing
33 changed files
with
3,894 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
About ESFM bank editor | ||
====================== | ||
|
||
[ESS](https://en.wikipedia.org/wiki/ESS_Technology) PCI Soundcards like | ||
the ES1969 (Solo1), ES1946, Allegro PCI etc. have their own 4-channel | ||
synthesizer which is more capable than [OPL3](https://moddingwiki.shikadi.net/wiki/OPL_chip), | ||
which these card also are capable of emulating. | ||
Their synthesizer is called ESFM and due to its enhanced capabilities, the | ||
driver has its own Patches-table which takes into account the 4 oeprators with | ||
individual frequency offsets, something the basic OPL is not capable of. | ||
The Patches-table is embedded within the driver, but I reverse-engineeres the | ||
ES1969 driver and ported it to also support 64bit, which is available | ||
[here](https://github.com/leecher1337/es1969). | ||
This copy of the driver also allows you to load your custom patch set from a file | ||
so that you can adjust the instrument tables according to your needs and maybe | ||
implement some additional effects that can again then be ported back into | ||
the driver. | ||
|
||
As it is not convenient to edit the table with a hex-editor to experiment with | ||
it, ESFM bank editor has been created. It runs on 32bit and 64bit Windows and | ||
allows you to load and save the patches table and also test you settings by | ||
playing an instrument note on the ESFM card (supported ESFM card required). | ||
|
||
Installation | ||
============ | ||
Depending on the Windows version you have, either download the 32bit or 64bit | ||
package from the "Releases" link on the right side. | ||
Unpack all files to a directory and run esfmbank.exe | ||
|
||
How to use | ||
========== | ||
The release package ships with the default patch set that gets used by all | ||
drivers (including i.e. Allegro DOS sound system) except the NT4 driver | ||
which has a slightly different patch set. | ||
Both patch sets can be obtained from | ||
[ESSplaymid repository](https://github.com/pachuco/ESSPlayMid/tree/master/bin). | ||
|
||
When opening the application, the default patch set is loaded when available. | ||
The user interface is pretty similar to that of | ||
[OPL3BankEditor](https://github.com/Wohlstand/OPL3BankEditor). | ||
To the left, you can choose between General Midi Melodic (0-127) and | ||
Percussion (128-255) instruments. | ||
When clicking on an instrument, its parameters are shown to the right side. | ||
If an instrument has a second voice, the check box `[x] Second voice` | ||
needs to be checked, otherwise the Tab with the second voice will be readonly. | ||
Per voice, there are the 4 Operators that can be tuned accordingly. | ||
For an explanation on all the settings and values, please see the | ||
[ESFM documentation](https://github.com/jwt27/esfm). | ||
When you change a parameter for an instrument, the change will not be applied, | ||
unless you click on the "Apply" button. | ||
|
||
An exception to that rule are the "Play note" etc. buttons on the right which | ||
temporarily apply your settings when playing the note so that you can | ||
experiment with the parameters. | ||
Use "Reset" button to reset the parameters to the state of the last click | ||
on "Apply" (or to initial state if there was no "Apply" click yet). | ||
Apply/Reset are per operator. | ||
For testing the chord, as mentioned, use the buttons under "Testing" tab. | ||
For them to be enabled and to work properly, you need to connect to your | ||
ESS soundcard and for this, you need to know the correct base address of the | ||
SB base port. The application tries to already fill in the correct port, | ||
if you have the ESS soundcard driver installed. | ||
Look under "Soundcard connection" frame for it. In the dropdown menu, you | ||
can select your ESFM soundcard and the correct port should be filled in, | ||
so you just have to click onto "Connect" button to connect to your soundcard. | ||
Be aware that chosing a wrong port can have unforseen consequences for the | ||
stability of you machine, so ensure that you are not using a random port there! | ||
|
||
The "MIDI input" tab acts as a possibility to play a MIDI file with the current | ||
patchset from an external MIDI player. In order to make use of it, you need | ||
the [loopMIDI](https://www.tobias-erichsen.de/software/loopmidi.html) driver | ||
and create a virtual MIDI cable. | ||
Than connect to the loopMIDI MIDI input in the "MIDI input" tab and press | ||
"Connect". On the other end of the "loopMIDI" cable, attach your MIDI player. | ||
I recommend | ||
[TMIDI: (Tom's MIDI Player)](https://www.grandgent.com/tom/projects/tmidi/) | ||
for that purpose. | ||
ESFM bank editor takes the MIDI data from the player, uses the current | ||
bank settings (which need to be applied) for MIDI playback and sends the | ||
signals to the Soundcard. | ||
|
||
Patch table format | ||
================== | ||
The format of the patch table is pretty straightforward: | ||
Check out [ESFM docs](https://github.com/jwt27/esfm) for register definitions. | ||
|
||
The patch file starts with 128 USHORTs that specify the offset of the 128 | ||
programs defined by [General Midi](https://de.wikipedia.org/wiki/General_MIDI). | ||
|
||
Then follows the table with 128 USHORTs that specify the offset of the | ||
General midi Percussion instruments also defined by general midi. | ||
|
||
Afterwards the actual patch definitions start, consisting of: | ||
|
||
Byte 0 | ||
------ | ||
``` | ||
╔═══════╦═══════╤═══════╤═══════╤═══════╤═══════╤═══════╤═══════╤═══════╗ | ||
║ R↓ B→ ║ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 ║ | ||
╠═══════╬═══════╪═══════╪═══════╪═══════╪═══════╪═══════╧═══════╪═══════╣ | ||
║ ║ FP4 │ FP3 │ FP2 │ FP1 │ ? │ Operation │ PAT16 ║ | ||
╚═══════╩═══════╧═══════╧═══════╧═══════╧═══════╧═══════════════╧═══════╝ | ||
``` | ||
|
||
PAT16: Use Patch16? | ||
Operation: | ||
0 - Only use voice 1 | ||
1 - Also use second voice, if set | ||
2 - Also use second voice, if not set, steal voice | ||
FP1..FP4: Set fixed pitch for operator 1-4 | ||
|
||
Byte 3 | ||
------ | ||
Relative velocity for operator 1-4 | ||
``` | ||
╔═══════╦═══════╤═══════╤═══════╤═══════╤═══════╤═══════╤═══════╤═══════╗ | ||
║ R↓ B→ ║ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 ║ | ||
╠═══════╬═══════╧═══════╪═══════╧═══════╪═══════╧═══════╪═══════╧═══════╣ | ||
║ ║ Rel.veloc. 4 │ Rel.veloc. 3 │ Rel.veloc. 2 │ Rel.veloc. 1 ║ | ||
╚═══════╩═══════════════╧═══════════════╧═══════════════╧═══════════════╝ | ||
``` | ||
|
||
Byte 4-11,12-19,20-27,28-35 | ||
--------------------------- | ||
Registers to set for each operator as documented under "Operator registers" | ||
in ESFM documentation. | ||
|
||
If `Operation` in Byte 0 is > 0 then data for the second voice follows | ||
(Starting with byte 0 from above again). | ||
|
||
Compiling | ||
========= | ||
The application has been developed and compile with Microsoft Visual | ||
Studio 6 and it contains a .dsp file for it, but you should also be able | ||
to compile it with newer versions of Visual Studio. | ||
|
||
References | ||
========== | ||
[ES1969 Windows driver](https://github.com/leecher1337/es1969) | ||
|
||
[ESFM documentation](https://github.com/jwt27/esfm) | ||
|
||
Author | ||
====== | ||
(c)oded by [email protected] | ||
For support use the issue tracker on the project's page: | ||
https://github.com/leecher1337/esfmbank |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
VOID FAR PASCAL fmwrite (WORD wAddress, BYTE bValue); | ||
void FAR PASCAL fmreset(); | ||
|
||
SHORT NATV_CalcBend(USHORT detune, USHORT iBend, USHORT iBendRange); | ||
BYTE NATV_CalcVolume(BYTE reg1, BYTE bVelocity, BYTE bChannel); | ||
void NATV_CalcNewVolume(BYTE bChannel); | ||
|
||
void note_on(BYTE bChannel, BYTE bNote, BYTE bVelocity); | ||
void note_off(BYTE bChannel, BYTE bNote); | ||
|
||
void voice_on(int voiceNr); | ||
void voice_off(int voiceNr); | ||
|
||
void hold_controller(BYTE bChannel, BYTE bVelocity); | ||
void find_voice(BOOL patch1617_allowed_voice1, BOOL patch1617_allowed_voice2, BYTE bChannel, BYTE bNote); | ||
void setup_voice(int voicenr, int offset, int bChannel, int bNote, int bVelocity); | ||
int steal_voice(int patch1617_allowed); | ||
|
||
VOID MidiAllNotesOff(void); | ||
WORD NEAR PASCAL MidiCalcFAndB (DWORD dwPitch, BYTE bBlock); | ||
VOID NEAR PASCAL MidiPitchBend (BYTE bChannel, USHORT iBend); | ||
VOID NEAR PASCAL MidiMessage (DWORD dwData); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/****************************************************************** | ||
esdev.c - Functions to find ES1969 sound card IO port address | ||
ESFM Bank editor | ||
Copyright (c) 2023, [email protected] All Rights Reserved. | ||
*******************************************************************/ | ||
#define WIN32_LEAN_AND_MEAN | ||
#include <windows.h> | ||
#include <setupapi.h> | ||
#include <cfgmgr32.h> | ||
#include "esdev.h" | ||
|
||
#ifdef _MSC_VER | ||
#pragma comment(lib, "Setupapi.lib") | ||
#endif | ||
|
||
// ks.h | ||
#define KSCATEGORY_RENDER {0x65E8773EL, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} | ||
|
||
|
||
DWORD EnumESSDevices(HWND hWnd, void (*EnumCB)(ESS_DEVCFG *pCfg, void *pUser), void *pUser) | ||
{ | ||
GUID render = KSCATEGORY_RENDER; | ||
HDEVINFO hDevInfo; | ||
SP_DEVINFO_DATA infoData={0}; | ||
LOG_CONF hFirstLogConf; | ||
CONFIGRET rcCm; | ||
ESS_DEVCFG devCfg; | ||
DWORD i, n, ret = 0; | ||
|
||
hDevInfo = SetupDiGetClassDevsW(&render, NULL, hWnd, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); | ||
if (hDevInfo == INVALID_HANDLE_VALUE) return 0; | ||
|
||
infoData.cbSize = sizeof(SP_DEVINFO_DATA); | ||
for (n = 0; SetupDiEnumDeviceInfo(hDevInfo, n, &infoData); ++n) | ||
{ | ||
if (SetupDiGetDeviceRegistryProperty(hDevInfo, &infoData, SPDRP_DEVICEDESC, NULL, devCfg.szDevName, sizeof(devCfg.szDevName), NULL)) | ||
{ | ||
rcCm = CM_Get_First_Log_Conf(&hFirstLogConf, infoData.DevInst, ALLOC_LOG_CONF); | ||
if (rcCm != CR_SUCCESS) | ||
rcCm = CM_Get_First_Log_Conf(&hFirstLogConf, infoData.DevInst, BOOT_LOG_CONF); | ||
if (rcCm == CR_SUCCESS) | ||
{ | ||
/* Get the first resource descriptor handle. */ | ||
LOG_CONF hCurLogConf = 0; | ||
rcCm = CM_Get_Next_Res_Des(&hCurLogConf, hFirstLogConf, ResType_IO, 0, 0); | ||
if (rcCm == CR_SUCCESS) | ||
{ | ||
for (i=0;i<sizeof(devCfg.Ports)/sizeof(devCfg.Ports[0]);i++) | ||
{ | ||
ULONG cbData; | ||
IO_DES *pIoDesc; | ||
RES_DES hFreeResDesc; | ||
|
||
rcCm = CM_Get_Res_Des_Data_Size(&cbData, hCurLogConf, 0); | ||
if (rcCm != CR_SUCCESS) | ||
cbData = 0; | ||
cbData = max(cbData, sizeof(IO_DES)); | ||
pIoDesc = (IO_DES *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbData); | ||
if (pIoDesc) | ||
{ | ||
rcCm = CM_Get_Res_Des_Data(hCurLogConf, pIoDesc, cbData, 0L); | ||
if (rcCm == CR_SUCCESS) | ||
{ | ||
/* | ||
printf("drvHostParallelGetWinHostIoPortsSub: Count=%d Type=%x Base=%I64x End=%I64x Flags=%x\n", | ||
pIoDesc->IOD_Count, pIoDesc->IOD_Type, pIoDesc->IOD_Alloc_Base, | ||
pIoDesc->IOD_Alloc_End, pIoDesc->IOD_DesFlags);*/ | ||
devCfg.Ports[i] = (USHORT)pIoDesc->IOD_Alloc_Base; | ||
} | ||
HeapFree(GetProcessHeap(), 0, pIoDesc); | ||
} | ||
|
||
/* Next */ | ||
hFreeResDesc = hCurLogConf; | ||
rcCm = CM_Get_Next_Res_Des(&hCurLogConf, hCurLogConf, ResType_IO, 0, 0); | ||
CM_Free_Res_Des_Handle(hFreeResDesc); | ||
if (rcCm != CR_SUCCESS) | ||
break; | ||
} | ||
if (i == sizeof(devCfg.Ports)/sizeof(devCfg.Ports[0])-1) | ||
{ | ||
EnumCB(&devCfg, pUser); | ||
ret++; | ||
} | ||
} | ||
CM_Free_Log_Conf_Handle(hFirstLogConf); | ||
} | ||
} | ||
} | ||
return ret; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/****************************************************************** | ||
esdev.h - Functions to find ES1969 sound card IO port address | ||
ESFM Bank editor | ||
Copyright (c) 2023, [email protected] All Rights Reserved. | ||
*******************************************************************/ | ||
enum | ||
{ | ||
ESSPortIO = 0, | ||
ESSPortSB = 1, | ||
ESSPortVc = 2, | ||
ESSPortMPU = 3, | ||
ESSPortGP = 4 | ||
}; | ||
|
||
typedef struct | ||
{ | ||
char szDevName[128]; | ||
USHORT Ports[5]; | ||
} ESS_DEVCFG; | ||
|
||
DWORD EnumESSDevices(HWND hWnd, void (*EnumCB)(ESS_DEVCFG *pCfg, void *pUser), void *pUser); |
Oops, something went wrong.