Jump to content

Eric Lafortune

Members
  • Posts

    61
  • Joined

  • Last visited

Everything posted by Eric Lafortune

  1. Continuing on your experiments, I've added a few options to my transposing tool (still way more limited than your toolkit). If both tone 2 and the tuned periodic noise are audible at the same time, I can pick one of: Tune the loudest generator correctly (and leave the other one off-tune) Tune tone 2 correctly Tune the periodic noise correctly Silence the most quiet generator (and tune the other one correctly) Silence tone 2 Silence the periodic noise Comparing them on this chiptune, I prefer versions with the droning bass, so I'm now silencing the most quiet generator, which is tone 2 most of the time. badapple_silencequietestconflictinggenerator.mp3
  2. Wow, excellent research, thanks! It sounds perfectly acceptable to me. In the meanwhile, I had found a brief analysis by Simondotm, the developer of the BBC demo, suggesting to suppress tone channel 2 in conflicting areas. It doesn't seem implemented in their own vgmconverter yet. I've implemented it in my own conversion tool, but now I need to study and compare the different approaches and results.
  3. I'm preparing a new release of the demo. Sorry about the delay; I've already been distracted by a new project (a 2.5D game, building on similar ideas). @OLD CS1 mentioned that the periodic noise channel might be 1/2 note off, but I can't figure that one out, or hear it with my untrained ears. The demo is based on the source VGM file of the BBC Micro version (on Github). It should correspond to the audio version of their composer (on Bandcamp). In their demo, they process it for the 4 MHz clock and the 15-bits noise shift register of the BBC Micro. I'm just using the unprocessed sound data. The VGM header states that it is targeted at a 3.579545 MHz (NTSC) clock and a 16-bits noise shift register. That should be exactly right for our TI. Does anyone know what I'm missing?
  4. I find myself using the cheat sheet regularly now. Thanks again! Another small typo: "Shift right arithmetic circular" -> "Shift right circular".
  5. Adding some practical examples to the theory that others have explained nicely... I use BLWP/RTWP extensively in my code, for example in the action game Rock Runner. Some pointers: game_screen.asm contains the main game loop, which is mostly a list of calls to subroutines. Subroutines themselves can also perform nested calls. This keeps the code manageable and readable. rendering.asm for example contains a set of subroutines for rendering. In their documentation, IN refers to a register in the workspace of the calling code. STATIC refers to a register in the workspace of the subroutine that has a fixed purpose across calls (like a static variable in C), so it is conveniently available in all related subroutines. I put the vector with addresses of the workspace and the code right before the code ('!' is a local label, supported in the xas99 assembler). main.asm defines the addresses of 9 register workspaces for all kinds of purposes, 8 of which fit in fast scratch-pad RAM. The few microseconds overhead are generally irrelevant.
  6. Very nice! Surprisingly complete, effective graphics, some sound, all in compact code. Nice use of subroutines. I like the low-level approach with custom VDP and CRU routines. As for coding tips: Documentation is essential to make sense of any assembly code, e.g. what do the subroutines do. You can use BLWP/RTWP subroutines (with their own register workspaces) instead of BL/RT subroutines, so you don't need to worry about clobbering registers. You might then even keep all your variables in registers, which makes for simpler code (although the naming isn't as explicit). You could consider the xdt assembler. It supports long names and macros, to work at a slightly higher level of abstraction.
  7. Very useful! Possible typo: "LIMI cnt: Load int. level: 0,1 enable; 2-15 dis." -> isn't it the other way around?
  8. I'll include it in the next update, thanks.
  9. I've tested it myself in the demo now: the reading CRU bit 2 for the VDP interrupt works fine in Mame. That's more in line with my earlier experiences and expectations; it's amazingly accurate software. I'll apply this technique in the next updates of the video tools and the demo.
  10. Thanks for the experiments. The recent video tools already had a small epsilon on the Vsync frequencies to account for potential minor timing issues -- that may have helped. I hadn't seen the CRU polling technique before, to wait for a vsync -- only the VDP status polling technique. After some searching, the advanced copper demo and XB GEM do turn out to use the former. I don't yet understand how VDP status polling can miss vsyncs. In practice, I rely entirely on Mame for development. Maybe CRU polling followed by VDP status polling would work on all systems/emulators.
  11. Thanks for the experiments and feedback, everyone! I'll adjust the balance between the chiptune and the vocals based on the more accurate settings in Mame, and I'll fix the frequency of the periodic noise channel. For the latter, the SMS Power website has an extensive discussion of the SN76489, and the BBC Micro version of Bad Apple has the code that added the shift originally, which had escaped my attention.
  12. I've updated the VideoTools project to version 2.1. The ComposeVideo tool now applies the more accurate PAL/NTSC frame rates. It also pre-fills the speech buffer with more data when a speech fragment starts (not wasting those precious 16 bytes!), so it avoids spuriously underflowing the buffer later on. With this update, version 2.1 of the Bad Apple project now offers a PAL version and an NTSC version. You can find the RPK files on the release page.
  13. You were right, @JasonACT -- the NTSC version didn't work, even with the CPU-intensive animation disabled, and the approximate frequencies were the culprit. Thanks! I've now adapted the code and the garbling is gone, even with the animation enabled. There's still a very occasional non-deterministic glitch, maybe due to smaller rounding/timing problems. I'll check some more, document the option, and release an update.
  14. That's a good point. ComposeVideo parses and counts the input speech data as frames and adds the corresponding chunks of bytes to the video output stream again (possibly already including a few bits of the next frames), so it should be okay. The interleaved streams of music/speech/video ensure that they always remain synchronized, but the speech buffer is the most sensitive part. Sending speech data too fast may go unnoticed because it halts the CPU, but sending speech data too slowly seems to be resulting in garbled speech. I'll check some more. In Mame, you can watch the many internal registers of the speech synthesizer, but it's non-trivial to see the right things at the right time.
  15. Interesting! I should check that myself, but feel free to post the files. I don't see an explanation for the speech breaking up with the 60Hz version on an NTSC console -- the pace of the speech frames should be the same. The speech synthesizer dictates the 40 speech frames per second, irrespective of NTSC or PAL. The ComposeVideo tool (called near the end of the build script) gets an option `-50Hz` or `-60Hz` and spaces out the speech frames between the Vsync commands of the video, in order to get the right pace.
  16. Double-checking myself: I get the same error with Mame 0.242, but not with Mame 0.252. If I'm not mistaken, Mame 0.243 is the minimum. You can find the official RPK file of Bad Apple at https://github.com/EricLafortune/BadApple/releases
  17. Java needs slightly different settings to specify the class files. Assuming you have downloaded or built the jar archive, on Windows: set CLASSPATH=d:\tools\VideoToolsByEric\videotools.jar java ConvertWavToLpc ..... On Linux: export CLASSPATH=/mnt/d/tools/VideoToolsByEric/videotools.jar java ConvertWavToLpc ..... (the path contains the jar/zip file name videotools.jar. If it's just a directory, java looks for loose .class files; mostly useful during development) You can also specify the archive with each invocation. On Windows java -cp d:\tools\VideoToolsByEric\videotools.jar ConvertWavToLpc ..... On Linux: java -cp /mnt/d/tools/VideoToolsByEric/videotools.jar ConvertWavToLpc ..... (the option -cp specifies the archive in which to look for ConvertWavToLpc. The alternative option -jar looks for a manifest file inside the archive, in which the name of the executable class is specified. This videotools.jar doesn't have such a manifest, mostly because it contains multiple executable classes to choose from.) Note that the class files have been compiled for Java 14 or higher, so Java 11 will refuse to load them.
  18. Thanks for the experiments! Nice setup. I still have the original hardware, but no fancy RAM cartridges, so I'm running all my code on Mame. The cartridge size requires Mame version 0.243 or higher. The balance between the sound volume and the speech volume is hardwired in the actual hardware and hardcoded in Mame, as far as I know. I'm only assuming they are doing things right... Looking at the speech data, the energy could be slightly higher, but I needed to be careful not to clip the output and the result sounded okay. You could try a more conventional cartridge like Parsec to calibrate between different setups (and perhaps Youtube videos). The speech processor indeed halts the CPU when the speech buffer starts to overflow. This has as a side-effect that the demo runs at the intended 50Hz PAL speed on 60Hz NTCSC systems during the vocal sections, because the sound/animation data streams are slowed down accordingly. I've tried to create an NTSC version (undocumented: build.sh ntsc), but the streaming code can't always keep up with the 60Hz Vsyncs for complex frames, resulting in the speech buffer eventually underflowing and the speech breaking up. The PAL version is the best approximation at this time.
  19. I've now released version 2.0 of my Bad Apple demo. This version has better vocals from the speech synthesizer, thanks to my new audio-to-speech tool ConvertWavToLpc. The vocals are more in tune and have fewer pops and other artifacts. I'll add a Youtube video in the first post of this thread. You can still find the source code and binaries on Github.
  20. We already have a few options to convert audio files to speech coefficients, suitable for our beloved speech synthesizer: QBox Pro, BlueWizard, python_wizard, and Praat with ConvertPraatToLpc. It's my pleasure to add yet another option: ConvertWavToLpc. ConvertWavToLpc uniquely applies an accurate simulation of the TMS5200/5220 speech processors, including their approximations/quirks/bugs. The approach is intended to return the best possible speech coefficients for all input audio. It has helped me to improve the vocals in version 2 of my Bad Apple demo. The tool comes with a companion tool ConvertLpcToWav to replay the speech file to an audio file, based on the same simulation of the speech processors. It for example allows you to check how the 8-bit accuracy of the output of the TI speech synthesizer accounts for a great deal of white noise. The development turned out to be a deep rabbit hole with months of research in academic papers and practical implementations. I've explored and included/rejected a range of different techniques, discussed in the documentation. The simulation of the the TMS5200/5220 speech processors is derived from the canonical code by Lord Nightmare and others in Mame. I've converted the code from C++ to Java, refactored it for my purpose, cleaned it up, and documented it. I'm happy with the resulting code. The speech processors have the usual random seeds and stateful lattice filters, but they also interleave interpolation of LPC coefficients between speech frames. As a result, optimizing the LPC coefficients of individual frames remains challenging. The quality of the output still depends on a few settings, for which I've tried to provide sane defaults. ConvertWavToLpc and ConvertLpcToWav are part of my Video Tools for the TI-99/4A. You can find the tools, documentation, and source code on Github. Notably, you can find compiled binaries (for Java 14) in the release section. Enjoy! I'm interested to hear about your experiences.
  21. I've now released version 2.0 of the Video Tools. This version adds: A brand new tool ConvertWavToLpc to convert audio files to speech files, based on an accurate simulation of the TMS5200/5220 speech processors. I'll introduce it in a separate thread. A tool ConvertLpcToWav to convert LPC speech files to audio files, based on the same simulation of the speech processors. A bug fix and enhancements for processing animations with large differences between frames. The performance of such converted animations also degrades more gracefully. As always, you can find the tools, documentation, and source code on Github. Notably, you can find compiled binaries (for Java 14) in the release section.
  22. For audio-to-speech, it's important to start from clean speech audio: avoid poor recordings, background noise, background instruments, echoes, overdubbing,... LPC speech encoding is based on a simple model of a vocal tract, so best suited for simple voices. High-pitched voices and songs are more difficult because of the sample frequency and the limited number of available LPC frequencies. It then helps to play with the options of the tool that you are using (QBox Pro, Blue Wizard, python_wizard, TMS Express, Praat) : notably frequency range of voiced frames, stability of frequencies, threshold between voiced and unvoiced frames, pre-emphasis, frame sizes. In my experience, this requires a lot of trial and error because of the combinatorial explosion of possible settings. I still need to document and release my own audio-to-speech tool, which I created in the hopes of solving this problem. It includes an exact simulation of the TMS5200/TMS5220, to automatically tune the results and clean up clicks and pops resulting from quirks/bugs in the processor. It turned out to be a rabbit hole with months of research in academic papers and technical implementations. The problem remains non-trivial. It did help to create much better results for the vocals of the Bad Apple demo, also the be released (as version 2). Let me aim for October.
  23. You're right -- it's 0x60 indeed. This byte doesn't go into the LPC FIFO buffer. The bit order of the commands and the LPC data remain tricky. On the TI-99, you can send the command byte as-is, and LPC software will already reverse the LPC bits for you, so you can send the resulting LPC bytes unchanged. If it helps, my VideoTools project has ConvertLpcToText and ConvertTextToLpc to convert between binary and readable/editable LPC files.
  24. Some general thoughts, based on my experience simulating the TMS5200 in software (Java code to be released, derived from the canonical code in Mame). It seems you have implemented and probably checked most of them, and some probably don't apply. On the input side: You mustn't forget the initial SPEAK EXTERNAL command (0x40). The input is a contiguous stream of bits, packed in a stream of bytes. The bit order is easy to get wrong, although it would consistently result in pure noise. The LPC coding tables are different for the TMS5200 and the TMS5220, but not dramatically. You probably want to end with a STOP frame (0xf) to leave the chip in a clean state. I also get garbled speech when underflowing the LPC buffer. You could start with a simple vowel sample of 16 bytes, e.g. stuffing it with compact REPEAT frames. I assume the TMS9900 doesn't resend the 17th byte either when it is held up by the /READY line. On the output side: In software, you can use the analog output or the more accurate digital output. In my experience, getting the order of the bits in the digital output wrong can result in vaguely recognizable speech.
  25. It's peculiar and fascinating... Thanks for the pointer to the video -- I was starting to think she was a vocaloid, a virtual character with a virtual voice. She's lip syncing in that video, but it turns out there's another one where she's singing live: In any case, still work to do on improving my speech synthesis.
×
×
  • Create New...