REQ: R1 MF ("Blue box") Tone Generator

Using Nyquist scripts in Audacity.
Post and download new plug-ins.

If you require help using Audacity, please post on the forum board relevant to your operating system:
Windows
Mac OS X
GNU/Linux and Unix-like

REQ: R1 MF ("Blue box") Tone Generator

Permanent link to this post Posted by BellCurve » Tue Feb 12, 2013 9:14 pm

I've been an Audacity user for quite a while now, and I've used it for a multitude of projects. Lovely program it is.

Of late, I've come into a project when I need to use the old Bell System MF tones. I have the barest idea of how to use the Nyquist language, so I have no idea how to write the plugin myself. I had the idea of modifying the DTMF generator, but I have no idea how to go about doing it (also, there's the fact that the DTMF system doesn't generate in the same manner as the Bell (R1) MF system).


For anyone who is interested in helping out by writing this generator, here's the pertinent information regarding the Bell MF signalling system (which is the same as the ITU "R1" signalling scheme).

The tones used by the system are:
  1. KP 1100 Hz + 1700 Hz
  2. ST 1500 Hz + 1700 Hz
  3. 1 700 Hz + 900 Hz
  4. 2 700 Hz + 1100 Hz
  5. 3 900 Hz + 1100 Hz
  6. 4 700 Hz + 1300 Hz
  7. 5 900 Hz + 1300 Hz
  8. 6 1100 Hz + 1300 Hz
  9. 7 700 Hz + 1500 Hz
  10. 8 900 Hz + 1500 Hz
  11. 9 1100 Hz + 1500 Hz
  12. 0 1300 Hz + 1500 Hz
(If you'll notice, the digit tones of the MF system follow a two of five code, with the 700, 900, 1100, 1300 and 1500 values corresponding to 0, 1, 2, 4, 7; the KP (start of pulsing) tone and ST (end of pulsing) tone use the 1700 tone plus 2 and 7, respectively. The European R2 MF signalling system uses the other combinations of 1700 with 0, 1, and 4 for more tones, but nevermind the R2 system.)

The KP tone must being 100 ms long, plus or minus 10 ms; and the digit and ST tones must be 68 ms long, plus or minus 7 ms. There must be 68 ms of silence between each signal, plus or minus 7 ms. Transmissions start with KP, and end with ST, tones are sent "en bloc", so no pauses.

I.e. a number dialed as "1 (pause) 800 (pause) 555 (pause) 1212", would be sent as "KP 18005551212 ST" (where the spaces are only inserted for clarity).


In terms of input to the generator, all that is really needed is the input of the number to be generated (with KP and ST generated automatically), and the volume.


Thanks to any one who is willing to take on this task, I wish I could be of more help.
BellCurve
 
Posts: 2
Joined: Mon Feb 11, 2013 10:58 pm
Operating System: Please select

Re: REQ: R1 MF ("Blue box") Tone Generator

Permanent link to this post Posted by steve » Wed Feb 13, 2013 12:35 am

BellCurve wrote:For anyone who is interested in helping out by writing this generator,....

There's "helping" and there's "writing".
As I'm not employed to do this, I only generally write plug-ins that are of particular interest to me, but I'd be more than happy to help you write a plug-in ;)

As a start, try running the following snippets in the "Nyquist Prompt" effect (in the Effect menu). To run these snippets of code, select a short part of an audio track, then open the Nyquist Prompt effect, copy and paste the code into the Nyquist Prompt text box and click the OK button.

Code: Select all
; this is a comment
; comments start with a semicolon
; KP 1100 Hz + 1700 Hz

(setf kp
  (mult 0.4
    (sim (hzosc 1100)
      (hzosc 1700))))


Code: Select all
; ST 1500 Hz + 1700 Hz

(setf st
  (mult 0.4
    (sim (hzosc 1500)
      (hzosc 1700))))


Code: Select all
; 1 = 700 Hz + 900 Hz

(setf st
  (mult 0.4
    (sim (hzosc 700)
      (hzosc 900))))


Can you create the others?
Next will be sorting out the timing.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 45327
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: REQ: R1 MF ("Blue box") Tone Generator

Permanent link to this post Posted by BellCurve » Wed Feb 13, 2013 3:16 am

steve wrote:There's "helping" and there's "writing".
As I'm not employed to do this, I only generally write plug-ins that are of particular interest to me, but I'd be more than happy to help you write a plug-in ;)

Well, that's to be expected really, though I do have to say me and functional languages don't go well together. (My experience with trying to be forced to learn one went badly, and that's soured my view of such languages, even though I do see the power behind them.)

But enough about my issues with functional languages.

steve wrote:As a start, try running the following snippets in the "Nyquist Prompt" effect (in the Effect menu). To run these snippets of code, select a short part of an audio track, then open the Nyquist Prompt effect, copy and paste the code into the Nyquist Prompt text box and click the OK button.

Code: Select all
<snipped>

Which works quite well I must say. Save for the whole "applying to some stretch of previously made track of variable length".


steve wrote:Can you create the others?
Next will be sorting out the timing.

The others were easily able to be created, I mean it's changing a few comments and constants; now, if I were writing this in C:
Code: Select all
switch(digit) {
    case 0:
        intHiTone = 1500;
        intLoTone = 1300;
        break;
    case 1:
        intHiTone = 900;
        intLoTone = 700;
        break;
    case 2:
        intHiTone = 1100;
        intLoTone = 700;
        break;
    case 3:
        intHiTone = 1100;
        intLoTone = 900;
        break;
    case 4:
        intHiTone = 1300;
        intLoTone = 700;
        break;
    case 5:
        intHiTone = 1300;
        intLoTone = 900;
        break;
    case 6:
        intHiTone = 1300;
        intLoTone = 1100;
        break;
    case 7:
        intHiTone = 1500;
        intLoTone = 700;
        break;
    case 8:
        intHiTone = 1500;
        intLoTone = 900;
        break;
    case 9:
        intHiTone = 1500;
        intLoTone = 1100;
        break;
    case 10:
        intHiTone = 1700;
        intLoTone = 1100;
        break;
    case 11:
        intHiTone = 1700;
        intLoTone = 1500;
        break;
}

To select the frequency pairs, and with that I'd then replace the constant values of the generating code with the intHiTone and intLoTone variables. Gives me the right digit pairs.

But I have no idea how to do the equivalent of a C "switch()" expression in the Nyquist language, so I have no idea how to go about doing that. I also don't know how to create specific lengths of silence which is what I would thing is the easiest way to get the tones produced "perfectly".


Thank you for the assistance with this.
BellCurve
 
Posts: 2
Joined: Mon Feb 11, 2013 10:58 pm
Operating System: Please select

Re: REQ: R1 MF ("Blue box") Tone Generator

Permanent link to this post Posted by steve » Wed Feb 13, 2013 4:05 am

BellCurve wrote:though I do have to say me and functional languages don't go well together. (My experience with trying to be forced to learn one went badly, and that's soured my view of such languages, even though I do see the power behind them.)

OK, point taken - I'll be gentle :D

BellCurve wrote:Which works quite well I must say. Save for the whole "applying to some stretch of previously made track of variable length".

Ah yes, the stretching. This is one of the trickiest parts to get your head round because it involves "local time", "global time" and "warp", but fortunately we don't need to go deeply into this and can get by with a couple of "rules":
  1. For "effects", time is treated as "local time". This means that the current selection counts as "1 unit of time".
  2. For "generate" type plug-ins, time is treated as "global" ("real") time, so "1 unit" of time is 1 second.

What this means in practice:
If we run (osc 60 2.5) in the Nyquist Prompt (which is an "effect"), the second parameter (2.5) is the duration and the command will generate a tone that is 2.5 "units" duration - that is, 2.5 times the duration of the selection.
If we run the same code in a generate type plug-in, it will generate 2.5 seconds of the sine tone.

The Nyquist Prompt provides a convenient way to test short scripts, but we need a way to make it use "real" time rather than "local" time. There is a function provided for this called abs-env. What this function does is to "evaluate its arguments in the default environment". In other words, wrapping a function in abs-env will force that function to use "real" time.

As an example we can use abs-env with hzosc (which we used previously).
Code: Select all
; this will produce a 440 Hz tone that is the same length as the selection
(hzosc 440)

Code: Select all
; this will produce a 440 Hz tone that is 1 second long
(abs-env (hzosc 440))




BellCurve wrote:now, if I were writing this in C:

We can do a similar thing in Nyquist (and XLISP, on which Nyquist is based).
http://www.audacity-forum.de/download/e ... ef-047.htm
Code: Select all
(setq digit 1)

(case digit
  (0 (print "digit 0"))
  (1 (print "digit 1"))
  (2 (print "digit 2"))
  (t (print "any other")))
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 45327
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: REQ: R1 MF ("Blue box") Tone Generator

Permanent link to this post Posted by steve » Wed Feb 13, 2013 4:21 am

As the MF tones all require exactly two frequencies, we can create a function with one argument for each frequency. We also want to set the duration so we'll use an additional argument for the duration.

The hzosc function that we have been using so far does not take a parameter for duration. Rather than messing about with stretching, we will use the function osc to generate the tones as this does take duration as a parameter http://www.cs.cmu.edu/~rbd/doc/nyquist/ ... l#index361

Code: Select all
;;; generate the MF tone
(defun mftone (hz1 hz2 dur)
  (mult 0.4
    (sim (osc (hz-to-step hz1) dur))
      (osc (hz-to-step hz2) dur)))

; call the function
(mftone 1100 1700 0.1)

As expected, this does not work quite right in the Nyquist Prompt because it is an "effect" and is using "local" time, so the duration ends up as 0.1 times the selection.
To fix this we need to evaluate out function in the default environment ("real time" not "local").
Code: Select all
;;; generate the MF tone
(defun mftone (hz1 hz2 dur)
  (mult 0.4
    (sim (osc (hz-to-step hz1) dur))
      (osc (hz-to-step hz2) dur)))

; call the function
(abs-env (mftone 1100 1700 0.1))
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 45327
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: REQ: R1 MF ("Blue box") Tone Generator

Permanent link to this post Posted by steve » Wed Feb 13, 2013 4:24 am

One last bit for now as it's late now and I need sleep.

Code: Select all
;;; generate the MF tone
(defun mftone (hz1 hz2 dur)
  (mult 0.4
    (sim (osc (hz-to-step hz1) dur))
      (osc (hz-to-step hz2) dur)))

;; call the function
(abs-env
  (sim
    (at 0 (mftone 1100 1700 0.1))
    (at 1 (mftone 700 1700 0.1))
    (at 2 (mftone 1100 500 0.1))))
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 45327
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: REQ: R1 MF ("Blue box") Tone Generator

Permanent link to this post Posted by Robert J. H. » Wed Feb 13, 2013 10:02 am

Perhaps I won't need these tones myself. Nevertheless it's an interesting task, so I gave it a try too.
I've been playing with some recursive code (loops get boring over time).
I only wanted to contribute some code for the sorting out of the text input but ended up with nearly the whole plug-in.
There is in principle only the plug-in header missing.
However, there are some things I am not certain about.
Are there any other inputs besides the text box for the number desired (e.g the volume)?
Have the durations to be varied, as described above, or are the precise values satisfactory?
I fancy, it would be nice when the durations would be varied such that the sine tones end with a full cycle, in order to avoid clicks. Please test the snippet:
Code: Select all
;; A test input:
(setf input "01 234 567 89")

;; the recursive function
(defun number-to-tone (num-stream &aux low-high dur)
  (setf current (pop num-stream))
  (unless current (return-from number-to-tone s))
  (setf dur (if (equal current #>) 0.1 0.068))
  (setf low-high
        (case current
              (#> '(1100 1700)); KP
              (#< '(1500 1700)); ST
              (#1 '(700 900))
              (#2 '(700 1100))
              (#3 '(900 1100))
              (#4 '(700 1300))
              (#5 '(900 1300))
              (#6 '(1100 1300))
              (#7 '(700 1500))
              (#8 '(900 1500))
              (#9 '(1100 1500))
              (#\0 '(1300 1500))
              (t nil)))
  (seq (number-to-tone num-stream)
       (if low-high
           (sim (osc (hz-to-step (first low-high)) dur)
                (osc (hz-to-step (second low-high)) dur)
                (s-rest 0.136))
           (s-rest 0))))

;;; Start of the main program
(setf *sr* *sound-srate*)
; initialize s to 0 length
(setf s (s-rest 0))

; String to chars
(setf numbers
      (cons #<  ; append st
            (reverse (cons #>  ; append kp
                     (get-output-stream-list
                        (make-string-input-stream input))))))

; Return sound
(abs-env (mult 0.4 (number-to-tone numbers)))
Last edited by Robert J. H. on Fri Apr 24, 2015 4:12 pm, edited 2 times in total.
Reason: added a coouple of line breaks to aid readability
Robert J. H.
 
Posts: 1813
Joined: Thu May 31, 2012 8:33 am
Operating System: Windows 7

Re: REQ: R1 MF ("Blue box") Tone Generator

Permanent link to this post Posted by steve » Wed Feb 13, 2013 2:23 pm

Robert J. H. wrote:I've been playing with some recursive code (loops get boring over time).

I was thinking that this might be a good use for an a-list:

Code: Select all
;; association list of parameters
(setf params
  '((KP . (1100 1700))
    (ST . (1500 1700))
    (1 . (700 900))
    (2 . (700 1100))
    (3 . (900 1100))
    (4 . (700 1300))
    (5 . (900 1300))
    (6 . (1100 1300))
    (7 . (700 1500))
    (8 . (900 1500))
    (9 . (1100 1500))
    (0 . (1300 1500))))

(setq mylist '(KP 1 2 3 4 5 4 3 2 1 ST))

(dotimes (i (length mylist))
  (print (assoc (pop mylist) params)))
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 45327
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: REQ: R1 MF ("Blue box") Tone Generator

Permanent link to this post Posted by Annabelle3985 » Sun Oct 25, 2015 3:11 pm

I'd certainly be interested in creating a plugin of this sort. Would I be able to create it in a text editor like Notepad, and then save it as a .ny file?
Annabelle3985
 
Posts: 53
Joined: Sat Oct 24, 2015 1:17 am
Operating System: Windows 7

Re: REQ: R1 MF ("Blue box") Tone Generator

Permanent link to this post Posted by Robert J. H. » Sun Oct 25, 2015 5:22 pm

Annabelle3985 wrote:I'd certainly be interested in creating a plugin of this sort. Would I be able to create it in a text editor like Notepad, and then save it as a .ny file?

Hi Annabelle

You could paste my code directly into the Nyquist prompt and test it as if it were a plug-in.

Just add an appropriate header (copy one from a existing Generate plug-in, for instance)

You'll also need a text control for the input variable.

The code can now be saved directly from within this prompt.
This works with any kind of snippet and you can save with any extension you like, *.ny is only needed for plug-ins.

However, I still favour Notepad++ to create plug-ins.

Cheers
Robert
Robert J. H.
 
Posts: 1813
Joined: Thu May 31, 2012 8:33 am
Operating System: Windows 7

Next

Return to Nyquist



Who is online

Users browsing this forum: No registered users and 2 guests