;;; d-number-sayer.el --- An system for converting numbers into spoken text

;; Copyright (C) 2006-2011 Davin Pearson

;; Author/Maintainer: m4_davin_pearson
;; Keywords: improved appt.el
;; Version: 1.0

;;; Commentary:

;; This file is not part of GNU Emacs.

;; The function d-say-number-improved takes in integer argument and
;; speaks it through your computer's speakers.

;;; m4_limitation_of_warranty

;;; m4_install_instructions(d-number-sayer)

;;; Known Bugs:

;; None!

;;; Code:

;; (length d-random-play-emacs-midi--file-list)

(defvar d-number-sayer-folder
  (cond
   ((file-exists-p "c:/sound-samples")
    "c:/sound-samples")
   ((file-exists-p "d:/sound-samples")
    "d:/sound-samples")
   ((file-exists-p "e:/sound-samples")
    "e:/sound-samples")
   ((file-exists-p "f:/sound-samples")
    "f:/sound-samples")
   ((file-exists-p "g:/sound-samples")
    "g:/sound-samples")
   ((file-exists-p "/media/www/C1TB/sound-samples")
    "/media/www/C1TB/sound-samples")
   ((file-exists-p "/media/www/D153GB/sound-samples")
    "/media/www/D153GB/sound-samples")
   ((file-exists-p "/media/www/F2TB/sound-samples")
    "/media/www/F2TB/sound-samples")
   ((file-exists-p "/media/www/G16GB/sound-samples")
            "/media/www/G16GB/sound-samples")
   ))

;; (d-say-number-inner-inner 33)
;; (d-say-number-inner-inner 89)
;; (d-say-number-inner-inner 65)
(defun d-say-number-inner-inner (number)
  (assert (and (>= number 0) (<= number 99)))
  (let (file file1 file2)
    (cond
     ((or (<= number 20) (= number 30) (= number 40) (= number 50)
          (=  number 60) (= number 70) (= number 80) (= number 90)
          )
      (setq file (format "%s/emacs/numbers/%d.wav" d-number-sayer-folder number))
      (play-sound (list 'sound :file file :volume 1.0)))
     ((and (> number 20) (< number 30))
      (setq file1 (format "%s/emacs/numbers/20.wav" d-number-sayer-folder))
      (setq file2 (format "%s/emacs/numbers/%d.wav" d-number-sayer-folder (- number 20)))
      (play-sound (list 'sound :file file1 :volume 1.0))
      (play-sound (list 'sound :file file2 :volume 1.0)))
     ((and (> number 30) (< number 40))
      (setq file1 (format "%s/emacs/numbers/30.wav" d-number-sayer-folder))
      (setq file2 (format "%s/emacs/numbers/%d.wav" d-number-sayer-folder (- number 30)))
      (play-sound (list 'sound :file file1 :volume 1.0))
      (play-sound (list 'sound :file file2 :volume 1.0)))
     ((and (> number 40) (< number 50))
      (setq file1 (format "%s/emacs/numbers/40.wav" d-number-sayer-folder))
      (setq file2 (format "%s/emacs/numbers/%d.wav" d-number-sayer-folder (- number 40)))
      (play-sound (list 'sound :file file1 :volume 1.0))
      (play-sound (list 'sound :file file2 :volume 1.0)))
     ((and (> number 50) (< number 60))
      (setq file1 (format "%s/emacs/numbers/50.wav" d-number-sayer-folder))
      (setq file2 (format "%s/emacs/numbers/%d.wav" d-number-sayer-folder (- number 50)))
      (play-sound (list 'sound :file file1 :volume 1.0))
      (play-sound (list 'sound :file file2 :volume 1.0)))
     ((and (> number 60) (< number 70))
      (setq file1 (format "%s/emacs/numbers/60.wav" d-number-sayer-folder))
      (setq file2 (format "%s/emacs/numbers/%d.wav" d-number-sayer-folder (- number 60)))
      (play-sound (list 'sound :file file1 :volume 1.0))
      (play-sound (list 'sound :file file2 :volume 1.0)))
     ((and (> number 70) (< number 80))
      (setq file1 (format "%s/emacs/numbers/70.wav" d-number-sayer-folder))
      (setq file2 (format "%s/emacs/numbers/%d.wav" d-number-sayer-folder (- number 70)))
      (play-sound (list 'sound :file file1 :volume 1.0))
      (play-sound (list 'sound :file file2 :volume 1.0)))
     ((and (> number 80) (< number 90))
      (progn
        (setq file1 (format "%s/emacs/numbers/80.wav" d-number-sayer-folder))
        (setq file2 (format "%s/emacs/numbers/%d.wav" d-number-sayer-folder (- number 80)))
        (play-sound (list 'sound :file file1 :volume 1.0))
        (play-sound (list 'sound :file file2 :volume 1.0)))
      )
     ((and (> number 90) (< number 100))
      (setq file1 (format "%s/emacs/numbers/90.wav" d-number-sayer-folder))
      (setq file2 (format "%s/emacs/numbers/%d.wav" d-number-sayer-folder (- number 90)))
      (play-sound (list 'sound :file file1 :volume 1.0))
      (play-sound (list 'sound :file file2 :volume 1.0)))
     (t
      (play-sound (list 'sound :file (format
                                      "%s/emacs/numbers/many.wav"
                                      d-number-sayer-folder) :volume 1.0)))
     )
    )
  )

;; (setq number 19)
;; (d-say 33)
(defun d-say-number-inner (number)
  (assert (and (>= number 0) (<= number 999)))
  (let (file file1 file2 file3)
    (cond
     ((or (= number 100) (= number 200) (= number 300) (= number 400)
          (= number 500) (= number 600) (= number 700) (= number 800)
          (= number 900))
      (progn
        (setq file1 (format "%s/emacs/numbers/%d.wav" d-number-sayer-folder (/ number 100)))
        (setq file2 (format "%s/emacs/numbers/hundred.wav" d-number-sayer-folder))
        (play-sound (list 'sound :file file1 :volume 1.0))
        (play-sound (list 'sound :file file2 :volume 1.0))
        )
      )
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     ((and (> number 100) (< number 200))
      (progn
        (setq file1 (concat d-number-sayer-folder "/emacs/numbers/1.wav"))
        (setq file2 (concat d-number-sayer-folder "/emacs/numbers/hundred.wav"))
        (setq file3 (concat d-number-sayer-folder "/emacs/numbers/and.wav"))
        (play-sound (list 'sound :file file1 :volume 1.0))
        (play-sound (list 'sound :file file2 :volume 1.0))
        (play-sound (list 'sound :file file3 :volume 1.0))
        )
      (d-say-number-inner-inner (- number 100)))
     ((and (> number 200) (< number 300))
      (progn
        (setq file1 (concat d-number-sayer-folder "/emacs/numbers/2.wav"))
        (setq file2 (concat d-number-sayer-folder "/emacs/numbers/hundred.wav"))
        (setq file3 (concat d-number-sayer-folder "/emacs/numbers/and.wav"))
        (play-sound (list 'sound :file file1 :volume 1.0))
        (play-sound (list 'sound :file file2 :volume 1.0))
        (play-sound (list 'sound :file file3 :volume 1.0))
        )
      (d-say-number-inner-inner (- number 200)))
     ((and (> number 300) (< number 400))
      (progn
        (setq file1 (concat d-number-sayer-folder "/emacs/numbers/3.wav"))
        (setq file2 (concat d-number-sayer-folder "/emacs/numbers/hundred.wav"))
        (setq file3 (concat d-number-sayer-folder "/emacs/numbers/and.wav"))
        (play-sound (list 'sound :file file1 :volume 1.0))
        (play-sound (list 'sound :file file2 :volume 1.0))
        (play-sound (list 'sound :file file3 :volume 1.0))
        )
      (d-say-number-inner-inner (- number 300)))
     ((and (> number 400) (< number 500))
      (progn
        (setq file1 (concat d-number-sayer-folder "/emacs/numbers/4.wav"))
        (setq file2 (concat d-number-sayer-folder "/emacs/numbers/hundred.wav"))
        (setq file3 (concat d-number-sayer-folder "/emacs/numbers/and.wav"))
        (play-sound (list 'sound :file file1 :volume 1.0))
        (play-sound (list 'sound :file file2 :volume 1.0))
        (play-sound (list 'sound :file file3 :volume 1.0))
        )
        (d-say-number-inner-inner (- number 400)))
     ((and (> number 500) (< number 600))
      (progn
        (setq file1 (concat d-number-sayer-folder "/emacs/numbers/5.wav"))
        (setq file2 (concat d-number-sayer-folder "/emacs/numbers/hundred.wav"))
        (setq file3 (concat d-number-sayer-folder "/emacs/numbers/and.wav"))
        (play-sound (list 'sound :file file1 :volume 1.0))
        (play-sound (list 'sound :file file2 :volume 1.0))
        (play-sound (list 'sound :file file3 :volume 1.0))
        )
      (d-say-number-inner-inner (- number 500)))
     ((and (> number 600) (< number 700))
      (progn
        (setq file1 (concat d-number-sayer-folder "/emacs/numbers/6.wav"))
        (setq file2 (concat d-number-sayer-folder "/emacs/numbers/hundred.wav"))
        (setq file3 (concat d-number-sayer-folder "/emacs/numbers/and.wav"))
        (play-sound (list 'sound :file file1 :volume 1.0))
        (play-sound (list 'sound :file file2 :volume 1.0))
        (play-sound (list 'sound :file file3 :volume 1.0))
        )
      (d-say-number-inner-inner (- number 600)))
     ((and (> number 700) (< number 800))
      (progn
        (setq file1 (concat d-number-sayer-folder "/emacs/numbers/7.wav"))
        (setq file2 (concat d-number-sayer-folder "/emacs/numbers/hundred.wav"))
        (setq file3 (concat d-number-sayer-folder "/emacs/numbers/and.wav"))
        (play-sound (list 'sound :file file1 :volume 1.0))
        (play-sound (list 'sound :file file2 :volume 1.0))
        (play-sound (list 'sound :file file3 :volume 1.0))
        )
      (d-say-number-inner-inner (- number 700)))
     ((and (> number 800) (< number 900))
      (progn
        (setq file1 (concat d-number-sayer-folder "/emacs/numbers/8.wav"))
        (setq file2 (concat d-number-sayer-folder "/emacs/numbers/hundred.wav"))
        (setq file3 (concat d-number-sayer-folder "/emacs/numbers/and.wav"))
        (play-sound (list 'sound :file file1 :volume 1.0))
        (play-sound (list 'sound :file file2 :volume 1.0))
        (play-sound (list 'sound :file file3 :volume 1.0))
        )
      (d-say-number-inner-inner (- number 800)))
     ((and (> number 900) (< number 1000))
      (progn
        (setq file1 (concat d-number-sayer-folder "/emacs/numbers/9.wav"))
        (setq file2 (concat d-number-sayer-folder "/emacs/numbers/hundred.wav"))
        (setq file3 (concat d-number-sayer-folder "/emacs/numbers/and.wav"))
        (play-sound (list 'sound :file file1 :volume 1.0))
        (play-sound (list 'sound :file file2 :volume 1.0))
        (play-sound (list 'sound :file file3 :volume 1.0))
        )
      (d-say-number-inner-inner (- number 900)))
     (t
      (d-say-number-inner-inner number)
      )
     )
    )
  )

;; (d-split-3 123456)
(defun d-split-3 (number)
  (let ((ans nil))
    (while (> number 0)
      (setq ans (cons (mod number 1000) ans))
      (setq number (/ number 1000)))
    ans))

;; (d-say-number-improved (+ (* 123 1000000) (* 0 1000) 123))
;; (d-say-number-improved (+ (* 123 1000000) (* 456 1000) 789))
;; (d-say-number-improved (+ (* 123 1000000) 789))
;; (d-say-number-improved 54)
;; (progn (d-say-number-improved 123) (d-random-play-emacs-midi (concat d-number-sayer-folder "/emacs/numbers/minutes-to-go.wav"))
(defun d-say-number-improved (number)
  ;(setq number 123456789)
  (let (file)
    (if (= 0 number)
        (progn
          (setq file (concat d-number-sayer-folder "/emacs/numbers/0.wav"))
          (play-sound (list 'sound :file file :volume 1.0)))
      ;; (d-split-3 -1)
      (let* ((ptr (d-split-3 number))
             (i (length ptr))
             (a)
             (alist '((1 . nil)
                      (2 . "thousand")
                      (3 . "million")
                      (4 . "billion"))))
        (while (> i 0)
          (when (/= 0 (car ptr))
            (d-say-number-inner (car ptr))
            (setq a (cdr (assq i alist)))
            (when a
              (setq a (concat d-number-sayer-folder "/emacs/numbers/" a ".wav"))
              (if (file-exists-p a)
                  (play-sound (list 'sound :file a :volume 1.0))
                (beep))))
          (decf i)
          (setq ptr (cdr ptr)))))))

(provide 'd-number-sayer)
;;; d-number-sayer.el ends here
