English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General > Coders. Releases

 
 
Thread Tools
Old 14 July 2019, 12:34   #81
daxb
Registered User
 
Join Date: Oct 2009
Location: Germany
Posts: 3,303
@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.
daxb is offline  
Old 14 July 2019, 12:41   #82
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,409
@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.
roondar is offline  
Old 08 August 2019, 11:29   #83
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
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.
V5.2 was used in Trap Runner and Celtic Heart but never officially released, because I was waiting for a patch from StingRay concerning _mt_SongEnd (since the beginning of this year ). So just forget about this feature for now.

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
phx is offline  
Old 08 August 2019, 12:12   #84
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by phx View Post
In the latter case the idle loop will point to address
$0. Make sure that the word at this address is cleared!
Yep, clearing $0 is a panacea.
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.
ross is offline  
Old 08 August 2019, 14:51   #85
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by ross View Post
Yep, clearing $0 is a panacea.
At first I read "pancake", which I just had for lunch.

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.
Yes, I'm also using it for empty sprites. And the Enforcer shouldn't notice any Audio- or Sprite-DMA access.

Quote:
And it has no side effects and that's what counts.
Exactly. Depending on a memory-allocation function or adding a Chip-RAM section could have caused trouble in certain situations.
phx is offline  
Old 08 August 2019, 16:28   #86
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by phx View Post
Yes, I'm also using it for empty sprites. And the Enforcer shouldn't notice any Audio- or Sprite-DMA access.
In my patches I never take it for granted that it is zeroed.
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)
Zeroed ax register can also be used to move #0 in custom registers.
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)
ross is offline  
Old 09 August 2019, 10:25   #87
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by ross View Post
In my patches I never take it for granted that it is zeroed.
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.
phx is offline  
Old 15 October 2019, 21:15   #88
dodke
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?
dodke is offline  
Old 16 October 2019, 16:15   #89
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by dodke View Post
Also, is there a recommended way of splitting the mod into pattern and sample data?
You have to find the start address of the first sample in your MOD file. Split the file at that offset.

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;
}
phx is offline  
Old 17 October 2019, 11:33   #90
dodke
Registered User
 
Join Date: Feb 2018
Location: London / UK
Posts: 112
Works perfectly, thanks!
dodke is offline  
Old 18 October 2019, 14:32   #91
dodke
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.
dodke is offline  
Old 18 October 2019, 21:57   #92
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by dodke View Post
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?
Yes. And I should really add that to the Readme, for the next release. This is asked frequently.

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.
phx is offline  
Old 21 December 2019, 15:22   #93
jotd
This cat is no more
 
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,162
@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:
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.
same format means? I'm using a custom python script to convert .wav files to 8 bits, adding 2 zeroes at start. Is that unsigned/signed raw?

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)
here's my sample loading code (C++):

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;
}
I'm playing like this: mt_playfx(custom_base,&sn.cvt);
jotd is offline  
Old 21 December 2019, 19:26   #94
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by jotd View Post
- 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.
What is VLC? The media player? It plays MODs?
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:
- 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)
It stops the music and then there is no sound effect but silence? On all channels? Stopping music on one channel for the effect to play would be normal. There must be something wrong with the parameters (pointer, period, volume...).

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:
- I'd like to be able to stop the music / play the music only once. Possible?
Theoretically, yes. The player knows when the song starts from the beginning. But it's not yet implemented. Stingray wanted to send me a patch about it - over a year ago...

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:
- 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.
Never set mt_Enable without having called mt_init for a module! You do not need mt_Enable for playing sound effects - it is only needed for music. Leave mt_Enbable at zero and just call mt_playfx. Samples will also play without music.

Quote:
same format means?
Normal Amiga samples, but with the first two bytes cleared.

Quote:
I'm using a custom python script to convert .wav files to 8 bits, adding 2 zeroes at start. Is that unsigned/signed raw?
Amiga samples are 8-bit signed!

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:
here's my sample loading code (C++):
You may check your hardware_period() function. I don't think it is correct to have a different period for different samples lengths. The rest looks ok, although my C++ is rusty.

Last edited by phx; 07 December 2020 at 11:49.
phx is offline  
Old 21 December 2019, 22:20   #95
jotd
This cat is no more
 
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,162
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));
}
for the reason you explained, and also because (UWORD) 100000000L wraps to a small value, and the period always ended up being zero (when the cast isn't useful, I copied that wrongly from somewhere like Amiga Bible). fixed:
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
jotd is offline  
Old 21 December 2019, 23:09   #96
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by jotd View Post
I was able to fix my code.
Great! I already noticed the update of your game. Very nice! Have check it out over the holidays...

Quote:
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.
Indeed! Thanks. It's always good when a second eye-pair has a look.
phx is offline  
Old 20 July 2020, 23:07   #97
girv
Mostly Harmless
 
girv's Avatar
 
Join Date: Aug 2004
Location: Northern Ireland
Posts: 1,109
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?
girv is offline  
Old 21 July 2020, 18:36   #98
girv
Mostly Harmless
 
girv's Avatar
 
Join Date: Aug 2004
Location: Northern Ireland
Posts: 1,109
Can you have sound effects repeat with ptplayer?
girv is offline  
Old 23 July 2020, 16:53   #99
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by girv View Post
It works well, but bangs on the CIAB registers and level 6 interrupt vector.
I wrote this player for games and demos which take over the hardware and do not use the OS.

Quote:
The game can run off hard drive and quit back to Workbench, so it is reasonably system friendly
The CIA-B timers used by ptplayer are not used by AmigaOS. And mt_remove_cia() restores everything, including the level 6 vector and the contents of the CIA registers. So when your game disables the OS while it runs it should be pretty safe, but I wouldn't recommend it.

Quote:
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.
Yes, you will need some cleanup. The TA interrupt for the music will set the level 6 vector first to the TB interrupt handler to enable audio DMA, and then to a second TB interrupt handler to set the repeat length for the samples. Finally the vector points back to the TA music interrupt.

In the still unreleased V5.4 I changed that, following a suggestion of Ross, so that the interrupt vector stays the same.

Quote:
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?
May work. But that's quite hacky. I wouldn't do that.

Quote:
Originally Posted by girv View Post
Can you have sound effects repeat with ptplayer?
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.
phx is offline  
Old 23 July 2020, 17:28   #100
girv
Mostly Harmless
 
girv's Avatar
 
Join Date: Aug 2004
Location: Northern Ireland
Posts: 1,109
Quote:
Originally Posted by phx View Post
I wrote this player for games and demos which take over the hardware and do not use the OS.
Of course That wasn't meant as a criticism, sorry. I was looking in to adapting my replay code to handle sound effects as well but ptplay saved me some head scratching. Love it.


Quote:
Originally Posted by phx View Post
The TA interrupt for the music will set the level 6 vector first to the TB interrupt handler to enable audio DMA, and then to a second TB interrupt handler to set the repeat length for the samples. Finally the vector points back to the TA music interrupt.

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:
Originally Posted by phx View Post
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.

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?



girv is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 09:50.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.56760 seconds with 14 queries