elks icon indicating copy to clipboard operation
elks copied to clipboard

PCM player for elks 0.9

Open drachen6jp opened this issue 7 months ago • 8 comments

https://github.com/drachen6jp/ems_pcm

Previously, I wrote software to play PCM with beep. However, it was unable to run under the current elks xms system environment, so I have improved it.

It is written on the assumption that FS and GS are already set to flat 4G in unreal mode. On a 32-bit CPU, unreal mode is used to expand PCM to memory, and IO access to the 8254 is similarly performed during playback.

I decided to use EMS for 16-bit machines. It worked on a PCEM award286 machine, but I don't have the actual machine. For PC-98, I have three types of EMS boards, so it is compatible with those. It is also compatible with the NekoProject2 emulator.

I will rewrite it again once the OS itself supports EMS. Well then,

drachen6jp avatar May 23 '25 07:05 drachen6jp

Hello @drachen6jp,

Thank you for porting your PCM sound player to ELKS!

Is this for 386 CPU only, or would you like it to run on 286 also?

It is written on the assumption that FS and GS are already set to flat 4G in unreal mode.

Yes, this assumption is OK, since FS and GS are set to flat 4G in the enable_unreal_mode function in unreal.S. Of course, there are no FS and GS registers on 286.

I decided to use EMS for 16-bit machines.

I am thinking, rather than using the complicated EMS with multiple board issues, why not use XMS memory and the LOADALL block move functions we now have working to copy from XMS/main memory? For 386+ systems, the existing linear32_fmemcpy routines using unreal mode in fmemory.S could be used to copy to/from XMS as well. Then perhaps EMS would not be required?

I am thinking we could add a C library routine that would perform block moves to and from XMS for user programs, without having to know whether running on 286 vs 386. Also, a user program allocation routine for XMS memory could also be added. This was already being discussed with @rafael2k to allow access to large amounts of extra memory for his web browser project. In this way, your PCM player could automatically run on a wide variety of IBM PC and PC-98 machines without worrying about EMS board types.

I will rewrite it again once the OS itself supports EMS.

I think it may be some time before ELKS supports EMS directly, because of the complication of supporting a variety of EMS boards, and lack of ability of testing. In general, it seems that perhaps using XMS memory with LOADALL or unreal mode would be better for ELKS, with the ability to run on all 286 and 386 machines with XMS.

What do you think?

Thank you!

ghaerr avatar May 23 '25 18:05 ghaerr

Thank you for your reply.

Is this for 386 CPU only, or would you like it to run on 286 also?

Both can play PCM.386 system uses highmemory with unrealmode,and 16bit machines use low memory bank access with EMS.

I considered using xms and loadall for block transfer, but first of all there was a speed problem.

This program does what it can during an interrupt. For a 286 12MHz class, it assumes a cycle of about 4000Hz. It seemed that block transfer combined with loadall would not be able to keep up with that.

So I decided to try using bank memory this time. It was a challenge. Also, using EMS would allow 8086 and V30 to use a lot of memory, so I was hoping for that. When I tried this on a real machine, I didn't get the results I expected (V30 can only play at a low quality of about 2000Hz (just at the edge of the human audible range)).

I understand that it would be very, very difficult for elks to support EMS. It was also difficult to control the hardware EMS to write this program. I was being selfish and hoping that the OS would support this. I'm happy to hear that xms will be released to user programs.

Thank you!

drachen6jp avatar May 23 '25 19:05 drachen6jp

I see, so the big issues is non-386 machines, since unreal mode allows direct access to XMS memory for 386+.

I'm not that familiar with EMS specifics, but sounds like you are using large EMS memory preloaded with the PCM data, then bank-switching for very fast access to the next 64K PCM data?

When I tried this on a real machine, I didn't get the results I expected (V30 can only play at a low quality of about 2000Hz

Does this mean that V30 or older machines aren't going to be fast enough to play 4000HZ PCM data even with EMS?

I suppose perhaps your approach is best: support 386+ machines using unreal mode, and all others, including 80286 using EMS.

Trying to get LOADALL to work without copying data could be quite tricky under multitasking OS, unless all PCM code executed only during interrupts disabled, until segment base register cache reset for continuing normal operation. If you want to talk about using LOADALL for this, we can continue discussion of how that might work.

It was also difficult to control the hardware EMS to write this program.

Well, if your EMS code were put in a separate file and a standard API developed for it, then it might be easy to add these to ELKS C library in the future, for support of other user-EMS programs, as well as support for different EMS boards.

I understand that it would be very, very difficult for elks to support EMS. I was being selfish and hoping that the OS would support this.

It is OK - if the EMS access wouldn't be shared across separately running ELKS processes, then it might be just as well to have EMS support built into C library function instead of kernel, since the kernel wouldn't be doing much, other than handling a new system call to switch banks. So perhaps if you want to continue to support EMS with your PCM or other programs, we can add your EMS code to the ELKS C library. Then it will be available for others to play with, and for you to update or maintain new EMS boards.

ghaerr avatar May 23 '25 19:05 ghaerr

sounds like you are using large EMS memory preloaded with the PCM data, then bank-switching for very fast access to the next 64K PCM data?

Yes.286 12MHz machine can play about 5kHz PCM(about 2MiB) clearly with bank change.but load time is looong.

Does this mean that V30 or older machines aren't going to be fast enough to play 4000HZ PCM data even with EMS?

aand Yes,unfortunately.V30 can't play PCM well by 8254 timer.

I have no qualms about writing support code for EMS. After 0.9 is officially released with XMS fully implemented, I'll start with the PC-98 style I have. I don't have any knowledge or materials for IBM-PC, so I think the writing speed will be slow.

thanks for your advice.

drachen6jp avatar May 23 '25 20:05 drachen6jp

Hey, I had some high workload these times. I get this when trying to compile with Watcom C compiler:

owcc -c -O2 -mcmodel=l -bnone -march=i86 -std=c99 -fno-stack-check -fnostdlib -Wc,-fpi87 -Wc,-zev -Wc,-zls -Wc,-x -Wc,-wcd=303 -Wall -Wextra -I/home/rafael2k/programs/devel/elks/libc/include -I/home/rafael2k/programs/devel/elks/elks/include -I/home/rafael2k/programs/devel/elks/libc/include/watcom -D__ELKS__ -DNDEBUG -o emspcm.obj emspcm.c
emspcm.c(59): Error! E1055: Unable to open 'i86.h'
emspcm.c(1116): Warning! W131: No prototype found for function 'FP_SEG'
emspcm.c(1118): Warning! W131: No prototype found for function 'FP_OFF'
emspcm.c(1601): Error! E1031: Name 'main_used' not found in struct/union mem_usage
emspcm.c(1601): Error! E1031: Name 'main_used' not found in struct/union mem_usage
emspcm.c(1601): Error! E1031: Name 'main_free' not found in struct/union mem_usage
emspcm.c(1601): Error! E1031: Name 'main_free' not found in struct/union mem_usage
emspcm.c(1603): Error! E1031: Name 'xms_used' not found in struct/union mem_usage
emspcm.c(1603): Error! E1031: Name 'xms_used' not found in struct/union mem_usage
emspcm.c(1603): Error! E1031: Name 'xms_free' not found in struct/union mem_usage
emspcm.c(1603): Error! E1031: Name 'xms_free' not found in struct/union mem_usage
emspcm.c(1605): Error! E1031: Name 'xms_used' not found in struct/union mem_usage

I committed the Makefile here: https://github.com/rafael2k/ems_pcm

ps: In the past I also tried to run your player in real hardware (a modern lenovo thinkpad on ELKS, but I dunno why, I got no sound): https://github.com/rafael2k/elks-player/

rafael2k avatar May 23 '25 22:05 rafael2k

@rafael2k:

emspcm.c(1601): Error! E1031: Name 'main_used' not found in struct/union mem_usage

The field names in the struct mem_usage in linuxmt/mem.h change recently - these errors require that you pull the latest sources in order to compile.

@drachen6jp: what C compiler are you using to compile your project?

ghaerr avatar May 24 '25 00:05 ghaerr

Hi.@rafael2k. thanks your writing Makefile.

ps: In the past I also tried to run your player in real hardware

elks 0.9 have GDT for unreal mode.so past code was gone. I think past code can't run real 286(IBM-PC) or my code had many bugs why you cannot play pcm with before0.8.

@drachen6jp: what C compiler are you using to compile your project?

openwatcom 2.0 on gentoo linux x86_64.

drachen6jp avatar May 24 '25 00:05 drachen6jp

by the way. Can IBM-PC DMA Memory-memory transfer move Highmemory to Lowmemory ? PC-98 DMA cannot do it.

If IBM DMA can move them, this is very useful.

drachen6jp avatar May 24 '25 07:05 drachen6jp

Hello @ghaerr ,

I think I have pulled the latest elks and recompiled the libc, but I also have Error! E1055: Unable to open 'i86.h' if I do ewcc emspcm.c

Image

Is this header still available?

tyama501 avatar Jun 22 '25 08:06 tyama501

Hello @tyama501,

The i86.h header is in the OWC bld/hdr/dos/ directory and is not included in ELKS libc because this is a non-standard C header and are primarily DOS functions. You can likely get the program compiled by copying this header to the ems_pcm directory.

Thank you!

ghaerr avatar Jun 22 '25 16:06 ghaerr

Hello @ghaerr ,

I see. Yes, now I could compile it.

Thank you.

tyama501 avatar Jun 23 '25 14:06 tyama501

Hi @drachen6jp and @ghaerr ,

I have tested the ems_pcm with PC-9801RX, intel 286 12MHz with EMJ 4MB ems board.

Image

I have created 16kHz, 8bit wavefile reading the following text (by ChatGPT and converted frequency). Image

Here is the recorded video. It seems that it has been reduced to 2kHz but it is speaking :) (I don't know the high tone beep noise is expected or not) https://github.com/user-attachments/assets/c9e545f9-e926-4539-ab40-c6945802f063

Thank you.

tyama501 avatar Jun 28 '25 16:06 tyama501

It would seem the high tone beep noise should not be present, it is hard to hear the spoken text with it.

What program are you using to create the actual PCM data, is ChatGPT doing that for you?

ghaerr avatar Jun 29 '25 01:06 ghaerr

It seems that ChatGPT used some python library. This noise does not exist in the original sound so it is limitation of this hardware.

tyama501 avatar Jun 29 '25 01:06 tyama501