Hello friends. I bring more contributions:
See attached demo.vgm for the complete but untrimmed demo song. I will post a better version later, this one is fairly close. It sounds pretty good even without the DSP, though you can tell the DSP is missing.
It is only playable with the libvgm
vgmtest program. I have tried applying ValleyBell's patch to the MultiPCM core in vgmplay, but the instruments are messed up and it doesn't play correctly. Perhaps ValleyBell can do a quick backport?
In the log to vgm converter, I was able to detect the sync word at any offset, by simply reading byte by byte until I found what I was looking for. I also skip a few sync words at the beginning, seems to give better results. I was also able to get the timing correct by simply multiplying by two the waits. Perhaps I'm doing something wrong on the micro when counting samples.
I had trouble getting vgmplay to work with libao, due to uninstalling pulseaudio, and libao's config file /etc/libao.conf still trying to use pulse instead of alsa. If you ask me that's a bunch of caca dookie.
I haven't used git in a while, so just so I don't mess anything up, instead of committing here is a patch for vgmplay:
Code:
diff --git a/VGMPlay/Stream.c b/VGMPlay/Stream.c
index a8cb05e..2319a1f 100644
--- a/VGMPlay/Stream.c
+++ b/VGMPlay/Stream.c
@@ -30,6 +30,7 @@
#error "Sorry, but this doesn't work yet!"
#endif
#include <ao/ao.h>
+#include <errno.h>
#endif
#include "chips/mamedef.h" // for UINT8 etc.
@@ -240,6 +241,17 @@ UINT8 SoundLogging(UINT8 Mode)
return RetVal;
}
+static const char *ao_strerror(int e) {
+ switch(e) {
+ case AO_ENODRIVER: return "No driver corresponds to driver_id.";
+ case AO_ENOTLIVE: return "This driver is not a live output device.";
+ case AO_EBADOPTION: return "A valid option key has an invalid value.";
+ case AO_EOPENDEVICE: return "Cannot open the device (for example, if /dev/dsp cannot be opened for writing).";
+ case AO_EFAIL: return "Any other cause of failure.";
+ }
+ return "Unknown";
+}
+
UINT8 StartStream(UINT8 DeviceID)
{
UINT32 RetVal;
@@ -322,6 +334,7 @@ UINT8 StartStream(UINT8 DeviceID)
if (dev_ao == NULL)
#endif
{
+ fprintf(stderr, "Error opening AO: %s (%d)\n", ao_strerror(errno), errno);
CloseThread = true;
return 0xC0; // waveOutOpen failed
}
It might need some more #ifdef'ing though.
And here is a patch for README.md:
Code:
diff --git a/VGMPlay/README.md b/VGMPlay/README.md
index 8be3aa3..9923963 100644
--- a/VGMPlay/README.md
+++ b/VGMPlay/README.md
@@ -13,3 +13,10 @@ sudo apt-get install make gcc zlib1g-dev libao-dev
make
```
+**troubleshooting**
+If you are using libao and you get an error similar to this one:
+```
+Error opening AO: Cannot open the device (for example, if /dev/dsp cannot be opened for writing). (5)
+Error openning Sound Device!
+```
+Try checking the contents of /etc/libao.conf or ~/.libao and select the correct driver. One example is if you uninstalled pulseaudio and the default_driver value remained pulse instead of alsa.
Here is my attempted MultiPCM patch, which fails because the instruments sound switched around:
Code:
diff --git a/VGMPlay/chips/multipcm.c b/VGMPlay/chips/multipcm.c
index a108536..2c302ce 100644
--- a/VGMPlay/chips/multipcm.c
+++ b/VGMPlay/chips/multipcm.c
@@ -346,7 +346,7 @@ static void WriteSlot(MultiPCM *ptChip,struct _SLOT *slot,int reg,unsigned char
//according to YMF278 sample write causes some base params written to the regs (envelope+lfos)
//the game should never change the sample while playing.
{
- struct _Sample *Sample=ptChip->Samples+slot->Regs[1];
+ struct _Sample *Sample=ptChip->Samples+(slot->Regs[1] | ((slot->Regs[2] & 1) << 8));
WriteSlot(ptChip,slot,6,Sample->LFOVIB);
WriteSlot(ptChip,slot,7,Sample->AM);
}
@@ -382,9 +382,9 @@ static void WriteSlot(MultiPCM *ptChip,struct _SLOT *slot,int reg,unsigned char
if(slot->Base>=0x100000)
{
if(slot->Pan&8)
- slot->Base=(slot->Base&0xfffff)|(ptChip->BankL);
+ slot->Base=(slot->Base&0x3fffff)|(ptChip->BankL);
else
- slot->Base=(slot->Base&0xfffff)|(ptChip->BankR);
+ slot->Base=(slot->Base&0x3fffff)|(ptChip->BankR);
}
}
I guess now there a few things left to do:
- Add 12 bit sample support in the multipcm core.
- Log the DSP test program and get some clues on how the YMW258-F controls the DSP chip.
- Emulate the DSP chip.
- Trim the demo song and post as a pack or in homebrew. I think it would be the first hardware VGM log.
- I'll post the firmware to the github page as well, after a bit of cleanup.
- I still haven't figured out why I was getting the 65536 sample errors previously, it seems to behave well now. I'd like to figure out a more robust way to log hardware VGM. Perhaps by using a CPLD with its own timer inside, and making a reusable board with a bunch of I/O lines. I wonder if 16 is enough?
EDIT: a 16 channel logic analyzer should suffice IMO.
- Perhaps filter out command spamming by keeping a register cache? Would that be possible?
- Dance.