![]() |
![]() |
#81 |
Registered User
Join Date: Oct 2009
Location: Germany
Posts: 3,326
|
@roondar:
I know there exists plain xm players but I meant something like phx player (play music + play sound fx samples). @saimon69: I think dbm (2 commands at the same time) can do this already. Choose 4 channels and audio mode "Paula: DMA 8 bit stereo". However, with using dbm you have all the features it brings = more control. Last edited by daxb; 14 July 2019 at 13:12. |
![]() |
![]() |
#82 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,464
|
@daxb:
I completely missed that bit. Not sure then, maybe the exist but something tells me a lot of Amiga games just use mods or go straight to streamed samples/mp3's. |
![]() |
![]() |
#83 |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,581
|
After some more testing I will release V5.3 on Aminet during the following days. The beta-version, which was successfully tested by mcgeezer and me, is already availble for anybody interested:
http://sun.hasenbraten.de/~frank/TEST/ptplayer53.lha I am announcing it here, because it has some more improvements and fixes than previous releases. From the Readme: Code:
5.2: - Make it work with broken mods, which have a sample repeat length of zero. - Never break looped samples with sound effects, except we have looped samples on all four channels at once! - New variable _mt_SongEnd to automatically stop the song when having played the last position. Don't use it! Doesn't work perfectly yet. 5.3: - No longer clear the first word of each sample for idle looping. Either we have a good Amiga tracker MOD with repeat-length one, which already cleared that word, or we have a PC tracker MOD with a zero repeat length. In the latter case the idle loop will point to address $0. Make sure that the word at this address is cleared! - Treat samples with a length of one word the same as with zero length as a workaround for broken PC trackers. - Changed APTR to void* in the C headers, for better Kickstart 1.x OS header file compatibility. ![]() Most important changes were that the first word of samples is no longer cleared, which improves compatibility with PC trackers and zero repeat-length. In this case I'm using $0 for idle-looping, as proposed by Don_Adan here: http://eab.abime.net/showpost.php?p=...6&postcount=20 And a fix for samples with a length of one word, which appear in broken PC tracker MODs (the word doesn't appear in the samples!), suggested by Ross here: http://eab.abime.net/showpost.php?p=1335842&postcount=2 |
![]() |
![]() |
#84 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,536
|
Quote:
In my patches is ever in the list (corrects audio, sprites, stupid code..). It is not orthodox and Enforcer is not happy at all, but it works. And it has no side effects and that's what counts. Thanks phx. ![]() |
|
![]() |
![]() |
#85 | ||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,581
|
At first I read "pancake", which I just had for lunch.
![]() Quote:
Quote:
|
||
![]() |
![]() |
#86 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,536
|
Quote:
Sometime, for some reason or simply by mistake, bad code write to $0 (or read from it.., so many time i've noticed wrong $0 used instead of #0 for carelessness). Can be seen in some demos/games where there are glitches with sprites expecting $0=0 but it's not. So I always grant a simple: Code:
suba.l a0,a0 move.l a0,(a0) I have often seen the use of clr which is slower (on pure 68k) and potentially even dangerous. But yes, normally it should already be like this ![]() (I apologise for digressing) |
|
![]() |
![]() |
#87 |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,581
|
You're right, you should not expect that $0 is zeroed.
In ptplayer I decided to let the developer initialise $0 in the main program. So you may still use it for other purposes as long as you are playing a real Amiga tracker MOD, without any zero repeat-length. |
![]() |
![]() |
#88 |
Registered User
Join Date: Feb 2018
Location: London / UK
Posts: 112
|
I had some trouble with this at first but then realised I had an old version and the latest one was easier to set up and the C header came quite handy.
Now I've got some music and a sound effect working without issues which is amazing so thank you! Also, is there a recommended way of splitting the mod into pattern and sample data? |
![]() |
![]() |
#89 | |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,581
|
Quote:
For my games I wrote the following portable C source: Code:
/* * Splits a standard SoundTracker/ProTracker MOD file into two parts: * - <name>.trk : MOD data (header, sample info, song arrangement, patterns) * - <name>.smp : MOD samples (to be loaded into Chip RAM) * * Usage: splitmod <name> * * Written by Frank Wille in 2013. */ #include <stdio.h> #include <stdlib.h> #include <string.h> static size_t filesize(FILE *fp,const char *name) { long oldpos,size; if ((oldpos = ftell(fp)) >= 0) if (fseek(fp,0,SEEK_END) >= 0) if ((size = ftell(fp)) >= 0) if (fseek(fp,oldpos,SEEK_SET) >= 0) return (size_t)size; fprintf(stderr,"Cannot determine file size of \"%s\"!\n",name); return 0; } static int splitmod(char *name,unsigned char *mod,size_t len) { unsigned char *p; unsigned char maxpat; char *namebuf; size_t smp_off; FILE *f; int werr = 1; int i; /* buffer for new name with .trk or .smp extension */ namebuf = malloc(strlen(name) + 5); if (!namebuf) { fprintf(stderr,"No memory for name buffer!\n"); return 1; } /* determine number of patterns */ for (p=&mod[952],maxpat=0,i=0; i<128; p++,i++) { if (*p > maxpat) maxpat = *p; } /* samples reside behind the patterns */ smp_off = ((size_t)(maxpat+1) << 10) + 1084; /* write the tracker part */ sprintf(namebuf,"%s.trk",name); if (f = fopen(namebuf,"wb")) { if (fwrite(mod,1,smp_off,f) == smp_off) { fclose(f); /* write the sample part */ sprintf(namebuf,"%s.smp",name); if (f = fopen(namebuf,"wb")) { if (fwrite(mod+smp_off,1,len-smp_off,f) == len-smp_off) werr = 0; fclose(f); } } } if (werr) { fprintf(stderr,"Cannot write \"%s\"!\n",namebuf); return 1; } return 0; } int main(int argc,char *argv[]) { int rc = 1; FILE *f; if (argc != 2) { fprintf(stderr,"Usage: %s <name>\n",argv[0]); return 1; } if (f = fopen(argv[1],"rb")) { size_t len; unsigned char *mod; len = filesize(f,argv[1]); if (len) { mod = malloc(len); if (mod) { if (fread(mod,1,len,f) == len) rc = splitmod(argv[1],mod,len); else fprintf(stderr,"Read error (\"%s\")!\n",argv[1]); } else fprintf(stderr,"Out of memory!\n"); } fclose(f); } else fprintf(stderr,"Cannot open \"%s\"!\n",argv[1]); return rc; } |
|
![]() |
![]() |
#90 |
Registered User
Join Date: Feb 2018
Location: London / UK
Posts: 112
|
Works perfectly, thanks!
|
![]() |
![]() |
#91 |
Registered User
Join Date: Feb 2018
Location: London / UK
Posts: 112
|
After a sound effect stops playing I'm left with a somewhat quiet continuous high pitched voice on the channel. This happens with and without a module playing. Any ideas what could be the cause?
I tried adjusting volume and the sample length but no change. If I set the length to half the noise afterwards is the same. Also I checked that the sample ends with zeroes. |
![]() |
![]() |
#92 | |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,581
|
Quote:
![]() Sound effect samples have to be in the same format as the music samples, which means: make sure the first two bytes are cleared! The player uses the first two bytes for idle-looping. |
|
![]() |
![]() |
#93 | |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,458
|
@phx I've installed the player (latest from aminet, with unmodified ptplayer.h header!) into my program and I have issues/questions
- the module replay works fine. I have created a custom module where some bass notes are played wrong though. Play okay in VLC. Doesn't matter much... Do you want to look at it? I can zone it. - I'm not able to play sounds properly. Do you have a small example on how to do that? I've used the structure and all but nothing plays (it stops the music when I play a sound) - I'd like to be able to stop the music / play the music only once. Possible? - I'd like to play sounds without the music started. When I set mt_Enable = 1 before playing a module, I have a trashed sound playing, then nothing. Quote:
Code:
import subprocess,os,glob outdir = "amiga/sfx" for wav_file in glob.glob(os.path.join("../sound/*.wav")): raw_file = os.path.join(outdir,os.path.splitext(os.path.basename(wav_file))[0]+".raw") cmd = ["sox",wav_file,"--bits","8","-r","16000","--encoding","unsigned-integer",raw_file] subprocess.check_call(cmd) with open(raw_file,"rb") as f: contents = f.read() with open(raw_file,"wb") as f: f.write(b"\x00"*2) f.write(contents) Code:
static UWORD hardware_period(int bytes, int hertz) { return ((UWORD) 100000000L / (bytes*hertz*28)); } SoundPlay::SampleNode *SoundPlay::load(const MyString &filename, int key, bool) { init(); SoundPlay::SampleNode *rc = 0; SampleNode sn; MyFile sf(filename); StreamPosition sz = sf.size(); if (sz>0) { sn.cvt.sfx_ptr = AllocMem(sz,MEMF_CHIP); if (sn.cvt.sfx_ptr == nullptr) { abort_run("Cannot allocate %d bytes",sz); } } else { abort_run("Cannot read sound file %s",filename); } sn.cvt.sfx_len = sz / 2; sn.cvt.sfx_per = hardware_period(sz,16000); sn.cvt.sfx_vol = 50; sn.cvt.sfx_cha = -1; sn.cvt.sfx_pri = 1; sf.read_bytes(sn.cvt.sfx_ptr,sz); std::pair<SampleList::iterator,bool> rval = sample_node.insert(std::make_pair(key,sn)); SampleList::iterator it = rval.first; rc = &(it->second); return rc; } |
|
![]() |
![]() |
#94 | |||||||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,581
|
Quote:
When notes from low or high octaves don't play then the reason is most likely the limitation of the original Amiga Protracker. PC-trackers often support more octaves than Protracker. Milkytracker has some compatibility switches for it (e.g. "PT 3 octaves limit"). Check that first. Quote:
Attached you find a minimal example source, which plays a Mod while waiting for left mouse button. Press button again to play a sample and another time to quit. It's in assembler and really ugly as it writes to the audio hardware while multitasking it running. But it should be easy to understand. Quote:
![]() You (or I) can hack something, if you really need it. Or just use an "F00" command in the MOD's last pattern to stop it. Quote:
Quote:
Quote:
Your sox-call with "--encoding unsigned" is likely wrong. I'm using my own portable converter (tools/wavtoraw.c in all my published game sources) which converts to mono at 11025Hz. Then I can play these samples with a period of 320. Quote:
Last edited by phx; 07 December 2020 at 11:49. |
|||||||
![]() |
![]() |
#95 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,458
|
thanks for your help & detailed answer. You're probably right about the module. I made that myself very quickly and it may not run on a real amiga.
I was able to fix my code. In particular this was plain wrong: Code:
static UWORD hardware_period(int bytes, int hertz) { return ((UWORD) 100000000L / (bytes*hertz*28)); } Code:
static UWORD hardware_period(int bytes, int hertz) { return ((UWORD) 100000000L / (bytes*hertz*28)); } Code:
static UWORD hardware_period(int hertz) { return 100000000L / (hertz*28); } I'm sure I had hardcoded that at some point, and it didn't work, but there were too many things that didn't work. BTW there's a small error in your sample code (that you definitely should include in the player package). The sfx structure ends with 2 bytes, not words. It works but by luck. Fix: Code:
sfx: dc.l sample dc.w (sampleend-sample)/2,320,64 dc.b -1,1 |
![]() |
![]() |
#96 | |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,581
|
Great! I already noticed the update of your game. Very nice! Have check it out over the holidays...
Quote:
![]() |
|
![]() |
![]() |
#97 |
Mostly Harmless
Join Date: Aug 2004
Location: Northern Ireland
Posts: 1,159
|
I've started using v5.3 of this lib in my game - thanks
![]() It works well, but bangs on the CIAB registers and level 6 interrupt vector. The game can run off hard drive and quit back to Workbench, so it is reasonably system friendly and I think I'd prefer if it was able to allocate the CIAB timer interrupts from the OS as well. The previous replayer code I was using did this sort of thing. So has anyone made a version of ptplayer that adds the interrupts via AddICRVector? It looks like I should create a CIAB TA interrupt pointing at mt_TimerAInt and a CIAB TB interrupt pointing at mt_TimerBdmaon? Plus some cleanup to remove messing with the autovectors. The game doesn't actually multitask though, so maybe there's nothing to be gained from doing this? Just call _mt_remove_cia when I partially restore the system (to load files via DOS) and _mt_install_cia afterwards? |
![]() |
![]() |
#98 |
Mostly Harmless
Join Date: Aug 2004
Location: Northern Ireland
Posts: 1,159
|
Can you have sound effects repeat with ptplayer?
|
![]() |
![]() |
#99 | ||||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,581
|
Quote:
Quote:
Quote:
In the still unreleased V5.4 I changed that, following a suggestion of Ross, so that the interrupt vector stays the same. Quote:
Not easily. Currently a music channel is blocked as long as an effects sample is played. For unblocking it waits for the audio-interrupt, which indicates that the sample has played once completely. |
||||
![]() |
![]() |
#100 | |||
Mostly Harmless
Join Date: Aug 2004
Location: Northern Ireland
Posts: 1,159
|
Quote:
![]() Quote:
Ah, so that's what it's doing. With AddICRVector the TA and TB interrrupts are separated for you so ... the TA routine would set a pointer to and start the timer for DMA enable, the DMA enable routine would set a pointer to and start the timer for repeat, the repeat timer routine would start the TA timer again. I think ![]() Quote:
The system I had before did the same thing except it supported repeating the effect, but repeats were only actually used for two effects so I'll see if I can work around it. Maybe a future enhancement for ptplay? ![]() |
|||
![]() |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
MOD-player with external sound effects | phx | Coders. Asm / Hardware | 14 | 18 June 2012 10:41 |
Amiga Forever&Protracker bad sound | moriez | support.WinUAE | 14 | 06 January 2009 01:26 |
What was the first Amiga tracker to support external midi instruments | Kola | Amiga scene | 3 | 09 December 2008 19:20 |
Sound/Protracker package | Dunny | request.Apps | 3 | 23 July 2008 19:17 |
Sampled sound player? | cdoty | Coders. General | 7 | 25 August 2007 16:21 |
|
|