```(* D'après le code Lucid Synchrone de Gwenael Delaval *)

let node xor (a, b) = o where
rec o = (a && (not b)) || (b && (not a))

(************************* cyclic_encoding *******************************)

(*
let node div_X3_X_1 i = (reg0,reg1,reg2) where
rec reg0 = false fby (xor(i, back))
and reg1 = false fby reg0
and reg2 = false fby (xor(reg1, back))
and back = reg2
*)

let node add_tail_bits_50_3 i = merge (1^50 0^3) i false

let node div_X3_X_1 p = (reg0,reg1,reg2) where
and reg0 = false fby (xor(p', back))
and reg1 = false fby reg0
and reg2 = false fby (xor(reg1, back))
and back = add_tail_bits_50_3 (reg2 when (1^50 0^3))

(* remainder of the division by X^3 + X + 1 *)
let node redundancy i = (bit0,bit1,bit2) where
rec (reg0,reg1,reg2) = div_X3_X_1 i
and bit0 = reg0  when (0^50 100)
and bit1 = reg1  when (0^50 100)
and bit2 = reg2  when (0^50 100)

(* join data and redundancy *)
let node join_50_3 (i, bit0, bit1, bit2) = o3 where
rec o1 = merge (1^50 0) i  bit0
and o2 = merge (1^51 0) o1 bit1
and o3 = merge (1^52 0) o2 bit2

(* cyclic encoder: X^3 + X + 1 *)
let node cyclic_encoding i = o where
rec (bit0, bit1, bit2) = redundancy i
and o = join_50_3 (i, buffer bit0,
buffer bit1,
buffer bit2)

(*************************** convolutional_encoding ************************)
let node add_tail_bits_185_4 i = merge (1^185 0^4) i false

let node mult_polys i = (o1, o2) where
and reg0 = false fby i'
and reg1 = false fby reg0
and reg2 = false fby reg1
and reg3 = false fby reg2
and o1 = xor (xor (xor (i', reg0), reg2), reg3)  (* X^4 + X^3 + X + 1 *)
and o2 = xor (xor (i', reg2), reg3)              (* X^4 + X^3 + 1 *)

(* to merge the two flows of redundancy *)
let node multiplexer (i1, i2) = o where
rec o = merge (10) i1 i2

(* convolutional encoder: X^4 + X^3 + 1 and X^4 + X^3 + X + 1 *)
let node convolutional_encoding i = o where
rec (p1, p2) = mult_polys i
and o = multiplexer (p1, buffer p2)

(********** split_speech **********)

let node split_speech i = (o_Ia, o_Ib, o_II) where
rec o_Ia = i when (1^50 0^210)
and o_Ib = i when (0^50 1^132 0^78)
and o_II = i when (0^182 1^78)

(********** gsm_encoding ***********)

let node gsm_encoding i = o where
rec (part_Ia, part_Ib, part_II) = split_speech i
and part_Ia_enc = cyclic_encoding part_Ia
and part_I = merge (1^53 0^132) part_Ia_enc part_Ib
and part_I_enc = convolutional_encoding part_I
and o = merge (1^378 0^78) part_I_enc part_II

(******************************************************************************)
(******************************** decodeur GSM ********************************)
(******************************************************************************)

(********** cyclic decoding **********)

let node stutter_50 i = o where
rec o =  merge (1 0^49) i (buffer (o when (1^49 0)))

let node split3 i = i when (100), i when (010), i when (001)

let node and_by_3 i = o where
rec i1, i2, i3 = split3 i
and o = ((buffer ((buffer i1) && i2)) && i3)

let node cyclic_decoding i = o where
rec (data, redundancy) = (i when (1^50 0^3) , i whenot (1^50 0^3))
and reencoded_data = cyclic_encoding data
and code = reencoded_data whenot (1^50 0^3)
and frame_ok = and_by_3 (code = redundancy)
and data_ok = stutter_50 frame_ok
and current_frame = buffer(data)
and last_frame = merge 1^50(0) true (buffer(current_frame))
and o = if data_ok then current_frame else last_frame

(********** convolutional decoding **********)
(* hamming distance *)
let node hamming_dist ((x1,x2),(y1,y2)) =
(if x1 = y1 then 0 else 1) + (if x2 = y2 then 0 else 1)

let node convolutional_decoding x = (* non implemente *)
(x when (01)) when 0^188(1^185 0^4)
(* code factice, avec le bon type de sortie *)

(********** join speech **********)
let node join_speech (part_Ia, part_Ib, part_II) = o where
rec o = merge (1^50 0^210) part_Ia (merge (1^132 0^78) part_Ib part_II)

(********** split encoded speech **********)
let node split_I_II i = (i when (1^378 0^78), i whenot (1^378 0^78))
let node split_Ia_Ib part_I =
(part_I when (1^53 0^132), part_I whenot (1^53 0^132))

let node decode_with_3_buffers i = o where
rec part_I_enc, part_II = split_I_II i
and part_I = convolutional_decoding part_I_enc
and part_Ia_enc, part_Ib = split_Ia_Ib part_I
and part_Ia = cyclic_decoding part_Ia_enc
and o = join_speech (buffer(part_Ia), buffer(part_Ib), buffer(part_II))

```