Autore Topic: Da testo a codice Morse + audio  (Letto 742 volte)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.723
  • Ne mors quidem nos iunget
    • Mostra profilo
Da testo a codice Morse + audio
« il: 08 Febbraio 2014, 01:39:07 »
Di seguito un semplice codice per convertire il testo in codice Morse.
Sarà inoltre creato un file audio per ascoltare il sonoro dei "punto" e delle "linea".

Codice: gambas [Seleziona]
Private Const PARIS As Single = 44.0      ' "tick" in un PARIS
Private Const SECPM As Single = 70.0      ' secondi al Minuto
Private Const FREQ_CAMP As Short = 8000   ' frequenza di campionamento al Secondo
Private Const CANALI As Short = 1         ' impostazione predefinita MONO
Private Const HERTZ As Float = 880.0      ' impostazione predefinita onda sinusoidale a 880 hertz
Private Const FWPM As Float = 18.0        ' velocità 'Farnsworth'
Private Const WPM As Float = 13.0

' Definizione dei punti e delle linee per lettere, numeri e punteggiatura secondo il codice Morse internazionale:

'' lettere
Private lettere As String[] = [".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.",  ' [a - n]
                               "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."]            ' [o - z]

'' numeri [0 - 9]
Private num As String[] = ["-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----."]

'' punteggiatura                ?         !        .         ,          ;         :         +        -         /        =        @
Private punti As String[] = [".-.-.-", "-.-.--", ".-.-.-", "--..--", "-.-.-.", "---...", ".-.-.", "-....-", "-..-.", "-...-", ".--.-.", ".-..."] ' &

' blocco d'intestazione del file wav futuro: 1 canale, 8 bit, hz 8000
Private bh As Byte[] = [&52, &49, &46, &46, &00, &00, &00, &00, &57, &41, &56, &45, &66, &6D, &74, &20, &10, &00, &00, &00, &01, &00, &01, &00,
                        &40, &1F, &00, &00, &40, &1F, &00, &00, &01, &00, &08, &00, &64, &61, &74, &61, &00, &00, &00, &00]
Private tick_per_minuto As Float
Private sec_per_tick As Float
Private spazio_tra_elementi As Float
Private spazio_fra_caratteri As Float
Private spazio_fra_parole As Float
Private fl As File
Private TextArea1 As TextArea
Private TextArea2 As TextArea
Private Button1 As Button


Public Sub _new()
 
  With Me
    .W = Screen.AvailableWidth * 0.6
    .H = Screen.AvailableHeight / 2
    .Center
  End With
  With TextArea1 = New TextArea(Me)
    .X = 5
    .Y = 5
    .W = Me.W * 0.35
    .H = Me.H * 0.9
  End With
  With TextArea2 = New TextArea(Me)
    .X = TextArea1.X + TextArea1.W + 5
    .Y = 5
    .W = Me.W * 0.5
    .H = Me.H * 0.9
    .Font.Size = 12
    .Wrap = True
    .ReadOnly = True
  End With
  With Button1 = New Button(Me) As "Button1"
    .W = Me.W * 0.1
    .H = TextArea2.H / 2
    .X = (Me.W - .w) - 10
    .Y = TextArea2.H / 4
    .Text = "Crea\nfile\naudio"
  End With
 
End

Public Sub Form_Open()
 
  Dim durata_del_silenzio, lunghezza_di_paris As Float
 
' Quantità di tick al Minuto ad una data velocità 'Farnsworth' (FWPM)
  tick_per_minuto = PARIS * FWPM

' Durata di un tick in Secondi:
  sec_per_tick = SECPM / tick_per_minuto
   
' Tempo tra gli elementi (punti e linee) di un caratttere:
  spazio_tra_elementi = sec_per_tick
 
' Durata di un 'paris' ad un dato WPM:
  lunghezza_di_paris = SECPM / WPM
   
' Durata temporale complessiva fra caratteri:
  durata_del_silenzio = lunghezza_di_paris - 31 * sec_per_tick

' La distanza temporale fra le parole deve essere almeno 7/3 della distanza fra le lettere:
  spazio_fra_caratteri = durata_del_silenzio / (6.0 + 1.0 / 3.0)
  spazio_fra_parole = (7.0 * spazio_fra_caratteri) / 3.0

End


Public Sub Button1_Click()
 
  TextArea2.Clear
 
  fl = Open "/tmp/morse.wav" For Create
  bh.Write(fl, 0, bh.Count)
   
  outlettere(TextArea1.Text)
   
  fl.Close

End


Private Procedure outlettere(outRiga As String)     ' Genera il suono di una linea di testo
 
  Dim c As Short = 1

  While c <= Len(outRiga)
    If Mid(outRiga, c, 1) = " " Then
      silenzio((spazio_fra_parole - spazio_fra_caratteri) + spazio_tra_elementi)
    Else
      putlettere(Mid(outRiga, c, 1))
    Endif
    Inc c
  Wend
 
End


Private Procedure silenzio(durata As Float)     ' Genera il silenzio
 
  Dim nsamples, i As Integer
  Dim spatium As Byte
 
  nsamples = durata * FREQ_CAMP
 
  For i = 0 To nsamples - 1
    spatium = 127
    Write #fl, spatium As Byte
  Next
 
End


Private Procedure putlettere(s As String)
 
  Dim index, i As Integer
  Dim punti_linee As String

  i = 1

  If IsPunct(s) = False Then
    If IsLCase(s) Then
      index = Asc(s) - Asc("a")
      punti_linee &= lettere[index]
    Endif
    If IsUCase(s) Then
      index = Asc(s) - Asc("A")
      punti_linee &= lettere[index]
    Endif
  Endif
   
  If IsDigit(s) Then
    index = Asc(s) - Asc("0")
    punti_linee &= num[index]
  Endif

  TextArea2.Text &= punti_linee & " "

  index = -1
   
  If IsPunct(s) Then
    Select Case s
      Case "?"
        index = 0
      Case "!"
        index = 1
      Case "."
        index = 2
      Case ","
        index = 3
      Case ";"
        index = 4
      Case ":"
        index = 5
      Case "+"
        index = 6
      Case "-"
        index = 7
      Case "/"
        index = 8
      Case "="
        index = 9
      Case "@"
        index = 10
      Case "&"
        index = 11
    End Select
' Se il carattere non è riconoscibile, allora viene sostituito con il carattere "?":
    If index < 0 Then index = 0
    punti_linee &= punti[index]
    TextArea2.Text &= punti_linee & " "
  Endif
   
' Risolve varie incognite:
  If Left(punti_linee, 1) = Chr(0) Then punti_linee &= punti[3]

  While i <= Len(punti_linee)    ' Len(punti_linee) è la quantità di segni che compongono il codice/lettera morse
    If Mid(punti_linee, i, 1) = "." Then
      suono(sec_per_tick)
    Else
      suono(3 * sec_per_tick)
      silenzio(spazio_tra_elementi)
    Endif
    Inc i
  Wend
 
  silenzio(spazio_fra_caratteri - spazio_tra_elementi) 
 
End

Private Procedure suono(durata As Float)
 
  Dim nsamples, i As Integer
  Dim t, f As Float
  Dim onda As Byte
 
  nsamples = durata * FREQ_CAMP
 
  For i = 0 To nsamples - 1
    t = CFloat(i) / FREQ_CAMP
    f = 1
    If t < sec_per_tick * 0.05 Then f = (140.0 * t / sec_per_tick)
    If t > (durata - sec_per_tick * 0.05) Then f = 140.0 * (durata - t) / sec_per_tick
    onda = 255 * (f * Sin(2 * Pi * HERTZ * t) + 1) / 2
    Write #fl, onda As Byte
  Next
 
End

Public Sub Form_Close()

  bh.Clear
  lettere.Clear
  num.Clear
  punti.Clear
 
End
« Ultima modifica: 27 Ottobre 2021, 23:00:21 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Michy9393

  • Gran Maestro dei Gamberi
  • *****
  • Post: 570
  • Ubuntu: Linux for Human Beings
    • Mostra profilo
Re: Da testo a codice Morse
« Risposta #1 il: 10 Febbraio 2014, 08:13:35 »
ma che forza! :D