Jump to content
IGNORED

Why does CALL SOUND use millisecond durations?


Recommended Posts

I have always wondered why CALL SOUND uses milliseconds.  All it does is create a single-line sound list out of your SOUND arguments, which is then played by the ISR, which has a resolution of 1/60s (or 1/50s over the pond.)  This makes the minimum resolution of a SOUND statement ~17ms (16.‾6ms) at 60Hz, or 20ms at 50Hz.

 

Not knowing what lies deeper under the hood, I suppose XB calculates its sound list duration by converting the duration argument into the appropriate ISR duration value.  That would be the only reason I can speculate for the use of ms.  If it does, the 4.25s duration at 60Hz (255 x 1/60) would actually be 5.1s (255 x 1/50)*.  At 50Hz, the ISR duration should be roughly >D5 (]212.5[) for the upper limit of the duration argument of 4250.

 

@RXB?

 

* 255, or >FF, being the longest duration value of an ISR sound list.

  • Like 1
Link to comment
Share on other sites

12 hours ago, OLD CS1 said:

I have always wondered why CALL SOUND uses milliseconds.  All it does is create a single-line sound list out of your SOUND arguments, which is then played by the ISR, which has a resolution of 1/60s (or 1/50s over the pond.)  This makes the minimum resolution of a SOUND statement ~17ms (16.‾6ms) at 60Hz, or 20ms at 50Hz.

 

Not knowing what lies deeper under the hood, I suppose XB calculates its sound list duration by converting the duration argument into the appropriate ISR duration value.  That would be the only reason I can speculate for the use of ms.  If it does, the 4.25s duration at 60Hz (255 x 1/60) would actually be 5.1s (255 x 1/50)*.  At 50Hz, the ISR duration should be roughly >D5 (]212.5[) for the upper limit of the duration argument of 4250.

 

@RXB?

 

* 255, or >FF, being the longest duration value of an ISR sound list.

Well the CALL SOUND in XB is pretty compact with no assembly really at all.

Other then fetching the command and values from XB.

 

***********************************************************
* INIALIZATION DATA FOR SOUND
FLTS   BYTE >42,>0B,>12,>22,>00,>00,>00,>00
SNDREG BYTE >01,>FF,>01,>04,>9F,>BF,>DF,>FF,>00
***********************************************************
*                SUBPROGRAM FOR 'SOUND'                   *
* CALL SOUND(duration,frequency,volume1,...)              *
* Builds 2 blocks in VDP RAM                              *
* 1st BLOCK : >01,<ATTENUATION FOR NOISE>,<INTERRUPT COUNT>
* 2nd BLOCK : >04,>9F,>BF,>DF,>FF,>00                     *
***********************************************************
XSOUND DCEQ VRMSND,@>83CC     Insure previous sound started
       BS   XSOUND
       MOVE 9,G@SNDREG,V@VRMSND
       CALL LPARR             Duration in milliseconds
       CGE  0,@FAC            Don't wait for completion
       BS   GAA39
       DNEG @FAC                of previous sound
       DCLR @PRTNFN           Make GPL interpeters stop pre
GAA39  XML  SPEED             Insure duration
       BYTE RANGE           *  is in range
       BYTE 1               *   of 1 - 4250
       DATA 4250
* Convert duration into 1/60s of a second
       DMUL 6,@FAC            Duration * 6
       DDIV 100,@FAC          (duration * 6) / 100
       CZ   @FAC1             If duration =0
       BR   GAA4D
       INC  @FAC1             Set it to 1/60th of a second
GAA4D  ST   @FAC1,V@VRMSND+2    3rd byte of the 1st block
*                          | INTERUPT COUNT
***********************************************************
*      SOUND TABLE OF 10 BYTES IN CPU RAM (>00 - >09)
* >00 - >05 : FREQUENCY CONTROL
* >06 - >08 : ATTENUATION CONTROL
* >09       : NOISE CONTROL(non-zero = noise encountered)
* >0A       : POINTER FOR CURRENT FREQENCY CONTROL
* >0B       : POINTER FOR CURRENT ATTENUATION CONTROL
*                    >00 , >01 FOR REG 0;
*                    >02 , >03 FOR REG 1;
*                    >04 , >05 FOR REG 2;
* REG0 : >8000, REG1 : >A000, REG3 : >C000
* INITIALIZE ATTENUATION CONTROL
* REG0 : >9F, REG1 : >BF, REG2 : >DF
***********************************************************
       MOVE 12,G@ATTREG,@>8300
SOUND1 XML  SPEED             Parse the frequency value
       BYTE PARCOM         *   and insure a comma
       CALL CKSTNM            Must be a numeric
       CGE  0,@FAC            Noise if negative
       BR   SOUND2
       MOVE 8,G@FLTS,@ARG     Constant 111834
       XML  FDIV              P = 111834/FREQUENCY
       XML  SPEED             Insure in range
       BYTE RANGE
       BYTE 3               * Range: 3 - 1023
       DATA 1023
* GET THE 4 L.S.Bits BITS AND 6 M.S.Bits OF 'P'
       DSRC 4,@FAC
       SRL  4,@FAC
       DOR  @FAC,*STADDR  1st byte of frequency control byt
*                         BIT   7   6   5   4   3   2   1
*                               1  <REG>    0  <L.S.B. 4 OF
*                         2nd byte of frequency control byt
*                               0   0   <M.S.B. 6 of 'P'
       INCT @STADDR           Advance ponter for next time
       CALL ATTNUT            Get attenuation
*                        BIT    7   6   5   4   3   2   1
*                               1   <REG>   1   0   0   0
       AND  @FAC1,*PADB         1   <REG>   1   <ATTN/2 DB>
       INC  @PADB             Advance pointer for next time
* CHECK FOR END OF SOUND CALL
SOUND3 CEQ  RPARZ,@CHAT       End of statement?
       BS   SOUND5
       XML  SPEED             If not right parenthesis
       BYTE SYNCHK        *    then must be at
       BYTE COMMAZ        *      a comma

       CEQ  6,@STADDR         If not 3 regs yet
       BR   SOUND1
* 3 sound regs already - so must be noise control
       XML  SPEED             Get frequency (should be nois
       BYTE PARCOM        *     and insure a comma
       CALL CKSTNM            Must be a numeric value
       CGE  0,@FAC            If not noise-error
       BS   ERRBV
* NOISE CONTROL
SOUND2 CEQ  >FF,@>8309        * BAD ARGUMENT ERROR
       BR   ERRBA
       DNEG @FAC              -(FREQUENCY)
       XML  SPEED             Insure in range
       BYTE RANGE         *    of 1 - 8
       BYTE 1             *
       DATA 8
       DEC  @FAC1             0 - 7 (2nd BIT: 'T')
*                                           OTH, 1ST BITS:
       ST   @FAC1,@>8309
       OR   >E0,@>8309        Noise control byte:
*                        BIT  7   6   5   4   3   2   1   0
*                             1   1   1   0   0  <T>  < S >
* PUT ATTENUATION IN THE 2ND BYTE OF 1ST BLOCK
       CALL ATTNUT
       ST   @FAC1,V@VRMSND+1
*                             1   1   1   1   < ATTN/2  DB>
       BR   SOUND3            Go check for end of list
SOUND5 CLR  @VAR5             Pointer to sound table
SND05  CZ   @PRTNFN           Wait untild previous
       BS   SOUND6
       SCAN                   Is finished and
       BR   SND05              look for a break-key
       CEQ  BREAK,@RKEY       If not break-key
       BR   SND05
       BR   EXEC6C            If BREAK-KEY encountered
* LOAD SOUND TABLE
SOUND6 ST   *VAR5,@>8400      SOUND ADDRESS PORT
       INC  @VAR5             Next byte in table
       CEQ  >0A,@VAR5         If not finished
       BR   SOUND6
       DST  VRMSND,@FAC       Where the 2 blocks are
       I/O  1,@FAC            Start sound from VDP list
       BR   LNKRTN            Return to caller
  ***********************************************************
* INSURE LEFT PARENTHESIS AND THEN PARSE TO A COMMA
***********************************************************
* RXB PATCH CODE
LPARR  CEQ  COMMAZ,@CHAT
       BS   CPAR
       XML  SPEED           *  Must be
       BYTE SYNCHK          *  at a
       BYTE LPARZ           *    left parenthesis
       BR   CPAR2
CPAR   XML  SPEED
       BYTE SYNCHK
       BYTE COMMAZ
* RXB PATCH LABEL ***********
CPAR2  XML  PARSE             Do the parse
       BYTE COMMAZ          * Stop on a comma
       XML  SPEED           *  Must be
       BYTE SYNCHK          *  at a
       BYTE COMMAZ          *    left comma
       RTN

 

  • Like 2
Link to comment
Share on other sites

15 hours ago, OLD CS1 said:

I have always wondered why CALL SOUND uses milliseconds.  All it does is create a single-line sound list out of your SOUND arguments, which is then played by the ISR, which has a resolution of 1/60s (or 1/50s over the pond.)  This makes the minimum resolution of a SOUND statement ~17ms (16.‾6ms) at 60Hz, or 20ms at 50Hz.

 

Not knowing what lies deeper under the hood, I suppose XB calculates its sound list duration by converting the duration argument into the appropriate ISR duration value.  That would be the only reason I can speculate for the use of ms.  If it does, the 4.25s duration at 60Hz (255 x 1/60) would actually be 5.1s (255 x 1/50)*.  At 50Hz, the ISR duration should be roughly >D5 (]212.5[) for the upper limit of the duration argument of 4250.

 

@RXB?

 

* 255, or >FF, being the longest duration value of an ISR sound list.

Good question. It would have been easier to make the duration in 60ths of a second, which would require no conversion.  I would guess they thought it would  be easier for us  humans to get the timing we want by using milliseconds. To me 400 milliseconds seems easier than 24/60 of s second.

Maybe they intended to have an OS for europe that divided by 50?

  • Like 1
Link to comment
Share on other sites

7 minutes ago, OLD CS1 said:

Is there a difference in the subprogram between NTSC and PAL consoles?  Is

 

CALL SOUND(4250,220,14)

 

4.25s in NTSC and 5.1s in PAL?

Yes, 10 iterations are between 42 and 43 seconds long on a NTSC and about 51 seconds long on a PAL console (measured in MAME, stopped by hand).

  • Like 3
  • Thanks 1
  • Sad 1
Link to comment
Share on other sites

7 minutes ago, mizapf said:

Yes, 10 iterations are between 42 and 43 seconds long on a NTSC and about 51 seconds long on a PAL console (measured in MAME, stopped by hand).

Neat, and sad at the same time.  The NTSC/PAL discrepancy plagues Commodore and Amiga music.

Link to comment
Share on other sites

When I first encountered Classic99 way back in 2009, I actually thought the emulator was running too fast.  Tombstone City sounded almost upbeat compared to how I was used to it on the old console at 50hz.  It took me weeks to realize it was set at 60hz because it wasn't written in Britain.  :)

  • Like 4
  • Sad 1
Link to comment
Share on other sites

For BASIC, I think you would want to use familiar units like seconds. I first learned what a millisecond was from Beginner's BASIC.  "Oh yeah, 0.25 seconds, 250 ms."

 

Thinking in "ticks"of 1/50th would be more nerdy. TIBASIC insulated you from machine implementation, unlike others with PEEKs and POKEs and OMG AppleSoft shape tables. (Packed byte of 3 "turtle" commands.)


Shame there was no calibration for NTSC/PAL. At least the frequencies are both 3.579 MHz right?

 

 


 

 

  • Like 2
Link to comment
Share on other sites

Yes, TI BASIC was all about "plain user friendliness", as I would call it. This is probably also the reason why they did not include integer arithmetics, although everyone (at least in this forum) understands the properties and pitfalls of such an arithmetic. And seconds should be a simple measure.

 

To be honest, I never really tried to check the duration of CALL SOUND. Usually, you use some short sound outputs, and there is no way to really check it. Obviously, for PAL consoles, the duration is not correct.

 

The issue with the sound duration does not end there. One could argue that they should have used a different factor, but then take the sprites and their automotion. On European consoles, interrupts happen every 50th of a second, and sprites are moved by an offset each interrupt, so they are also significantly slower. If you adapted the sound duration, some games with moving sprites would probably run into problems with the background sounds.

  • Like 1
Link to comment
Share on other sites

It makes sense that native sound lists would play faster or slower than expected, as they are literally coded and played back based upon interrupt frequency.  All of that is why I had hoped BASIC would calibrate for ms and not use the interrupt frequency.  If done this way, at least our BASIC programs would have some uniformity across regions.  The exception being sprite movement and other interrupt-driven events.

  • Like 1
Link to comment
Share on other sites

I think the CALL SOUND feature could have been calibrated for both if there was a region check built in.

 

NTSC machines, which are most common, would simply have this particular value as zero, while if PAL then the value of 1 would be loaded.

 

If NTSC machine (region check value is 0), use default duration value (1/60 or 4.25) for CALL SOUND

If PAL machine detected (region check value is 1), use 1/50 duration value (5.1) for CALL SOUND.

 

~Ben

Edited by ColecoFan1981
Link to comment
Share on other sites

Yep. For the same reason that CALL SOUND takes HZ for the frequency. To put it in units more comfortable for humans. It still gets converted down to frames for time and ticks for frequency. ;)

 

Link to comment
Share on other sites

5 hours ago, ColecoFan1981 said:

I think the CALL SOUND feature could have been calibrated for both if there was a region check built in.

 

NTSC machines, which are most common, would simply have this particular value as zero, while if PAL then the value of 1 would be loaded.

 

If NTSC machine (region check value is 0), use default duration value (1/60 or 4.25) for CALL SOUND

If PAL machine detected (region check value is 1), use 1/50 duration value (5.1) for CALL SOUND.

 

~Ben

Yes, but there were also some NTSC machines that ran on 100V/50Hz (half of Japan), so decoding isn't a simple binary answer here. There are flavors. . .the Japanese machines are rare in the extreme, but they do exist (I have several several Japanese brochures and a Japanese monitor in my collection, but not a console or any of the sidecars).

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

13 hours ago, mizapf said:

...

To be honest, I never really tried to check the duration of CALL SOUND. Usually, you use some short sound outputs, and there is no way to really check it. Obviously, for PAL consoles, the duration is not correct.

...

The music I typed into my TI was just a series of CALL SOUND statements, alternating with empty FOR loops to make a brute-force time delay to get the timing for each note.

First, I set the frequency (pitch) to a conversion-table I found in C. Regena's book about sound and graphics on the TI.  The duration was always something absurdly long, like two seconds.  I also specified that the computer would not wait for the sound to end before going to the next statement (negative duration?)  Then I used a FOR loop with nothing in it to get a time delay.  The ending value of the FOR loop determined the length of each note.

Anyway, to get the duration of a single iteration of the FOR loop, I did a CALL SOUND followed by a FOR loop with a really high count, like 10,000, followed by a CALL SOUND with a frequency of 10KHz to simulate silence.  I used the second hand of a clock to time the whole thing.  Dividing by 10,000 gave me the duration of a single FOR loop.

After that I just entered the appropriate ending value for each loop.

K-R.

Link to comment
Share on other sites

If it hadn't been for the second world war...

 

Today, the monitor refresh rate doesn't have to be linked to the supply frequency, but with analogue TV that was the most convenient.

 

In Europe, before the second world war, there were a lot of different voltages and frequencies, DC included, in the public grids. When rebuilding after the war it was considered an advantage if everybody did it the same way, so everything that was rebuilt aimed for 230 V 50 Hz. The few exceptions were countries where war had not raged on their soil, like the United Kingdom and Sweden. Sweden has later adapted, UK is still at 240 V, but all at 50 Hz.

 

In the US, however, there was no infrastructure destruction and USA was also pretty early with electricity in homes and industries. So although it was realized that the European system now being built was better, it was too late. Too many refrigerators were already out there to make it unrealistic to change.

 

Japan had no real choice. Although the war never reached their home islands, they were heavily bombed. After the war, they had to use what they could get. That ended up being a mess of mobile generators, collected by the winning powers in preparation for an invasion. It was too expensive to bring these devices back home, so they stayed in Japan to power the country while the grids were repaired. Since it was a mishmash of European 50 Hz and US 60 Hz generators, the decided to move those of the same type to the same end of the country. To this day Japan has both 50 and 60 Hz, together with four big converter sites, allowing for power transfer between the north and south.

  • Like 4
  • Sad 1
Link to comment
Share on other sites

Here is piece of N. American history that is mostly forgotten.

My mother told me about a massive changeout of electrical equipment when Ontario Canada (a province) and New York state ,which is on the other side of Niagara falls,

changed from 25Hz to 60Hz.

As I recall she said you either replaced your old equipment or there was a program to have techs come to your home and change motors and transformers.

 

And the internet even backs up my mother's story. 

https://www.lifebynumbers.ca/history/the-rise-and-fall-of-25-cycle-hz-electricity-in-ontario/

  • Like 2
Link to comment
Share on other sites

Such things have probably happened everywhere. In my small town of birth, Örkelljunga (population around 5000), there were six different power suppliers a hundred years ago. Each with their own transformer and own distribution network. Many of these inagurated as suppliers of some local industry and then sold what was left over to households for illumination.

It soom became obvious that it would not be feasible to continue to build a lot of parallel systems, but instead a power supplier could lease capacity in a network owner's grid, and vice versa. For that to be possible they had to unite on a common specification. Which in Sweden became 220/380 VAC 50 Hz. Today normalized with the rest of Europe to 230/400 V. There were 25 Hz and DC suppliers here too before this era.

Still today the Swedish railways run on 16 2/3 Hz at 16 kV. Denmark uses 25 kV at 50 Hz. This again is because Sweden was early adopters. With companies like ASEA in the country, electric railway propulsion was early and expanded a lot during that same second world war, due to the shortages of coal. Back then, traction motors ran better on lower frequencies and it also made it more difficult to steal electric current from the railway supply lines.

A drawback of higher frequencies is that motors become less effective. Smaller, but less effective. In the aircraft industry 400 Hz is common, but there low weight is considered more important than high efficiency.

 

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...