home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / offline / uniqwk30.zip / TALK.TXT < prev    next >
Text File  |  1993-12-20  |  14KB  |  433 lines

  1.                         Talkline - How it works.
  2.                         ~~~~~~~~~~~~~~~~~~~~~~~~
  3.  
  4.      Talkline is a sound of short duration, appended to the end of a message.
  5.      In this fist version, up to 5 seconds of sound can be added.
  6.      The purpose of this text file is to explain how the sound is coded
  7. and appended to the message.   This first version is called version "A" and
  8. has the following characterization:
  9.  
  10. 1-Sampling. - The sound bandwidth supports human voice only and so is sampled
  11.    at 5012.5Hz Hz, 8bits, with zero level at value 80h.
  12.  
  13. 2-Compression -
  14.    A - The signal is converted to 4 bits, first subtracting DC value (80h) and
  15.        using a log (base 2) conversion of the absolute value:
  16.             in           out
  17.                 0  ->  0
  18.           0.   .1  ->  1
  19.           2.   .3  ->  2
  20.           4.   .7  ->  3
  21.           8.  .15  ->  4
  22.          16.  .31  ->  5
  23.          32.  .63  ->  6
  24.          64. .127  ->  7
  25.        Now the signal is 4 bits with zero level at 0 (-16 to 15).
  26.  
  27.    B - The samples are packed 2 samples per byte, high nibble corresponding
  28.        to first sample and the low nibble to next one
  29.  
  30.         EX:
  31.         t = 0  0000hhhh  <-- 4 bit sample
  32.             1  0000LLLL
  33.  
  34.                 pack  ->  hhhhLLLL
  35.  
  36.    C - Run lenght encoded, using FFh as flag character.
  37.  
  38.        EX:
  39.        00 32 84 84 84 84 84 84 34 35 FF 54 54 FE FE FE FE FE FE
  40.  
  41.        is converted to:
  42.        00 32 FF 05 84 34 35 FF 01 FF 54 54 FF 06 FE
  43.  
  44. 3-Coding -
  45.  
  46.         Mode A: The signal is coded using 7 bits, from 30h to AFh.
  47.  
  48.         EX:
  49.         0 - AAAAaaaa      - >   0 - 0AAAAaaa   +  30h
  50.         1 - BBBBbbbb            1 - 0BBBBbbb   +  30h
  51.         2 - CCCCcccc            2 - 0CCCCccc   +  30h
  52.         3 - DDDDdddd            3 - 0DDDDddd   +  30h
  53.         4 - EEEEeeee            4 - 0EEEEeee   +  30h
  54.         5 - FFFFffff            5 - 0FFFFfff   +  30h
  55.         6 - GGGGgggg            6 - 0GGGGggg   +  30h
  56.                                 7 - 0abcdefg   +  30h
  57.  
  58.         Mode B: The signal is coded using 6 bits, from 30h to 70h.
  59.  
  60.         EX:
  61.         0 - AAAAaaaa      - >   0 - 00AAAAaa   +  30h
  62.         1 - BBBBbbbb            1 - 00BBBBbb   +  30h
  63.         2 - CCCCcccc            2 - 00CCCCcc   +  30h
  64.                                 3 - 00aabbcc   +  30h
  65.  
  66.  
  67. 4-Saving - The result is appended to the end of message at 64 bytes per line,
  68.   with a header:
  69.  
  70.    "[TALK]"  - 6 bytes - Identify a talkline
  71.    1Bh,"[8m" - 4 bytes - ANSI command to disable output, to avoid trash on
  72.                mail readers/terminal emulators without sound capabilities
  73.                but with full ANSI suport.
  74.    "A"       - 1 byte  -  A = coding in 7 bits
  75.                           B = coding in 6 bits
  76.                           Letters A to H are reserved.
  77.    "00000"   - 5 bytes -  The size of the sound in bytes, after coding and
  78.                           without line feeds (E3h).
  79.    E3h       - 1 byte  -  The character used as LF by the QWK file format.
  80.  
  81.    .. follow first 64 bytes,E3h,  and so on...
  82.  
  83. =========================================================================
  84.  
  85.    As example, the routines, used  to compress and expand the voice signal.
  86.  
  87. //-----------------------------------------------------------------------
  88. UINT WaveCompress (LPSTR Pk, LPSTR Wav, UINT nS)
  89. //
  90. //      Wav - intput signal
  91. //      Pk  - output signal
  92. //      nS  - number of data points
  93. //
  94. {
  95.   register UINT k, T;
  96.   char M;
  97.   UINT Ncomp, nS;
  98.  
  99.   Log2(Wav, nS);                        ;4 bit convert
  100.   Ncomp = nS >> 1;
  101. //                                      pack data
  102.   _asm  {
  103.             LES   SI,Wav        ;ES:SI -> Wav
  104.             MOV   DI,SI
  105.             MOV   CX,Ncomp
  106.             JCXZ  DONE
  107.      L1:    MOV   AX,ES:[SI]
  108.             SHL   AL,4          ;shift to HI nibble
  109.             AND   AX,0FF0h      ;mask
  110.             OR    AL,AH         ;merge
  111.             STOSB               ;save
  112.             ADD   SI,2
  113.             LOOP  L1
  114.      DONE:
  115.          }
  116. //
  117.   nS = 0;
  118.   Wav[Ncomp] = (char)(Wav[Ncomp-1]+1);  //make last different
  119.   for(k=0; k<Ncomp; k++)                //run lenght encode
  120.   {  T = 1;
  121.      M = Wav[k];
  122.      while (M == Wav[k+T])              //iqual next?
  123.      { if(T == 253) break;
  124.        else T = T + 1;                  //yes, bump T
  125.      }
  126.      if(T > 2 || M == '\xFF')
  127.      { Wav[nS++] = 0xFF;                //mark
  128.        Wav[nS++] =(char)T;              //total
  129.        k = k + T - 1;                   //next
  130.      }
  131.      Wav[nS++] = M;                     //save data
  132.   }
  133.   Ncomp = Pack(Pk, Wav, nS);            //7 bits convert
  134.   return Ncomp;
  135. }
  136. //-----------------------------------------------------------------
  137. LONG WaveExpand (LPSTR Wav, LPSTR Pk, UINT nS)
  138. //
  139. //      Pk  - input signal
  140. //      Wav - output signal
  141. //      nS  - number of data points
  142. //
  143. {
  144.   register UINT T, k;
  145.   UINT Cnt;
  146.   LONG nExp, Pt;
  147.  
  148. //
  149.    nSamp = Unpack(Pk, Pk, nSamp);             // 8 bits convert
  150.    nExp = 0;                                  // run lenght decode
  151.    for(Pt=0; (UINT)Pt < nSamp; Pt++)
  152.    {  if(Pk[Pt] == (char) 0xFF )
  153.       { Cnt = (BYTE) Pk[++Pt];
  154.         T = (char)Pk[++Pt];
  155.         for(k = 0; k < Cnt; k++) Wav[nExp++] = (char)T;
  156.       }
  157.       else
  158.       { Wav[nExp++] = Pk[Pt]; }
  159.    }
  160.    Cnt =(UINT)nExp;                           //unpack
  161.    _asm {
  162.             LES   DI, Wav
  163.             MOV   BX,Cnt
  164.             OR    BX,BX
  165.             JZ    DONE
  166.             MOV   SI,DI
  167.             ADD   SI,BX         ;end of data
  168.             ADD   BX,BX         ;end of unpacked data
  169.      L1:    MOV   AL,ES:[SI]
  170.             MOV   AH,AL         ;copy
  171.             SHR   AL,4          ;do inverse operation
  172.             AND   AX,0F0Fh     ;mask
  173.             MOV   ES:[DI+BX],AX ;save
  174.             DEC   SI
  175.             SUB   BX,2
  176.             JAE   L1            ;for all data points
  177.      DONE:
  178.         }
  179. //
  180.    nExp = nExp + nExp;
  181.    Exp2(Wave, nExp);                            ;8 bit convert
  182.    return nExp;
  183. }
  184. //=======================================================================
  185.  
  186.         Assebly routines to convert to and from 7 bits.
  187.  
  188. ;-------------------------------------------------------------------------
  189. ;       UINT = Pack (LPSTR, LPSTR, UINT);
  190. ;
  191. _Pack   PROC    FAR
  192.         PUSH    BP
  193.         MOV     BP,SP
  194.         PUSHF
  195.         CLD                     ;up
  196.         PUSH    DS
  197.         PUSH    SI
  198.         PUSH    DI
  199.         XOR     AX,AX           ;zero return value
  200.         MOV     CX,[BP+14]      ;size  (up to 64k)
  201.         JCXZ    PACK9
  202.         LES     DI,[BP+6];
  203.         LDS     SI,[BP+10];     ;DS:SI -> string
  204.         XOR     BX,BX           ;byte count
  205.         ADD     CX,SI           ;offset end of input string
  206.         PUSH    DI              ;save it
  207. ;
  208. PACK1:  MOV     DX,BX           ;insert a 0E3h each 64 bytes
  209.         AND     DX,3FH          ;test
  210.         JNZ     @F
  211.         MOV     AL,0E3h         ;LF (on QWK...)
  212.         STOSB                   ;insert
  213. @@:     CMP     SI,CX           ;end of processing?
  214.         JAE     PACK2           
  215.         LODSW                   ;-- 1 & 2
  216.         SHR     AL,1            ;-> 7, bit 0 to CY
  217.         RCL     DH,1            ;CY to bit 0 on DH
  218.         SHR     AH,1            ;repeat to next byte
  219.         RCL     DH,1
  220.         ADD     AX,3030h        ;translate to 30-A0h
  221.         STOSW                   ;ok, save it
  222.         LODSW
  223.         SHR     AL,1            ;repeat for bytes 3 & 4
  224.         RCL     DH,1
  225.         SHR     AH,1
  226.         RCL     DH,1
  227.         ADD     AX,3030h
  228.         STOSW
  229.         LODSW
  230.         SHR     AL,1            ;and 5 & 6
  231.         RCL     DH,1
  232.         SHR     AH,1
  233.         RCL     DH,1
  234.         ADD     AX,3030h
  235.         STOSW
  236.         LODSB
  237.         SHR     AL,1            ;the last one...
  238.         RCL     DH,1            ;
  239.         MOV     AH,DH           ;save DH (7 saved bits)
  240.         ADD     AX,3030h        ;
  241.         STOSW                   ;
  242.         ADD     BX,8            ;total
  243.         JMP     PACK1
  244. PACK2:  MOV     AX,DI           ;new position
  245.         POP     DI              ;initial position
  246.         SUB     AX,DI           ;return total processed bytes
  247. PACK9:  XOR     DX,DX           ;AX:DX
  248.         POP     DI
  249.         POP     SI
  250.         POP     DS
  251.         POPF
  252.         MOV     SP,BP
  253.         POP     BP
  254.         RET
  255. _Pack   ENDP
  256. ;-------------------------------------------------------------
  257. ;       UINT = Unpack (LPSTR, LPSTR, UINT);
  258. ;
  259. _Unpack PROC    FAR
  260.         PUSH    BP
  261.         MOV     BP,SP
  262.         PUSHF
  263.         PUSH    DS
  264.         PUSH    SI
  265.         PUSH    DI
  266.         CLD                     ;up
  267.         XOR     AX,AX
  268.         MOV     CX,[BP+14]      ;size
  269.         JCXZ    UNPCK9
  270.         LES     DI,[BP+6];      ;ES:DI -> string
  271.         LDS     SI,[BP+10];     ;DS:SI -> string
  272.         PUSH    DI
  273. ;
  274. UNPCK0: LODSB                    ;-- pcbord/qmail file corruption fix
  275.         CMP     AL,30H
  276.         JAE     @F
  277.         CMP     AL,'#'           ;<<<
  278.         JNE     UNPK2
  279.         MOV     AL,'@'           ;<<<
  280. @@:     CMP     AL,0B0H
  281.         JA      UNPK2
  282.         STOSB
  283. UNPK2:  LOOP    UNPCK0
  284. ;                                ;------------
  285.         MOV     AX,DI
  286.         POP     DI
  287.         SUB     AX,DI           ;total "clean" bytes
  288.         LDS     SI,[BP+6]
  289.         LES     DI,[BP+6]       ;works only on destination
  290.         ADD     AX,7
  291.         SHR     AX,3            ;number of loops
  292.         MOV     CX,AX
  293.         MOV     BX,7
  294.         MUL     BX              ;number of bytes
  295.         MOV     BX,AX           ;save on BX
  296. UNPCK1: MOV     DH,[SI+7]       ;get saved bit
  297.         SUB     DH,30h          ;convert to 0 - 7Fh
  298.         RCL     DH,1
  299.         LODSW
  300.         SUB     AX,3030h        ;convert data too
  301.         RCL     DH,1            ;bit -> CY
  302.         RCL     AL,1            ;insert on byte
  303.         RCL     DH,1            ;next byte
  304.         RCL     AH,1
  305.         STOSW                   ;save
  306.         LODSW
  307.         SUB     AX,3030h        ;next 2 bytes
  308.         RCL     DH,1
  309.         RCL     AL,1
  310.         RCL     DH,1
  311.         RCL     AH,1
  312.         STOSW
  313.         LODSW
  314.         SUB     AX,3030h        ;bytes 5 & 6
  315.         RCL     DH,1
  316.         RCL     AL,1
  317.         RCL     DH,1
  318.         RCL     AH,1
  319.         STOSW
  320.         LODSW
  321.         SUB     AL,30h          ;the last...
  322.         RCL     DH,1
  323.         RCL     AL,1
  324.         STOSB
  325.         LOOP    UNPCK1          ;repeat all
  326.         MOV     AX,BX
  327. UNPCK9: XOR     DX,DX           ;return total processed.
  328.         POP     DI
  329.         POP     SI
  330.         POP     DS
  331.         POPF
  332.         MOV     SP,BP
  333.         POP     BP
  334.         RET
  335. _Unpack ENDP
  336. ;---------------------------------------------------------------------
  337. ;       Assembly routines to convert from 8 to 4 bits and from 4 to 8
  338. ;---------------------------------------------------------------------
  339. ;       Log2 (LPSTR, UINT);
  340. ;
  341. _Log2   PROC    FAR
  342.         PUSH    BP
  343.         MOV     BP,SP
  344.         PUSHF
  345.         PUSH    ES
  346.         PUSH    DI
  347.         CLD
  348.         MOV     BX,[BP+10]      ;size to CX
  349.         OR      BX,BX
  350.         JZ      LOGC9
  351.         LES     DI,[BP+6];      ;ES:DI -> in/out - in place conversion
  352. LOGC1:  MOV     AL,ES:[DI]
  353.         XOR     CH,CH           ;zero
  354.         MOV     DL,CH           ;
  355.         sub     al,80h          ;remove DC value (-128..127)
  356.         OR      AL,AL
  357.         JNS     @F              ;if positive, go
  358.         NEG     AL              ;signal change
  359.         MOV     DL,8            ;signal bit
  360. @@:     AND     AL,7FH
  361.         SHL     AL,1
  362.         MOV     CL,7
  363. @@:     SHL     AL,1
  364.         JC      @F
  365.         LOOP    @B
  366. @@:     OR      CL,DL           ;insert signal
  367.         MOV     AL,CL
  368. ;
  369.         STOSB                   ;save
  370.         DEC     BX              ;end test
  371.         JNZ     LOGC1           ;no, more...
  372. LOGC9:  POP     DI
  373.         POP     ES
  374.         POPF
  375.         MOV     SP,BP
  376.         POP     BP
  377.         RET
  378. _Log2   ENDP
  379. ;-------------------------------------------------------------------
  380. ;       Exp2 (LPSTR, UINT);
  381. ;
  382. _LogExp PROC    FAR
  383.         PUSH    BP
  384.         MOV     BP,SP
  385.         PUSHF
  386.         PUSH    ES
  387.         PUSH    DI
  388.         CLD                     ;up
  389.         XOR     AX,AX
  390.         MOV     BX,[BP+10]      ;size
  391.         OR      BX,BX
  392.         JZ      LOGE9
  393.         LES     DI,[BP+6];      ;ES:DI -> in/out
  394.         XOR     CH,CH
  395. LOGE1:  MOV     AL,ES:[DI]
  396.         XOR     AH,AH
  397. ;
  398.         MOV     CL,AL           ;copy
  399.         AND     CL,7            ;signal mask
  400.         STC
  401.         RCL     AH,CL           ;exp
  402.         TEST    AL,8
  403.         JZ      @F              ;if positive
  404.         NEG     AH
  405. @@:     ADD     AH,80H          ;recover offset
  406.         MOV     AL,AH
  407.         STOSB                   ;save
  408.         DEC     BX
  409.         JNZ     LOGE1           ;loop
  410. LOGE9:  POP     DI
  411.         POP     ES
  412.         POPF
  413.         MOV     SP,BP
  414.         POP     BP
  415.         RET
  416. _Exp2   ENDP
  417. ;========================================================================
  418.  
  419. OBS: The music appended to the end of messages is a .MID file only coded
  420. into 7 bits.     The file header is the same, only the identifier "TALK"
  421. change to "MIDI".
  422.  
  423. ==========================================================================
  424.                                             Carlos Pires, Rio, March 1993.
  425. ==========================================================================
  426. NOTE: Unpack routine correction to avoid file corruption over some BBSs
  427.       systems, the change of "@" by "#".
  428.                                                                 June, 1993.
  429. ==========================================================================
  430. NOTE: Coding scheme "B" using 6 bits only to avoid some old fashioned
  431.       BBS.  This solve the problem of bit 7 stripping.      September 1993.
  432. ==========================================================================
  433.