changeset 32191:19e4617fbc40 stable

Remove obsolete callback constructor code for @audioplayer, @audiorecorder (bug #64379) Remove ancient code for a calling form of @audioplayer, @audiorecorder constructor that is not supported by Matlab and has been commented out and unavailable in Octave for years. * audiodevinfo.cc (init_fn): Delete function. * audiodevinfo.cc (__recorder_audiorecorder__): Remove calling form with first argument a function from Texinfo focumentation. Remove input validation to check for function as first argument. Remove potential call to init_fn(). * audioplayer.m: Remove commented-out documentation for calling form with callback function. Remove input validation checking for function as first argument. Add FIXME note about incomplete input validation for this function. Remove commented-out BIST tests for this functionality. Add BIST test for existing input validation. * audiorecorder.m: Remove commented-out documentation for calling form with callback function. Remove input validation checking for function as first argument. Add FIXME note about lack of input validation for this function. Remove commented-out BIST tests for this functionality. Add BIST tests for existing input validation.
author Rik <rik@octave.org>
date Wed, 12 Jul 2023 09:18:37 -0700
parents 51f4f59a51dc
children 372b73895c89 fe178c793ea0
files libinterp/dldfcn/audiodevinfo.cc scripts/audio/@audioplayer/audioplayer.m scripts/audio/@audiorecorder/audiorecorder.m
diffstat 3 files changed, 11 insertions(+), 172 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/dldfcn/audiodevinfo.cc	Sat Jul 08 22:30:12 2023 -0700
+++ b/libinterp/dldfcn/audiodevinfo.cc	Wed Jul 12 09:18:37 2023 -0700
@@ -536,7 +536,6 @@
   bool print_as_scalar (void) const { return true; }
 
   void init (void);
-  void init_fn (void);
   void set_y (const octave_value& y);
   void set_y (octave_function *fcn);
   void set_y (std::string fcn);
@@ -904,36 +903,6 @@
 }
 
 void
-audioplayer::init_fn (void)
-{
-  if (Pa_Initialize () != paNoError)
-    error ("audioplayer: initialization error");
-
-  if (Pa_GetDeviceCount () < 1)
-    error ("audioplayer: no audio devices found or available");
-
-  int device = get_id ();
-
-  if (device == -1)
-    device = Pa_GetDefaultOutputDevice ();
-
-  output_parameters.device = device;
-  output_parameters.channelCount = 2;
-  output_parameters.sampleFormat = bits_to_format (get_nbits ());
-
-  const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
-
-  if (! device_info)
-    warning_with_id ("Octave:invalid-default-audio-device",
-                     "invalid default audio device ID = %d", device);
-
-  output_parameters.suggestedLatency
-    = (device_info ? device_info->defaultHighOutputLatency : -1);
-
-  output_parameters.hostApiSpecificStreamInfo = nullptr;
-}
-
-void
 audioplayer::init (void)
 {
   // FIXME: Both of these variables are unused.
@@ -1916,7 +1885,6 @@
            doc: /* -*- texinfo -*-
 @deftypefn  {} {@var{recorder} =} __recorder_audiorecorder__ (@var{fs}, @var{nbits}, @var{channels})
 @deftypefnx {} {@var{recorder} =} __recorder_audiorecorder__ (@var{fs}, @var{nbits}, @var{channels}, @var{id})
-@deftypefnx {} {@var{recorder} =} __recorder_audiorecorder__ (@var{fcn}, @dots{})
 Undocumented internal function.
 @end deftypefn */)
 {
@@ -1928,15 +1896,6 @@
 
   audiorecorder *recorder = new audiorecorder ();
 
-  if (nargin > 0)
-    {
-      bool is_function = (args(0).is_string () || args(0).is_function_handle ()
-                          || args(0).is_inline_function ());
-
-      if (is_function)
-        error ("audiorecorder: callback functions are not yet implemented");
-    }
-
   if (nargin >= 3)
     {
       recorder->set_fs (args(0).int_value ());
@@ -2342,12 +2301,6 @@
 
   audioplayer *recorder = new audioplayer ();
 
-  bool is_function = (args(0).is_string () || args(0).is_function_handle ()
-                      || args(0).is_inline_function ());
-
-  if (is_function)
-    error ("audioplayer: callback functions are not yet implemented");
-
   recorder->set_y (args(0));
   recorder->set_fs (args(1).int_value ());
 
@@ -2371,10 +2324,7 @@
         }
     }
 
-  if (is_function)
-    recorder->init_fn ();
-  else
-    recorder->init ();
+  recorder->init ();
 
   retval = recorder;
 #else
--- a/scripts/audio/@audioplayer/audioplayer.m	Sat Jul 08 22:30:12 2023 -0700
+++ b/scripts/audio/@audioplayer/audioplayer.m	Wed Jul 12 09:18:37 2023 -0700
@@ -75,47 +75,9 @@
 ## @audiorecorder/audiorecorder, sound, soundsc}
 ## @end deftypefn
 
-################################################################################
-## FIXME: callbacks don't work properly, apparently because portaudio
-## will execute the callbacks in a separate thread, and calling Octave
-## functions in a separate thread which is likely to cause trouble with
-## all of Octave's global data...
-##
-## @deftypefnx {} {@var{player} =} audioplayer (@var{function}, @dots{})
-##
-## Given a function handle, use that function to process the audio.
-#
-## The following example will create and register a callback that generates
-## a sine wave on both channels.
-##
-## @example
-## @group
-## function [ sound, status ] = callback_sine (frames)
-##   global lphase = 0.0;
-##   global rphase = 0.0;
-##   incl = 440.0 / 44100.0;
-##   incr = 443.0 / 44100.0;
-##   nl = incl * frames;
-##   nr = incr * frames;
-##   left = sin (2.0 * pi * [lphase:incl:lphase+nl]);
-##   right = sin (2.0 * pi * [rphase:incr:rphase+nr]);
-##   sound = [left', right'];
-##   status = 0;
-##   lphase = lphase + nl;
-##   rphase = rphase + nr;
-## endfunction
-## player = audioplayer (@@callback_sine, 44100);
-## play (player);
-## # play for as long as you want
-## stop (player);
-## @end group
-################################################################################
-
 function player = audioplayer (varargin)
 
-  if (nargin < 1 || nargin > 4
-      || (nargin < 2 && ! (is_function_handle (varargin{1})
-                           || ischar (varargin{1}))))
+  if (nargin < 1 || nargin > 4)
     print_usage ();
   endif
 
@@ -133,14 +95,8 @@
       print_usage ();
     endif
   else
-    ## FIXME: Prevent use of callbacks until situation is fixed.
-    if (is_function_handle (varargin{1}) || ischar (varargin{1}))
-      error ("audioplayer: first argument cannot be a callback function");
-    endif
-    ## FIXME: Uncomment when callback functions are supported.
-    ## if (ischar (varargin{1}))
-    ##   varargin{1} = str2func (varargin{1});
-    ## endif
+    ## FIXME: There is incomplete input validation in internal C++ function.
+    ##        All validation should occur here in m-file.
     if (isempty (varargin{1}))
       error ("audioplayer: Y must be non-empty numeric data");
     endif
@@ -187,26 +143,6 @@
 %! assert (player.SampleRate, 44100);
 %! assert (player.BitsPerSample, 16);
 
-## FIXME: Callbacks do not work currently (5/31/2020) so BIST tests commented.
-%!#function [sound, status] = callback (samples)
-%!#  sound = rand (samples, 2) - 0.5;
-%!#  status = 0;
-%!#endfunction
-
-%!#testif HAVE_PORTAUDIO
-%!# player = audioplayer (@callback, 44100);
-%!# play (player);
-%!# pause (2);
-%!# stop (player);
-%!# assert (1);
-
-%!#testif HAVE_PORTAUDIO
-%!# player = audioplayer ("callback", 44100, 16);
-%!# play (player);
-%!# pause (2);
-%!# stop (player);
-%!# assert (1);
-
 ## Verify input validation
 %!testif HAVE_PORTAUDIO; audiodevinfo (0) > 0
 %! ## Verify nbits option only accepts 8, 16, 24
@@ -216,5 +152,4 @@
 %! player = audioplayer (1, 8e3, 16);
 %! player = audioplayer (1, 8e3, 24);
 
-%!error <first argument cannot be a callback> audioplayer (@ls, 8000)
-%!error <first argument cannot be a callback> audioplayer ("ls", 8000)
+%!error <Y must be non-empty numeric data> audioplayer ([])
--- a/scripts/audio/@audiorecorder/audiorecorder.m	Sat Jul 08 22:30:12 2023 -0700
+++ b/scripts/audio/@audiorecorder/audiorecorder.m	Wed Jul 12 09:18:37 2023 -0700
@@ -59,33 +59,14 @@
 ## @audiorecorder/recordblocking, @audioplayer/resume, @audiorecorder/set,
 ## @audiorecorder/stop, audiodevinfo, @audioplayer/audioplayer, record}
 
-################################################################################
-## FIXME: callbacks don't work properly, apparently because portaudio
-## will execute the callbacks in a separate thread, and calling Octave
-## functions in a separate thread is likely to cause trouble with
-## all of Octave's global data...
-##
-## @deftypefnx {} {@var{recorder} =} audiorecorder (@var{function}, @dots{})
-##
-## Given a function handle, use that function to process the audio.
-################################################################################
-
 function recorder = audiorecorder (varargin)
 
-  if (nargin > 5)
+  if (! (nargin == 0 || nargin == 3 || nargin == 4))
     print_usage ();
   endif
 
-  ## FIXME: Prevent use of callbacks until situation is fixed.
-  if (nargin > 0 && (is_function_handle (varargin{1}) || ischar (varargin{1})))
-    error ("audiorecorder: first argument cannot be a callback function");
-  endif
-
-  ## FIXME: Uncomment when callback functions are supported.
-  ## if (nargin > 0 && ischar (varargin{1}))
-  ##   varargin{1} = str2func (varargin{1});
-  ## endif
-
+  ## FIXME: No input validation in internal C++ function.
+  ##        It should occur here.
   recorder.recorder = __recorder_audiorecorder__ (varargin{:});
   recorder = class (recorder, "audiorecorder");
 
@@ -108,34 +89,7 @@
 
 ## Tests of audiorecorder must not actually record anything.
 
-## FIXME: Uncomment when callbacks are supported
-%!#function status = callback_record (sound)
-%!#  fid = fopen ("record.txt", "at");
-%!#  for index = 1:rows(sound)
-%!#    fprintf (fid, "%.4f, %.4f\n", sound(index, 1), sound(index, 2));
-%!#  endfor
-%!#  fclose (fid);
-%!#  status = 0;
-%!#endfunction
-
-%!#testif HAVE_PORTAUDIO
-%!# recorder = audiorecorder (@callback_record, 44100);
-%!# unlink ("record.txt")
-%!# record (recorder);
-%!# pause (2);
-%!# stop (recorder);
-%!# s = stat ("record.txt");
-%!# assert (s.size > 0);
-
-%!#testif HAVE_PORTAUDIO
-%!# recorder = audiorecorder (@callback_record, 44100);
-%!# unlink ("record.txt")
-%!# record (recorder);
-%!# pause (2);
-%!# stop (recorder);
-%!# s = stat ("record.txt");
-%!# assert (s.size > 0);
-
 ## Test input validation
-%!error <first argument cannot be a callback> audiorecorder (@ls)
-%!error <first argument cannot be a callback> audiorecorder ("ls")
+%!error <Invalid call> audiorecorder (1)
+%!error <Invalid call> audiorecorder (1, 8)
+%!error <Invalid call> audiorecorder (1, 8, 2, -1, 5)