[[Image:wave1.gif]]
'''Fig 1. An amplitude/time graph showing the waveform of the original sound'''
[[Image:wave2.gif]]
'''Fig 2. An amplitude/time graph showing the waveform of the original sound. The crosses indicate the amplitude measured at each sample time and the dotted lines indicate the the time of each measurement. The duration of time between each dotted line, defined by the sample rate, is equal to the duration of a sample. From this it can be seen that each sample has a finite and equal duration.''
[[Image:wave3.gif]]
'''Fig 3. An amplitude/time graph showing the waveform of the original sound. As in Fig 2, the crosses indicate the amplitude measured at each sample time. The dotted line shows the waveform generated by sampling. The final value of each sample is defined to be the amplitude measured at the time of measurement.'''
[[Image:wave4.gif]]
'''Fig 4. An amplitude/time graph showing the sampled waveform. This waveform was generated at a high sample rate, and therefore the resulting waveform has a shape which is similar to the original. This waveform is the type you can see in a audio recording program like Goldwave.'''
[[Image:wave5.gif]]
'''Fig 5. An amplitude/time graph showing the waveform of the original sound. As in Fig 2, this graph shows the amplitude of each measurement, and the dotted line indicates the time of measurement. This graph was created using a low sample rate. Notice that the time between each measurement is longer compared to Fig 2.'''
[[Image:wave6.gif]]
'''Fig 6. An amplitude/time graph showing the waveform of the original sound. As in Fig 3, the crosses indicate the amplitude measured at each sample time, and the dotted line shows the waveform generated by sampling. This graph shows the resulting waveform generated using a low sample rate.'''
[[Image:wave7.gif]]
'''Fig 7. An amplitude/time graph showing the sampled waveform. This waveform was generated at a low sample rate, and therefore the resulting waveform is much more coarse compared to Fig 4. Notice that although the general shape is similar to the original waveform, and much of the smoothness is is lost between the time of each measurement. The loss of smoothness also means loss of information since this waveform is not the same as the original. If you compare this graph against Fig 4 then you will see that the lower the sample rate, the more information is lost. The higher the sample rate, the less information is lost. Therefore, to record a sound, it is best to use a high sample rate'''
Notes:
So when a cassette is loaded the following occurs:
# 1. system loader recognises and loads "program for fast-loader".# 2. "program for fast loader" takes control and loads the data from the fast-loader block(s) into computer memory# 3. when loading has completed, the program is executed.
Notes:
# 1. a CPC without a disc interface (e.g. a CPC464, CPC464+ or KC Compact) will start-up in cassette mode. For a CPC with a disc interface attached (or internal), you must type |TAPE to enter cassette mode.
You can test if the computer is operating in cassette mode by typing RUN". If you see "Press PLAY then any key", then the computer is operating in cassette mode. If there is an error, then the computer is not operating in cassette mode.
Notes:
1. The CPC464 and CPC464+ have a cassette player built in. To connect a cassette player to the CPC664, CPC6128 or KC Compact then you must use a lead. 2. It is not known exactly how the amplitude of the sound from the cassette corresponds to the final "0" or "1" measurement.
samp2cdt uses a crude method to perform this conversion.
For a 8-bit signed sample: * if the amplitude is 0..128, then the final measurement will be "1". * if the amplitude is -128..0 then the final measurement will be "0".
=== Writing ===
A high level can be written using the following Z80 instructions:
<pre>
ld b,&f6 ;; I/O port address for PPI 8255 port C
;; (PPI 8255 port C is operating as output.)
set 5,a ;; set cassette write output to high level
out (c),a ;; output level</pre>
A low level can be written using the following Z80 instructions:
<pre>
ld b,&f6 ;; I/O port address for PPI 8255 port C
;; (PPI 8255 port C is operating as output.)
res 5,a ;; set cassette write output to low level
out (c),a ;; output level</pre>
The amplitude of the output waveform is not amplified, therefore if you wish to record the cassette audio direct from an Amstrad you will need to amplify the waveform.
|pilot|sync|data|trailer|
'''pilot This is also refered to as "leader" by some documents.'''
This is constructed from a repeated waveform often with a fixed number of repetitions defined also refered to as "leader" by the loading systemsome documents.
The shape This is constructed from a repeated waveform often with a fixed number of the waveform is known repetitions defined by the loader program and this is used to identify the pilot waveform from other waveforms that may be present (e.g. noise)loading system.
The pilot shape of the waveform is often long, so that known by the loader doesn't need program and this is used to see the start of identify the pilot waveform in order to load the blockfrom other waveforms that may be present (e.g. noise).
The loader program will test the incoming waveform, checking it against the parameters defined for the pilotis often long, before so that the waveform is accepted as loader doesn't need to see the pilot waveform. (e.g. the number start of repetitions must be some defined minimum value). The incoming waveform must fall within these specifications otherwise the waveform is not accepted as a pilot waveform. sync ("synchronisation") The sync is a waveform which is different to the pilot, and this defines the end of the pilot and the start of the data. When this sync has been detected, the loader knows that there is data following, and that the loader is always at the same point in the data stream. i.e. the loader program is synchronised order to a specific point in load the data waveform.data This is the actual data which is composed of waveforms defining "0" and "1" data bitsblock.
The first element of loader program will test the data may be a marker or id which mayincoming waveform, checking it against the parameters defined for examplethe pilot, indicate before the type of data in waveform is accepted as the block or pilot waveform. (e.g. the number of repetitions must be some defined minimum value). The incoming waveform must fall within these specifications otherwise the blockwaveform is not accepted as a pilot waveform.
The remaining bits will define the data and zero or more checksums.'''sync ("synchronisation")'''
The whole data may consist of sync is a single block with a single location waveform which is different to the pilot, and length (ethis defines the end of the pilot and the start of the data.g. one block for a screen another for When this sync has been detected, the loader knows that there is data)following, or multiple blocks each with their own location and lengththat the loader is always at the same point in the data stream. i. (e.g. one block for screen and the loader program is synchronised to a specific point in the data)waveform.
'''data''' This is the actual data which is composed of waveforms defining "0" and "1" data bits. The first element of the data may be a marker or id which may, for example, indicate the type of data in the block or the number of the block. The remaining bits will define the data and zero or more checksums. The whole data may consist of a single block with a single location and length (e.g. one block for a screen another for data), or multiple blocks each with their own location and length. (e.g. one block for screen and data) The location and lengths of the blocks may be in the data stream itself, or they may be in a preceeding block, or may be hard-coded into the loader program. '''trailer''' The trailer always follows the data. Some loaders may not have a trailer. The two main purposes of the trailer are to ensure that the waveform of the last data bit in the data is constructed correctly and to provide some time in which the loader can prepare for the next block.
The exact definition of the loading systems's audio waveform is defined by the loader program.
samp2cdt has a number of decoder algorithms which recognises the audio waveform of various loading systems. These decoders read the waveform using a similar method to the loader program itself. These decoders have been created by examining the instructions of each loader program and the graph of the waveform in a sound recording package.
== Example of a typical loading system==
The data on cassette actually consists of changing 0 and 1 levels. (a "level" is a magnitude of a value). The loader measures the time between each "level transition" where a "level transition" is the change from a "0" to a "1" level or the change from a "1" to a "0" level. The level can be timed using the following Z80 instructions: ;; - keep testing the state of bit 7 of PPI 8255 port B ;; - update the counter to record the number of tests done ;; - when bit 7 of PPI 8255 port B changes state, stop testing. ;; counter will hold the total number of tests made. ;; ;; B = &F5 (I/O address of PPI 8255 input port B) ;; C = previous data read from PPI port B ld d,0 ;; initialise count to 0 .loop inc d ;; increment count in a,(c) ;; read input to PPI 8255 port B xor c ;; exclusive-or with previous data read from PPI 8255 port B and %10000000 ;; isolate bit 7 ;; if result is 0, then the state of bit 7 that has ;; been read is the same as the previous state. i.e. bit 7 has not changed state. ;; if result is not 0, then the state of bit 7 has changed. ;; e.g. if bit 7 was previously 1, it is now 0. if bit 7 was previously 0, it is now 1. jr z,loop ;; when execution reaches here we know that bit 7 has changed state and D ;; contains the number of tests.
== Loader operation== The loader generally operates in this way: 1. time a wave. Is the duration of the wave within the minimum and maximum duration required for the pilot. If yes, go to 2, else go to 1. 2. We might have seen a wave from the pilot signal. time a wave. Is the duration of this wave within the minimum and maximum duration required for the pilot. If yes, increment number of waves seen, go to 2, else go to 1. 3. Have we seen the minimum number of pilot waves? Yes, go to 4, else go to 2. 4. time a wave. Is the duration of the wave within the minimum and maximum duration required for the sync? 2. Each Z80 instruction takes a finite time to execute. The execution time depends on the computer. If the timing of the Z80 instructions used by the test algorithm is known and predictable, then the time for each test can be calculated. Now, since the count represents the number of tests made before the condition is true (i.e. bit 7 changes state), the total time for the condition to be true, is the sum of the time for each test made. If each test always takes the same time, then the total time is the number of tests multiplied by the time for one test. In the Amstrad computer, all Z80 instructions execute in multiples of 1us (microsecond) regardless of their location in RAM. This fact simplifies this calculation.
Checksum