# HG changeset patch # User John W. Eaton # Date 1420177235 18000 # Node ID 99522db5b911b8de88e5c4135a70451f346e53ef # Parent 2a16dac2176f758b75dd614543b0d5f7c11e7345 merge audio source files * audiodevinfo.cc: Fold __player_audioplayer__.cc, __recorder_audiorecorder__.cc, player_class.cc, player_class.h, recorder_class.cc, and recorder_class.h into this source file. * audioread.cc: Fold audioinfo.cc and audiowrite.cc into this source file. * libinterp/dldfcn/module-files: Update. diff -r 2a16dac2176f -r 99522db5b911 libinterp/dldfcn/__player_audioplayer__.cc --- a/libinterp/dldfcn/__player_audioplayer__.cc Wed Dec 31 15:38:13 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,488 +0,0 @@ -/* - -Copyright (C) 2013 Vytautas Jančauskas - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -. - -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "oct.h" -#include "ov-struct.h" - -#ifdef HAVE_PORTAUDIO -#include "player_class.cc" -#include "recorder_class.cc" -#endif - -DEFUN_DLD (__player_audioplayer__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{player} =} __player_audioplayer__ (@var{y}, @var{fs})\n\ -@deftypefnx {Loadable Function} {@var{player} =} __player_audioplayer__ (@var{y}, @var{fs}, @var{nbits})\n\ -@deftypefnx {Loadable Function} {@var{player} =} __player_audioplayer__ (@var{y}, @var{fs}, @var{nbits}, @var{id})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - audioplayer* retval = new audioplayer (); - bool is_function = args(0).is_string () || args(0).is_function_handle () || args(0).is_inline_function (); - if (is_function) - retval->set_y (args(0).function_value ()); - else - retval->set_y (args(0)); - retval->set_fs (args(1).int_value ()); - switch (nargin) - { - case 3: - retval->set_nbits (args(2).int_value ()); - break; - case 4: - retval->set_nbits (args(2).int_value ()); - retval->set_id (args(3).int_value ()); - break; - } - if (is_function) - retval->init_fn (); - else - retval->init (); - return octave_value (retval); -#else - octave_value retval; - error ("portaudio not found on your system and thus audio functionality is not present"); - return retval; -#endif -} - -DEFUN_DLD (__player_get_channels__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{n} =} __player_get_channels__ (@var{player})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - retval = octave_value (player->get_channels ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_get_fs__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{fs} =} __player_get_fs__ (@var{player})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - retval = octave_value (player->get_fs ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_get_id__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{id} =} __player_get_id__ (@var{player})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - retval = octave_value (player->get_id ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_get_nbits__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{nbits} =} __player_get_nbits__ (@var{player})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - retval = octave_value (player->get_nbits ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_get_sample_number__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{n} =} __player_get_sample_number__ (@var{player})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - retval = octave_value (player->get_sample_number ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_get_tag__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{tag} =} __player_get_tag__ (@var{player})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - retval = octave_value (player->get_tag ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_get_total_samples__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{n} =} __player_get_total_samples__ (@var{player})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - retval = octave_value (player->get_total_samples ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_get_userdata__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{data} =} __player_get_userdata__ (@var{player})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - retval = player->get_userdata (); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_isplaying__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __player_isplaying__ (@var{player})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - if (player->isplaying ()) - return octave_value (1); - else - return octave_value (0); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_pause__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __player_pause__ (@var{player})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - player->pause (); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_playblocking__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __player_playblocking__ (@var{player})\n\ -@deftypefnx {Loadable Function} {} __player_playblocking__ (@var{player}, @var{start})\n\ -@deftypefnx {Loadable Function} {} __player_playblocking__ (@var{player}, [@var{start}, @var{end}])\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - player->playblocking (); - } - else - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - if (args(1).is_matrix_type ()) - { - unsigned int start, end; - RowVector range = args(1).row_vector_value (); - start = range.elem (0) - 1; - end = range.elem (1) - 1; - if (start < 0 or start > player->get_total_samples () or - start > end or end < 0 or end > player->get_total_samples ()) - error ("audioplayer: invalid range specified for playback"); - player->set_sample_number (start); - player->set_end_sample (end); - } - else - { - unsigned int start; - start = args(1).int_value () - 1; - if (start < 0 or start > player->get_total_samples ()) - error ("audioplayer: invalid range specified for playback"); - player->set_sample_number (start); - } - player->playblocking (); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_play__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __player_play__ (@var{player})\n\ -@deftypefnx {Loadable Function} {} __player_play__ (@var{player}, @var{start})\n\ -@deftypefnx {Loadable Function} {} __player_play__ (@var{player}, [@var{start}, @var{end}])\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - player->play (); - } - else - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - if (args(1).is_matrix_type ()) - { - unsigned int start, end; - RowVector range = args(1).row_vector_value (); - start = range.elem (0) - 1; - end = range.elem (1) - 1; - if (start < 0 or start > player->get_total_samples () or - start > end or end < 0 or end > player->get_total_samples ()) - error ("audioplayer: invalid range specified for playback"); - player->set_sample_number (start); - player->set_end_sample (end); - } - else - { - unsigned int start; - start = args(1).int_value () - 1; - if (start < 0 or start > player->get_total_samples ()) - error ("audioplayer: invalid range specified for playback"); - player->set_sample_number (start); - } - player->play (); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_resume__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __player_resume__ (@var{player})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - player->resume (); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_set_fs__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __player_set_fs__ (@var{player}, @var{fs})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 2) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - player->set_fs (args(1).int_value ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_set_tag__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __player_set_tag__ (@var{player}, @var{tag})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 2) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - player->set_tag (args(1).char_matrix_value ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_set_userdata__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __player_set_userdata__ (@var{player}, @var{data})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 2) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - player->set_userdata (args(1)); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__player_stop__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __player_stop__ (@var{player})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audioplayer *player = &((audioplayer &)rep); - player->stop (); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} diff -r 2a16dac2176f -r 99522db5b911 libinterp/dldfcn/__recorder_audiorecorder__.cc --- a/libinterp/dldfcn/__recorder_audiorecorder__.cc Wed Dec 31 15:38:13 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,455 +0,0 @@ -/* - -Copyright (C) 2013 Vytautas Jančauskas - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -. - -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "oct.h" -#include "ov-struct.h" - -#ifdef HAVE_PORTAUDIO -#include "player_class.cc" -#include "recorder_class.cc" -#endif - -DEFUN_DLD (__recorder_audiorecorder__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{recorder} =} __recorder_audiorecorder__ (@var{fs}, @var{nbits}, @var{channels})\n\ -@deftypefnx {Loadable Function} {@var{recorder} =} __recorder_audiorecorder__ (@var{fs}, @var{nbits}, @var{channels}, @var{id})\n\ -@deftypefnx {Loadable Function} {@var{recorder} =} __recorder_audiorecorder__ (@var{fcn}, @dots{})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - audiorecorder* retval = new audiorecorder (); - int offset = 0; - if (nargin > 0) - { - bool is_function = args(0).is_string () || args(0).is_function_handle () || args(0).is_inline_function (); - if (is_function) - { - retval->octave_callback_function = args(0).function_value (); - offset = 1; - } - } - switch (nargin - offset) - { - case 3: - retval->set_fs (args(0 + offset).int_value ()); - retval->set_nbits (args(1 + offset).int_value ()); - retval->set_channels (args(2 + offset).int_value ()); - break; - case 4: - retval->set_fs (args(0 + offset).int_value ()); - retval->set_nbits (args(1 + offset).int_value ()); - retval->set_channels (args(2 + offset).int_value ()); - retval->set_id (args(3 + offset).int_value ()); - break; - } - retval->init (); - return octave_value (retval); -#else - octave_value retval; - error ("portaudio not found on your system and thus audio functionality is not present"); - return retval; -#endif -} - -DEFUN_DLD (__recorder_getaudiodata__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{data}} __recorder_getaudiodata__ (@var{recorder})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - retval = octave_value (recorder->getaudiodata ()); -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_get_channels__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{n} =} __recorder_get_channels__ (@var{recorder})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - retval = octave_value (recorder->get_channels ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_get_fs__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{fs} =} __recorder_get_fs__ (@var{recorder})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - retval = octave_value (recorder->get_fs ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_get_id__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{id} =} __recorder_get_id__ (@var{recorder})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - retval = octave_value (recorder->get_id ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_get_nbits__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{nbits} =} __recorder_get_nbits__ (@var{recorder})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - retval = octave_value (recorder->get_nbits ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_get_sample_number__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{n} =} __recorder_get_sample_number__ (@var{recorder})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - retval = octave_value (recorder->get_sample_number ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_get_tag__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{tag} =} __recorder_get_tag__ (@var{recorder})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - retval = octave_value (recorder->get_tag ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_get_total_samples__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{n} =} __recorder_get_total_samples__ (@var{recorder})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - retval = octave_value (recorder->get_total_samples ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_get_userdata__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{data} =} __recorder_get_userdata__ (@var{recorder})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - retval = recorder->get_userdata (); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_isrecording__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __recorder_isrecording__ (@var{recorder})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - if (recorder->isrecording ()) - return octave_value (1); - else - return octave_value (0); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_pause__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __recorder_pause__ (@var{recorder})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - recorder->pause (); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_recordblocking__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __recorder_recordblocking__ (@var{recorder}, @var{seconds})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - recorder->recordblocking (args(1).float_value ()); -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_record__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __recorder_record__ (@var{recorder})\n\ -@deftypefnx {Loadable Function} {} __recorder_record__ (@var{recorder}, @var{seconds})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - if (args.length () == 1) - { - recorder->record (); - } - else if (args.length () == 2) - { - recorder->set_end_sample (args(1).int_value () * recorder->get_fs ()); - recorder->record (); - } - else - { - error ("audiorecorder: wrong number of arguments passed to record"); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_resume__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __recorder_resume__ (@var{recorder})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 1) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - recorder->resume (); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_set_fs__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __recorder_set_fs__ (@var{recorder}, @var{fs})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 2) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - recorder->set_fs (args(1).int_value ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_set_tag__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __recorder_set_tag__ (@var{recorder}, @var{tag})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 2) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - recorder->set_tag (args(1).char_matrix_value ()); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_set_userdata__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __recorder_set_userdata__ (@var{recorder}, @var{data})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - int nargin = args.length (); - if (nargin == 2) - { - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - recorder->set_userdata (args(1)); - } -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} - -DEFUN_DLD (__recorder_stop__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __recorder_stop__ (@var{recorder})\n\ -Undocumented internal function.\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_PORTAUDIO - const octave_base_value& rep = args(0).get_rep (); - audiorecorder *recorder = &((audiorecorder &)rep); - recorder->stop (); -#else - error ("portaudio not found on your system and thus audio functionality is not present"); -#endif - return retval; -} diff -r 2a16dac2176f -r 99522db5b911 libinterp/dldfcn/audiodevinfo.cc --- a/libinterp/dldfcn/audiodevinfo.cc Wed Dec 31 15:38:13 2014 -0500 +++ b/libinterp/dldfcn/audiodevinfo.cc Fri Jan 02 00:40:35 2015 -0500 @@ -24,9 +24,21 @@ #include #endif +// requires c++11 +#include + +#include +#include + #include "oct.h" +#include "ov.h" #include "ov-struct.h" +#include "ov-int32.h" +#include "parse.h" + +#if defined (HAVE_PORTAUDIO) #include +#endif PaSampleFormat bits_to_format (int bits) @@ -411,3 +423,2085 @@ %! assert (devinfo.input(i).ID, audiodevinfo (1, devinfo.input(i).Name)) %! endfor */ + +enum audio_type { INT8, UINT8, INT16, DOUBLE }; + +class audioplayer : public octave_base_value +{ +public: + audioplayer (void); + ~audioplayer (void) {}; + + // Overloaded base functions + double player_value (void) const { return 0; } + virtual double scalar_value (bool frc_str_conv = false) const { return 0; } + void print (std::ostream& os, bool pr_as_read_syntax = false) const; + void print_raw (std::ostream& os, bool pr_as_read_syntax) const; + + // Properties + bool is_constant (void) const { return true; } + bool is_defined (void) const { return true; } + bool print_as_scalar (void) const { return true; } + + void init (void); + void init_fn (void); + void set_y (octave_value y); + void set_y (octave_function *fn); + void set_y (std::string fn); + Matrix& get_y (void); + RowVector *get_left (void); + RowVector *get_right (void); + void set_fs (int fs); + int get_fs (void); + void set_nbits (int nbits); + int get_nbits (void); + void set_id (int id); + int get_id (void); + int get_channels (void); + audio_type get_type (void); + + void set_sample_number (unsigned int sample); + unsigned int get_sample_number (void); + unsigned int get_total_samples (void); + void set_end_sample (unsigned int sample); + unsigned int get_end_sample (void); + void reset_end_sample (void); + void set_tag (charMatrix tag); + charMatrix get_tag (void); + void set_userdata (octave_value userdata); + octave_value get_userdata (void); + PaStream *get_stream (void); + octave_function *octave_callback_function; + + void playblocking (void); + void play (void); + void pause (void); + void resume (void); + void stop (void); + bool isplaying (void); + +private: + Matrix y; + RowVector left; + RowVector right; + charMatrix tag; + octave_value userdata; + int channels; + int fs; + int nbits; + int id; + unsigned int sample_number; + unsigned int end_sample; + PaStream *stream; + PaStreamParameters output_parameters; + audio_type type; + DECLARE_OCTAVE_ALLOCATOR + DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA +}; + +#define BUFFER_SIZE 512 + +DEFINE_OCTAVE_ALLOCATOR (audioplayer); +DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (audioplayer, "audioplayer", "audioplayer"); + +int +is_big_endian (void) +{ + union + { + uint32_t i; + char c[4]; + } bint = { 0x01020304 }; + return bint.c[0] == 1; +} + +static int +octave_play_callback (const void *input, void *output, + unsigned long frames, + const PaStreamCallbackTimeInfo *time, + PaStreamCallbackFlags status, + void *data) +{ + audioplayer *player = (audioplayer *)data; + int big_endian = is_big_endian (); + octave_value_list args, retval; + args(0) = frames; + retval = feval (player->octave_callback_function, args, 1); + RowVector sound_l, sound_r; + Matrix sound = retval(0).matrix_value (); + int return_status = retval(1).int_value (); + sound_l.resize (frames); + sound_r.resize (frames); + if (sound.cols () == 1) + { + for (int i = 0; i < frames; i++) + { + sound_l(i) = sound(i, 0); + sound_r(i) = sound(i, 0); + } + } + else if (sound.cols () == 2) + { + for (int i = 0; i < frames; i++) + { + sound_l(i) = sound(i, 0); + sound_r(i) = sound(i, 1); + } + } + else + return paAbort; + + for (int i = 0; i < frames; i++) + { + if (player->get_nbits () == 8) + { + int8_t *buffer = (int8_t *)output; + buffer[2 * i] = sound_l.elem (i) * (pow (2.0, 7) - 1); + buffer[2 * i + 1] = sound_r.elem (i) * (pow (2.0, 7) - 1); + } + else if (player->get_nbits () == 16) + { + int16_t *buffer = (int16_t *)output; + buffer[2 * i] = sound_l.elem (i) * (pow (2.0, 15) - 1); + buffer[2 * i + 1] = sound_r.elem (i) * (pow (2.0, 15) - 1); + } + else if (player->get_nbits () == 24) + { + uint8_t *buffer = (uint8_t *)output; + int32_t sample_l = sound_l.elem (i) * (pow (2.0, 23) - 1); + int32_t sample_r = sound_r.elem (i) * (pow (2.0, 23) - 1); + sample_l &= 0x00ffffff; + sample_r &= 0x00ffffff; + uint8_t *_sample_l = (uint8_t *)&sample_l; + uint8_t *_sample_r = (uint8_t *)&sample_r; + buffer[i * 6 + 0] = _sample_l[0 + big_endian]; + buffer[i * 6 + 1] = _sample_l[1 + big_endian]; + buffer[i * 6 + 2] = _sample_l[2 + big_endian]; + buffer[i * 6 + 3] = _sample_r[0 + big_endian]; + buffer[i * 6 + 4] = _sample_r[1 + big_endian]; + buffer[i * 6 + 5] = _sample_r[2 + big_endian]; + } + } + return return_status; +} + +static int +portaudio_play_callback (const void *input, void *output, + unsigned long frames, + const PaStreamCallbackTimeInfo* time, + PaStreamCallbackFlags status, + void *data) +{ + audioplayer *player = (audioplayer *)data; + int big_endian = is_big_endian (); + int channels = player->get_channels (); + RowVector *sound_l = player->get_left (); + RowVector *sound_r; + + if (channels > 1) + sound_r = player->get_right (); + else + sound_r = sound_l; + + for (int j = 0, k = 0; j < frames; j++, k += 2) + { + unsigned int sample_number = player->get_sample_number (); + if (sample_number > player->get_end_sample ()) + return paAbort; + + if (player->get_type () == DOUBLE) + { + if (player->get_nbits () == 8) + { + int8_t *buffer = (int8_t *)output; + buffer[k] = sound_l->elem (sample_number) * (pow (2.0, 7) - 1); + buffer[k + 1] = sound_r->elem (sample_number) * (pow (2.0, 7) - 1); + } + else if (player->get_nbits () == 16) + { + int16_t *buffer = (int16_t *)output; + buffer[k] = sound_l->elem (sample_number) * (pow (2.0, 15) - 1); + buffer[k + 1] = sound_r->elem (sample_number) * (pow (2.0, 15) - 1); + } + else if (player->get_nbits () == 24) + { + uint8_t *buffer = (uint8_t *)output; + int32_t sample_l = sound_l->elem (sample_number) * (pow (2.0, 23) - 1); + int32_t sample_r = sound_r->elem (sample_number) * (pow (2.0, 23) - 1); + sample_l &= 0x00ffffff; + sample_r &= 0x00ffffff; + uint8_t *_sample_l = (uint8_t *)&sample_l; + uint8_t *_sample_r = (uint8_t *)&sample_r; + buffer[j * 6 + 0] = _sample_l[0 + big_endian]; + buffer[j * 6 + 1] = _sample_l[1 + big_endian]; + buffer[j * 6 + 2] = _sample_l[2 + big_endian]; + buffer[j * 6 + 3] = _sample_r[0 + big_endian]; + buffer[j * 6 + 4] = _sample_r[1 + big_endian]; + buffer[j * 6 + 5] = _sample_r[2 + big_endian]; + } + } + else if (player->get_type () == INT8) + { + int8_t *buffer = (int8_t *)output; + buffer[k] = sound_l->elem (sample_number); + buffer[k + 1] = sound_r->elem (sample_number); + } + else if (player->get_type () == UINT8) + { + uint8_t *buffer = (uint8_t *)output; + buffer[k] = sound_l->elem (sample_number); + buffer[k + 1] = sound_r->elem (sample_number); + } + else if (player->get_type () == INT16) + { + int16_t *buffer = (int16_t *)output; + buffer[k] = sound_l->elem (sample_number); + buffer[k + 1] = sound_r->elem (sample_number); + } + player->set_sample_number (sample_number + 1); + } + return paContinue; +} + +audioplayer::audioplayer (void) +{ + this->nbits = 16; + this->id = -1; + this->sample_number = 0; + this->tag = charMatrix (""); + Matrix userdata; + this->userdata = octave_value (userdata); + this->stream = 0; + this->octave_callback_function = 0; +} + +void +audioplayer::print (std::ostream& os, bool pr_as_read_syntax) const +{ + print_raw (os, pr_as_read_syntax); + newline (os); +} + +void +audioplayer::print_raw (std::ostream& os, bool pr_as_read_syntax) const +{ + os << 0; +} + +void +audioplayer::init_fn (void) +{ + PaError err; + int device; + + err = Pa_Initialize (); + if (err != paNoError) + { + error ("audioplayer: Initialization error!"); + return; + } + + int numDevices = Pa_GetDeviceCount (); + if (numDevices < 0) + { + error ("audioplayer: No audio devices found!"); + return; + } + + if (this->get_id () == -1) + device = Pa_GetDefaultOutputDevice (); + else + device = this->get_id (); + + output_parameters.device = device; + output_parameters.channelCount = 2; + output_parameters.sampleFormat = bits_to_format (this->get_nbits ()); + output_parameters.suggestedLatency = Pa_GetDeviceInfo (device)->defaultHighOutputLatency; + output_parameters.hostApiSpecificStreamInfo = NULL; +} + +void +audioplayer::init (void) +{ + PaError err; + int channels = this->y.rows (); + RowVector *sound_l = this->get_left (); + int device; + + err = Pa_Initialize (); + if (err != paNoError) + { + error ("audioplayer: Initialization error!"); + return; + } + + int numDevices = Pa_GetDeviceCount (); + if (numDevices < 0) + { + error ("audioplayer: No audio devices found!"); + return; + } + + if (this->get_id () == -1) + device = Pa_GetDefaultOutputDevice (); + else + device = this->get_id (); + + output_parameters.device = device; + output_parameters.channelCount = 2; + + if (this->type == DOUBLE) + output_parameters.sampleFormat = bits_to_format (this->get_nbits ()); + else if (this->type == INT8) + output_parameters.sampleFormat = paInt8; + else if (this->type == UINT8) + output_parameters.sampleFormat = paUInt8; + else if (this->type == INT16) + output_parameters.sampleFormat = paInt16; + + output_parameters.suggestedLatency = Pa_GetDeviceInfo (device)->defaultHighOutputLatency; + output_parameters.hostApiSpecificStreamInfo = NULL; +} + +void +audioplayer::set_y (octave_value y) +{ + if (y.is_int8_type ()) + this->type = INT8; + else if (y.is_uint8_type ()) + this->type = UINT8; + else if (y.is_int16_type ()) + this->type = INT16; + else + this->type = DOUBLE; + + this->y = y.matrix_value (); + if (this->y.rows () > 2) + this->y = this->y.transpose (); + + this->channels = this->y.rows (); + this->left = this->y.row (0); + if (this->channels == 2) + this->right = this->y.row (1); + + this->reset_end_sample (); +} + +void +audioplayer::set_y (octave_function *fn) +{ + this->octave_callback_function = fn; + this->channels = 2; + this->reset_end_sample (); +} + +Matrix& +audioplayer::get_y (void) +{ + return this->y; +} + +RowVector * +audioplayer::get_left (void) +{ + return &(this->left); +} + +RowVector * +audioplayer::get_right (void) +{ + return &(this->right); +} + +void +audioplayer::set_fs (int fs) +{ + this->fs = fs; +} + +int +audioplayer::get_fs (void) +{ + return this->fs; +} + +void +audioplayer::set_nbits (int nbits) +{ + this->nbits = nbits; +} + +int +audioplayer::get_nbits (void) +{ + return this->nbits; +} + +void +audioplayer::set_id (int id) +{ + this->id = id; +} + +int +audioplayer::get_id (void) +{ + return this->id; +} + +int +audioplayer::get_channels (void) +{ + return this->channels; +} + +audio_type +audioplayer::get_type (void) +{ + return this->type; +} + +void +audioplayer::set_sample_number (unsigned int sample_number) +{ + this->sample_number = sample_number; +} + +unsigned int +audioplayer::get_sample_number (void) +{ + return this->sample_number; +} + +unsigned int +audioplayer::get_total_samples (void) +{ + return this->left.length (); +} + +void +audioplayer::set_end_sample (unsigned int end_sample) +{ + this->end_sample = end_sample; +} + +unsigned int +audioplayer::get_end_sample (void) +{ + return this->end_sample; +} + +void +audioplayer::reset_end_sample (void) +{ + this->set_end_sample (this->left.length ()); +} + +void +audioplayer::set_tag (charMatrix tag) +{ + this->tag = tag; +} + +charMatrix +audioplayer::get_tag (void) +{ + return this->tag; +} + +void +audioplayer::set_userdata (octave_value userdata) +{ + this->userdata = userdata; +} + +octave_value +audioplayer::get_userdata (void) +{ + return this->userdata; +} + +void +audioplayer::playblocking (void) +{ + if (this->get_stream ()) + this->stop (); + + PaError err; + uint32_t buffer[BUFFER_SIZE * 2]; + err = Pa_OpenStream (&stream, NULL, &(this->output_parameters), this->get_fs (), BUFFER_SIZE, paClipOff, NULL, NULL); + if (err != paNoError) + { + error ("audioplayer: Error opening audio playback stream"); + return; + } + + err = Pa_StartStream (stream); + if (err != paNoError) + { + error ("audioplayer: Error starting audio playback stream"); + return; + } + + unsigned int start, end; + start = this->get_sample_number (); + end = this->get_end_sample (); + for (int i = start; i < end; i += BUFFER_SIZE) + { + if (this->octave_callback_function != 0) + octave_play_callback (0, (void *)buffer, BUFFER_SIZE, 0, 0, (void *)this); + else + portaudio_play_callback (0, (void *)buffer, BUFFER_SIZE, 0, 0, (void *)this); + err = Pa_WriteStream (stream, buffer, BUFFER_SIZE); + } + + err = Pa_StopStream (stream); + if (err != paNoError) + { + error ("audioplayer: Error stoping audio playback stream"); + return; + } + + err = Pa_CloseStream (stream); + if (err != paNoError) + { + error ("audioplayer: Error closing audio playback stream"); + return; + } + + stream = 0; + this->set_sample_number (0); + this->reset_end_sample (); +} + +void +audioplayer::play (void) +{ + if (this->get_stream ()) + this->stop (); + + PaError err; + if (this->octave_callback_function != 0) + err = Pa_OpenStream (&stream, NULL, &(this->output_parameters), this->get_fs (), BUFFER_SIZE, paClipOff, octave_play_callback, (void *)this); + else + err = Pa_OpenStream (&stream, NULL, &(this->output_parameters), this->get_fs (), BUFFER_SIZE, paClipOff, portaudio_play_callback, (void *)this); + + if (err != paNoError) + { + error ("audioplayer: Error opening audio playback stream"); + return; + } + + err = Pa_StartStream (stream); + if (err != paNoError) + { + error ("audioplayer: Error starting audio playback stream"); + return; + } +} + +void +audioplayer::pause (void) +{ + if (this->get_stream () == 0) + return; + + PaError err; + err = Pa_StopStream (stream); + if (err != paNoError) + { + error ("audiorecorder: Error stoping audio recording stream"); + return; + } +} + +void +audioplayer::resume (void) +{ + if (this->get_stream () == 0) + return; + + PaError err; + err = Pa_StartStream (stream); + if (err != paNoError) + { + error ("audiorecorder: Error starting audio recording stream"); + return; + } +} + +PaStream * +audioplayer::get_stream (void) +{ + return this->stream; +} + +void +audioplayer::stop (void) +{ + if (this->get_stream () == 0) + return; + + PaError err; + this->set_sample_number (0); + this->reset_end_sample (); + if (not Pa_IsStreamStopped (this->get_stream ())) + { + err = Pa_AbortStream (this->get_stream ()); + if (err != paNoError) + { + error ("audioplayer: Error stopping audio playback stream"); + return; + } + } + + err = Pa_CloseStream (this->get_stream ()); + if (err != paNoError) + { + error ("audioplayer: Error closing audio playback stream"); + return; + } + + stream = 0; +} + +bool +audioplayer::isplaying (void) +{ + if (this->get_stream () == 0) + return false; + + PaError err; + err = Pa_IsStreamActive (stream); + if (err != 0 and err != 1) + { + error ("audiorecorder: Error checking stream activity status"); + return false; + } + + return (err == 1); +} + +class audiorecorder : public octave_base_value +{ +public: + audiorecorder (void); + ~audiorecorder (void) {}; + + // Overloaded base functions + double player_value (void) const { return 0; } + virtual double scalar_value (bool frc_str_conv = false) const { return 0; } + void print (std::ostream& os, bool pr_as_read_syntax = false) const; + void print_raw (std::ostream& os, bool pr_as_read_syntax) const; + + // Properties + bool is_constant (void) const { return true; } + bool is_defined (void) const { return true; } + bool print_as_scalar (void) const { return true; } + + void init (void); + void set_fs (int fs); + int get_fs (void); + void set_nbits (int nbits); + int get_nbits (void); + void set_id (int id); + int get_id (void); + void set_channels (int channels); + int get_channels (void); + audio_type get_type (void); + + void set_sample_number (unsigned int sample); + unsigned int get_sample_number (void); + unsigned int get_total_samples (void); + void set_end_sample (unsigned int sample); + unsigned int get_end_sample (void); + void reset_end_sample (void); + void set_tag (charMatrix tag); + charMatrix get_tag (void); + void set_userdata (octave_value userdata); + octave_value get_userdata (void); + PaStream *get_stream (void); + octave_function *octave_callback_function; + + octave_value getaudiodata (void); + audioplayer *getplayer (void); + bool isrecording (void); + audioplayer play (void); + void record (void); + void recordblocking (float seconds); + void pause (void); + void resume (void); + void stop (void); + void append (float sample_l, float sample_r); + +private: + Matrix y; + std::vector left; + std::vector right; + charMatrix tag; + octave_value userdata; + int channels; + int fs; + int nbits; + int id; + unsigned int sample_number; + unsigned int end_sample; + PaStream *stream; + PaStreamParameters input_parameters; + audio_type type; + DECLARE_OCTAVE_ALLOCATOR + DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA +}; + +DEFINE_OCTAVE_ALLOCATOR (audiorecorder); +DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (audiorecorder, "audiorecorder", "audiorecorder"); + +static int +octave_record_callback (const void *input, void *output, + unsigned long frames, + const PaStreamCallbackTimeInfo* time, + PaStreamCallbackFlags status, + void *data) +{ + audiorecorder *recorder = (audiorecorder *)data; + int channels = recorder->get_channels (); + float sample_l, sample_r; + Matrix sound; + sound.resize (frames, 2); + if (recorder->get_nbits () == 8) + { + int8_t *input8 = (int8_t *)input; + for (int i = 0; i < frames; i++) + { + sample_l = input8[i * channels] / (pow (2.0, 7) - 1.0); + sample_r = input8[i * channels + (channels - 1)] / (pow (2.0, 7) - 1.0); + sound(i, 0) = sample_l; + sound(i, 1) = sample_r; + } + } + else if (recorder->get_nbits () == 16) + { + int16_t *input16 = (int16_t *)input; + for (int i = 0; i < frames; i++) + { + sample_l = input16[i * channels] / (pow (2.0, 15) - 1.0); + sample_r = input16[i * channels + (channels - 1)] / (pow (2.0, 15) - 1.0); + sound(i, 0) = sample_l; + sound(i, 1) = sample_r; + } + } + else if (recorder->get_nbits () == 24) + { + uint8_t *input24 = (uint8_t *)input; + int32_t sample_l32, sample_r32; + uint8_t *_sample_l = (uint8_t *)&sample_l; + uint8_t *_sample_r = (uint8_t *)&sample_r; + for (int i = 0; i < frames; i++) + { + for (int j = 0; j < 3; j++) + { + _sample_l[j] = input24[i * channels * 3 + j]; + _sample_r[j] = input24[i * channels * 3 + (channels - 1) * 3 + j]; + } + if (sample_l32 & 0x00800000) + sample_l32 |= 0xff000000; + if (sample_r32 & 0x00800000) + sample_r32 |= 0xff000000; + sound(i, 0) = sample_l32 / pow (2.0, 23); + sound(i, 1) = sample_r32 / pow (2.0, 23); + } + } + + octave_value_list args, retval; + args(0) = sound; + retval = feval (recorder->octave_callback_function, args, 1); + return retval(0).int_value (); +} + +static int +portaudio_record_callback (const void *input, void *output, + unsigned long frames, + const PaStreamCallbackTimeInfo* time, + PaStreamCallbackFlags status, + void *data) +{ + audiorecorder *recorder = (audiorecorder *)data; + int channels = recorder->get_channels (); + float sample_l, sample_r; + if (recorder->get_nbits () == 8) + { + int8_t *input8 = (int8_t *)input; + for (int i = 0; i < frames; i++) + { + sample_l = input8[i * channels] / (pow (2.0, 7) - 1.0); + sample_r = input8[i * channels + (channels - 1)] / (pow (2.0, 7) - 1.0); + recorder->append (sample_l, sample_r); + } + } + else if (recorder->get_nbits () == 16) + { + int16_t *input16 = (int16_t *)input; + for (int i = 0; i < frames; i++) + { + sample_l = input16[i * channels] / (pow (2.0, 15) - 1.0); + sample_r = input16[i * channels + (channels - 1)] / (pow (2.0, 15) - 1.0); + recorder->append (sample_l, sample_r); + } + } + else if (recorder->get_nbits () == 24) + { + uint8_t *input24 = (uint8_t *)input; + int32_t sample_l32, sample_r32; + uint8_t *_sample_l = (uint8_t *)&sample_l; + uint8_t *_sample_r = (uint8_t *)&sample_r; + for (int i = 0; i < frames; i++) + { + for (int j = 0; j < 3; j++) + { + _sample_l[j] = input24[i * channels * 3 + j]; + _sample_r[j] = input24[i * channels * 3 + (channels - 1) * 3 + j]; + } + if (sample_l32 & 0x00800000) + sample_l32 |= 0xff000000; + if (sample_r32 & 0x00800000) + sample_r32 |= 0xff000000; + recorder->append (sample_l32 / pow (2.0, 23), sample_r32 / pow (2.0, 23)); + } + } + + if (recorder->get_sample_number () > recorder->get_end_sample ()) + return paComplete; + + return paContinue; +} + +audiorecorder::audiorecorder (void) +{ + this->id = -1; + this->sample_number = 0; + this->channels = 1; + this->tag = charMatrix (""); + Matrix userdata; + this->userdata = octave_value (userdata); + this->stream = 0; + this->end_sample = -1; + this->set_fs (44100); + this->set_nbits (16); + this->set_channels (2); + this->octave_callback_function = 0; +} + +void +audiorecorder::print (std::ostream& os, bool pr_as_read_syntax) const +{ + print_raw (os, pr_as_read_syntax); + newline (os); +} + +void +audiorecorder::print_raw (std::ostream& os, bool pr_as_read_syntax) const +{ + os << 0; +} + +void +audiorecorder::init (void) +{ + PaError err; + int device; + err = Pa_Initialize (); + if (err != paNoError) + { + error ("audiorecorder: Initialization error!"); + return; + } + + int numDevices = Pa_GetDeviceCount (); + if (numDevices < 0) + { + error ("audiorecorder: No audio devices found!"); + return; + } + + if (this->get_id () == -1) + device = Pa_GetDefaultInputDevice (); + else + device = this->get_id (); + + this->input_parameters.device = device; + this->input_parameters.channelCount = this->get_channels (); + this->input_parameters.sampleFormat = bits_to_format (this->get_nbits ()); + this->input_parameters.suggestedLatency = Pa_GetDeviceInfo (device)->defaultHighInputLatency; + this->input_parameters.hostApiSpecificStreamInfo = NULL; +} + +void +audiorecorder::set_fs (int fs) +{ + this->fs = fs; +} + +int +audiorecorder::get_fs (void) +{ + return this->fs; +} + +void +audiorecorder::set_nbits (int nbits) +{ + this->nbits = nbits; +} + +int +audiorecorder::get_nbits (void) +{ + return this->nbits; +} + +void +audiorecorder::set_id (int id) +{ + this->id = id; +} + +int +audiorecorder::get_id (void) +{ + return this->id; +} + +void +audiorecorder::set_channels (int channels) +{ + assert (channels == 1 or channels == 2); + this->channels = channels; +} + +int +audiorecorder::get_channels (void) +{ + return this->channels; +} + +audio_type +audiorecorder::get_type (void) +{ + return this->type; +} + +void +audiorecorder::set_sample_number (unsigned int sample_number) +{ + this->sample_number = sample_number; +} + +unsigned int +audiorecorder::get_sample_number (void) +{ + return this->sample_number; +} + +unsigned int +audiorecorder::get_total_samples (void) +{ + return this->left.size (); +} + +void +audiorecorder::set_end_sample (unsigned int end_sample) +{ + this->end_sample = end_sample; +} + +unsigned int +audiorecorder::get_end_sample (void) +{ + return this->end_sample; +} + +void +audiorecorder::reset_end_sample (void) +{ + this->set_end_sample (this->left.size ()); +} + +void +audiorecorder::set_tag (charMatrix tag) +{ + this->tag = tag; +} + +charMatrix +audiorecorder::get_tag (void) +{ + return this->tag; +} + +void +audiorecorder::set_userdata (octave_value userdata) +{ + this->userdata = userdata; +} + +octave_value +audiorecorder::get_userdata (void) +{ + return this->userdata; +} + +octave_value +audiorecorder::getaudiodata (void) +{ + Matrix audio (2, this->left.size ()); + for (int i = 0; i < this->left.size (); i++) + { + audio(0, i) = this->left[i]; + audio(1, i) = this->right[i]; + } + return octave_value (audio); +} + +audioplayer * +audiorecorder::getplayer (void) +{ + audioplayer *player = new audioplayer (); + player->set_y (this->getaudiodata ()); + player->set_fs (this->get_fs ()); + player->set_nbits (this->get_nbits ()); + player->init (); + return player; +} + +bool +audiorecorder::isrecording (void) +{ + if (this->get_stream () == 0) + return false; + + PaError err; + err = Pa_IsStreamActive (stream); + if (err != 0 and err != 1) + { + error ("audiorecorder: Error checking stream activity status"); + return false; + } + + return (err == 1); +} + +void +audiorecorder::record (void) +{ + if (this->get_stream ()) + this->stop (); + + this->left.clear (); + this->right.clear (); + PaError err; + if (this->octave_callback_function != 0) + { + err = Pa_OpenStream (&stream, &(this->input_parameters), NULL, this->get_fs (), BUFFER_SIZE, paClipOff, octave_record_callback, (void *)this); + } + else + { + err = Pa_OpenStream (&stream, &(this->input_parameters), NULL, this->get_fs (), BUFFER_SIZE, paClipOff, portaudio_record_callback, (void *)this); + } + if (err != paNoError) + { + error ("audiorecorder: Error opening audio recording stream"); + return; + } + err = Pa_StartStream (stream); + if (err != paNoError) + { + error ("audiorecorder: Error starting audio recording stream"); + return; + } +} + +void +audiorecorder::recordblocking (float seconds) +{ + if (this->get_stream ()) + this->stop (); + + this->left.clear (); + this->right.clear (); + + PaError err; + err = Pa_OpenStream (&stream, &(this->input_parameters), NULL, this->get_fs (), BUFFER_SIZE, paClipOff, NULL, (void *)this); + if (err != paNoError) + { + error ("audiorecorder: Error opening audio recording stream"); + return; + } + + err = Pa_StartStream (stream); + if (err != paNoError) + { + error ("audiorecorder: Error starting audio recording stream"); + return; + } + + unsigned int frames = seconds * this->get_fs (); + uint8_t buffer[BUFFER_SIZE * 2 * 3]; + for (int i = 0; i < frames / BUFFER_SIZE; i++) + { + Pa_ReadStream (this->get_stream (), (void *)buffer, BUFFER_SIZE); + if (this->octave_callback_function != 0) + octave_record_callback ((void *)buffer, NULL, BUFFER_SIZE, 0, 0, (void *)this); + else + portaudio_record_callback ((void *)buffer, NULL, BUFFER_SIZE, 0, 0, (void *)this); + } +} + +void +audiorecorder::pause (void) +{ + if (this->get_stream () == 0) + return; + + PaError err; + err = Pa_StopStream (stream); + if (err != paNoError) + { + error ("audiorecorder: Error stoping audio recording stream"); + return; + } +} + +void +audiorecorder::resume (void) +{ + if (this->get_stream () == 0) + return; + + PaError err; + err = Pa_StartStream (stream); + if (err != paNoError) + { + error ("audiorecorder: Error starting audio recording stream"); + return; + } +} + +void +audiorecorder::stop (void) +{ + if (this->get_stream () == 0) + return; + + PaError err; + if (not Pa_IsStreamStopped (this->get_stream ())) + { + err = Pa_AbortStream (this->get_stream ()); + if (err != paNoError) + { + error ("audioplayer: Error stopping audio playback stream"); + return; + } + } + + err = Pa_CloseStream (stream); + if (err != paNoError) + { + error ("audiorecorder: Error closing audio recording stream"); + return; + } + + this->set_sample_number (0); + this->reset_end_sample (); + stream = 0; +} + +void +audiorecorder::append (float sample_l, float sample_r) +{ + this->left.push_back (sample_l); + this->right.push_back (sample_r); + this->set_sample_number (this->get_sample_number () + 1); +} + +PaStream * +audiorecorder::get_stream (void) +{ + return this->stream; +} + +DEFUN_DLD (__recorder_audiorecorder__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{recorder} =} __recorder_audiorecorder__ (@var{fs}, @var{nbits}, @var{channels})\n\ +@deftypefnx {Loadable Function} {@var{recorder} =} __recorder_audiorecorder__ (@var{fs}, @var{nbits}, @var{channels}, @var{id})\n\ +@deftypefnx {Loadable Function} {@var{recorder} =} __recorder_audiorecorder__ (@var{fcn}, @dots{})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + audiorecorder* retval = new audiorecorder (); + int offset = 0; + if (nargin > 0) + { + bool is_function = args(0).is_string () || args(0).is_function_handle () || args(0).is_inline_function (); + if (is_function) + { + retval->octave_callback_function = args(0).function_value (); + offset = 1; + } + } + switch (nargin - offset) + { + case 3: + retval->set_fs (args(0 + offset).int_value ()); + retval->set_nbits (args(1 + offset).int_value ()); + retval->set_channels (args(2 + offset).int_value ()); + break; + case 4: + retval->set_fs (args(0 + offset).int_value ()); + retval->set_nbits (args(1 + offset).int_value ()); + retval->set_channels (args(2 + offset).int_value ()); + retval->set_id (args(3 + offset).int_value ()); + break; + } + retval->init (); + return octave_value (retval); +#else + octave_value retval; + error ("portaudio not found on your system and thus audio functionality is not present"); + return retval; +#endif +} + +DEFUN_DLD (__recorder_getaudiodata__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{data}} __recorder_getaudiodata__ (@var{recorder})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + retval = octave_value (recorder->getaudiodata ()); +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_get_channels__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{n} =} __recorder_get_channels__ (@var{recorder})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + retval = octave_value (recorder->get_channels ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_get_fs__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{fs} =} __recorder_get_fs__ (@var{recorder})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + retval = octave_value (recorder->get_fs ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_get_id__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{id} =} __recorder_get_id__ (@var{recorder})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + retval = octave_value (recorder->get_id ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_get_nbits__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{nbits} =} __recorder_get_nbits__ (@var{recorder})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + retval = octave_value (recorder->get_nbits ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_get_sample_number__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{n} =} __recorder_get_sample_number__ (@var{recorder})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + retval = octave_value (recorder->get_sample_number ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_get_tag__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{tag} =} __recorder_get_tag__ (@var{recorder})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + retval = octave_value (recorder->get_tag ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_get_total_samples__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{n} =} __recorder_get_total_samples__ (@var{recorder})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + retval = octave_value (recorder->get_total_samples ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_get_userdata__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{data} =} __recorder_get_userdata__ (@var{recorder})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + retval = recorder->get_userdata (); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_isrecording__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __recorder_isrecording__ (@var{recorder})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + if (recorder->isrecording ()) + return octave_value (1); + else + return octave_value (0); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_pause__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __recorder_pause__ (@var{recorder})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + recorder->pause (); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_recordblocking__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __recorder_recordblocking__ (@var{recorder}, @var{seconds})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + recorder->recordblocking (args(1).float_value ()); +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_record__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __recorder_record__ (@var{recorder})\n\ +@deftypefnx {Loadable Function} {} __recorder_record__ (@var{recorder}, @var{seconds})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + if (args.length () == 1) + { + recorder->record (); + } + else if (args.length () == 2) + { + recorder->set_end_sample (args(1).int_value () * recorder->get_fs ()); + recorder->record (); + } + else + { + error ("audiorecorder: wrong number of arguments passed to record"); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_resume__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __recorder_resume__ (@var{recorder})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + recorder->resume (); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_set_fs__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __recorder_set_fs__ (@var{recorder}, @var{fs})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 2) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + recorder->set_fs (args(1).int_value ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_set_tag__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __recorder_set_tag__ (@var{recorder}, @var{tag})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 2) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + recorder->set_tag (args(1).char_matrix_value ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_set_userdata__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __recorder_set_userdata__ (@var{recorder}, @var{data})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 2) + { + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + recorder->set_userdata (args(1)); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__recorder_stop__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __recorder_stop__ (@var{recorder})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + const octave_base_value& rep = args(0).get_rep (); + audiorecorder *recorder = &((audiorecorder &)rep); + recorder->stop (); +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_audioplayer__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{player} =} __player_audioplayer__ (@var{y}, @var{fs})\n\ +@deftypefnx {Loadable Function} {@var{player} =} __player_audioplayer__ (@var{y}, @var{fs}, @var{nbits})\n\ +@deftypefnx {Loadable Function} {@var{player} =} __player_audioplayer__ (@var{y}, @var{fs}, @var{nbits}, @var{id})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + audioplayer* retval = new audioplayer (); + bool is_function = args(0).is_string () || args(0).is_function_handle () || args(0).is_inline_function (); + if (is_function) + retval->set_y (args(0).function_value ()); + else + retval->set_y (args(0)); + retval->set_fs (args(1).int_value ()); + switch (nargin) + { + case 3: + retval->set_nbits (args(2).int_value ()); + break; + case 4: + retval->set_nbits (args(2).int_value ()); + retval->set_id (args(3).int_value ()); + break; + } + if (is_function) + retval->init_fn (); + else + retval->init (); + return octave_value (retval); +#else + octave_value retval; + error ("portaudio not found on your system and thus audio functionality is not present"); + return retval; +#endif +} + +DEFUN_DLD (__player_get_channels__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{n} =} __player_get_channels__ (@var{player})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + retval = octave_value (player->get_channels ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_get_fs__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{fs} =} __player_get_fs__ (@var{player})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + retval = octave_value (player->get_fs ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_get_id__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{id} =} __player_get_id__ (@var{player})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + retval = octave_value (player->get_id ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_get_nbits__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{nbits} =} __player_get_nbits__ (@var{player})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + retval = octave_value (player->get_nbits ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_get_sample_number__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{n} =} __player_get_sample_number__ (@var{player})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + retval = octave_value (player->get_sample_number ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_get_tag__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{tag} =} __player_get_tag__ (@var{player})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + retval = octave_value (player->get_tag ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_get_total_samples__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{n} =} __player_get_total_samples__ (@var{player})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + retval = octave_value (player->get_total_samples ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_get_userdata__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{data} =} __player_get_userdata__ (@var{player})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + retval = player->get_userdata (); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_isplaying__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __player_isplaying__ (@var{player})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + if (player->isplaying ()) + return octave_value (1); + else + return octave_value (0); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_pause__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __player_pause__ (@var{player})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + player->pause (); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_playblocking__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __player_playblocking__ (@var{player})\n\ +@deftypefnx {Loadable Function} {} __player_playblocking__ (@var{player}, @var{start})\n\ +@deftypefnx {Loadable Function} {} __player_playblocking__ (@var{player}, [@var{start}, @var{end}])\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + player->playblocking (); + } + else + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + if (args(1).is_matrix_type ()) + { + unsigned int start, end; + RowVector range = args(1).row_vector_value (); + start = range.elem (0) - 1; + end = range.elem (1) - 1; + if (start < 0 or start > player->get_total_samples () or + start > end or end < 0 or end > player->get_total_samples ()) + error ("audioplayer: invalid range specified for playback"); + player->set_sample_number (start); + player->set_end_sample (end); + } + else + { + unsigned int start; + start = args(1).int_value () - 1; + if (start < 0 or start > player->get_total_samples ()) + error ("audioplayer: invalid range specified for playback"); + player->set_sample_number (start); + } + player->playblocking (); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_play__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __player_play__ (@var{player})\n\ +@deftypefnx {Loadable Function} {} __player_play__ (@var{player}, @var{start})\n\ +@deftypefnx {Loadable Function} {} __player_play__ (@var{player}, [@var{start}, @var{end}])\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + player->play (); + } + else + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + if (args(1).is_matrix_type ()) + { + unsigned int start, end; + RowVector range = args(1).row_vector_value (); + start = range.elem (0) - 1; + end = range.elem (1) - 1; + if (start < 0 or start > player->get_total_samples () or + start > end or end < 0 or end > player->get_total_samples ()) + error ("audioplayer: invalid range specified for playback"); + player->set_sample_number (start); + player->set_end_sample (end); + } + else + { + unsigned int start; + start = args(1).int_value () - 1; + if (start < 0 or start > player->get_total_samples ()) + error ("audioplayer: invalid range specified for playback"); + player->set_sample_number (start); + } + player->play (); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_resume__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __player_resume__ (@var{player})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + player->resume (); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_set_fs__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __player_set_fs__ (@var{player}, @var{fs})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 2) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + player->set_fs (args(1).int_value ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_set_tag__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __player_set_tag__ (@var{player}, @var{tag})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 2) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + player->set_tag (args(1).char_matrix_value ()); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_set_userdata__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __player_set_userdata__ (@var{player}, @var{data})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 2) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + player->set_userdata (args(1)); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} + +DEFUN_DLD (__player_stop__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __player_stop__ (@var{player})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; +#ifdef HAVE_PORTAUDIO + int nargin = args.length (); + if (nargin == 1) + { + const octave_base_value& rep = args(0).get_rep (); + audioplayer *player = &((audioplayer &)rep); + player->stop (); + } +#else + error ("portaudio not found on your system and thus audio functionality is not present"); +#endif + return retval; +} diff -r 2a16dac2176f -r 99522db5b911 libinterp/dldfcn/audioinfo.cc --- a/libinterp/dldfcn/audioinfo.cc Wed Dec 31 15:38:13 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - -Copyright (C) 2013 Vytautas Jančauskas - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -. - -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "oct.h" -#include "ov-struct.h" -#ifdef HAVE_SNDFILE -#include -#endif - -DEFUN_DLD (audioinfo, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{info} =} audioinfo (@var{filename})\n\ -Return information about an audio file specified by @var{filename}.\n\ -@end deftypefn") -{ - octave_scalar_map retval; - if (args.length () != 1 || not args(0).is_string ()) - { - print_usage (); - return octave_value (retval); - } -#ifdef HAVE_SNDFILE - Matrix audio; - SNDFILE *file; - SF_INFO info; - info.format = 0; - int start, end; - file = sf_open (args(0).string_value ().c_str (), SFM_READ, &info); - retval.assign ("Filename", args(0).string_value ()); - retval.assign ("CompressionMethod", ""); - retval.assign ("NumChannels", info.channels); - retval.assign ("SampleRate", info.samplerate); - retval.assign ("TotalSamples", info.frames); - retval.assign ("Duration", (float)info.frames / (float)info.samplerate); - - int bits; - if (info.format & SF_FORMAT_PCM_S8) - bits = 8; - else if (info.format & SF_FORMAT_PCM_U8) - bits = 8; - else if (info.format & SF_FORMAT_PCM_16) - bits = 16; - else if (info.format & SF_FORMAT_PCM_24) - bits = 24; - else if (info.format & SF_FORMAT_PCM_32) - bits = 32; - else - bits = -1; - - retval.assign ("BitsPerSample", bits); - retval.assign ("BitRate", -1); - retval.assign ("Title", sf_get_string (file, SF_STR_TITLE)); - retval.assign ("Artist", sf_get_string (file, SF_STR_ARTIST)); - retval.assign ("Comment", sf_get_string (file, SF_STR_COMMENT)); -#else - error ("sndfile not found on your system and thus audioinfo is not functional"); -#endif - return octave_value (retval); -} diff -r 2a16dac2176f -r 99522db5b911 libinterp/dldfcn/audioread.cc --- a/libinterp/dldfcn/audioread.cc Wed Dec 31 15:38:13 2014 -0500 +++ b/libinterp/dldfcn/audioread.cc Fri Jan 02 00:40:35 2015 -0500 @@ -24,8 +24,12 @@ #include #endif +#include +#include + #include "oct.h" #include "ov-struct.h" + #ifdef HAVE_SNDFILE #include #endif @@ -126,3 +130,191 @@ #endif return octave_value (retval); } + +#ifdef HAVE_SNDFILE +static void +fill_extension_table (std::map &table) +{ + table["wav"] = SF_FORMAT_WAV; + table["aiff"] = SF_FORMAT_AIFF; + table["au"] = SF_FORMAT_AU; + table["raw"] = SF_FORMAT_RAW; + table["paf"] = SF_FORMAT_PAF; + table["svx"] = SF_FORMAT_SVX; + table["nist"] = SF_FORMAT_NIST; + table["voc"] = SF_FORMAT_VOC; + table["ircam"] = SF_FORMAT_IRCAM; + table["w64"] = SF_FORMAT_W64; + table["mat4"] = SF_FORMAT_MAT4; + table["mat5"] = SF_FORMAT_MAT5; + table["pvf"] = SF_FORMAT_PVF; + table["xi"] = SF_FORMAT_XI; + table["htk"] = SF_FORMAT_HTK; + table["sds"] = SF_FORMAT_SDS; + table["avr"] = SF_FORMAT_AVR; + table["wavex"] = SF_FORMAT_WAVEX; + table["sd2"] = SF_FORMAT_SD2; + table["flac"] = SF_FORMAT_FLAC; + table["caf"] = SF_FORMAT_CAF; + table["wve"] = SF_FORMAT_WVE; + table["ogg"] = SF_FORMAT_OGG; + table["mpc2k"] = SF_FORMAT_MPC2K; + table["rf64"] = SF_FORMAT_RF64; +} +#endif + +DEFUN_DLD (audiowrite, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} audiowrite (@var{filename}, @var{y}, @var{fs})\n\ +\n\ +Write audio data from the matrix @var{y} to a file specified by @var{filename},\n\ +file format will be determined by the file extension.\n\ +\n\ +@end deftypefn\n\ +@deftypefn {Loadable Function} {} audiowrite (@var{filename}, @var{y}, @var{fs}, @var{name}, @var{value})\n\ +\n\ +Lets you specify additional parameters when writing the file. Those parameters\n\ +are given in the table below:\n\ +\n\ +@table @samp\n\ +@item BitsPerSample\n\ +Number of bits per sample, valid values are 8, 16, 24 and 32. Default is 16.\n\ +@item BitRate\n\ +Valid argument name, but ignored. Left for compatibility with MATLAB.\n\ +@item Quality\n\ +Quality setting for the Ogg Vorbis compressor. Values can range between 0 and 100 with 100 being the highest quality setting. Default is 75.\n\ +@item Title\n\ +Title for the audio file.\n\ +@item Artist\n\ +Artist name.\n\ +@item Comment\n\ +Comment.\n\ +@end table\n\ +@end deftypefn") +{ + octave_scalar_map retval; +#ifdef HAVE_SNDFILE + std::map extension_to_format; + fill_extension_table (extension_to_format); + std::string filename = args(0).string_value (); + std::string extension = filename.substr (filename.find_last_of (".") + 1); + std::transform (extension.begin (), extension.end (), extension.begin (), ::tolower); + Matrix audio = args(1).matrix_value (); + SNDFILE *file; + SF_INFO info; + float *data = (float *)malloc (audio.rows () * audio.cols () * sizeof (float)); + for (int i = 0; i < audio.cols (); i++) + { + for (int j = 0; j < audio.rows (); j++) + { + data[j * audio.cols () + i] = audio(j, i); + } + } + + if (extension == "ogg") + info.format = SF_FORMAT_VORBIS; + else + info.format = SF_FORMAT_PCM_16; + + std::string title = ""; + std::string artist = ""; + std::string comment = ""; + float quality = 0.75; + for (int i = 3; i < args.length (); i += 2) + { + if (args(i).string_value () == "BitsPerSample") + { + int bits = args(i + 1).int_value (); + if (bits == 8) + info.format |= SF_FORMAT_PCM_S8; + else if (bits == 16) + info.format |= SF_FORMAT_PCM_16; + else if (bits == 24) + info.format |= SF_FORMAT_PCM_24; + else if (bits == 32) + info.format |= SF_FORMAT_PCM_32; + else + error ("audiowrite: wrong number of bits specified"); + } + else if (args(i).string_value () == "BitRate") + ; + else if (args(i).string_value () == "Quality") + quality = args(i + 1).int_value () * 0.01; + else if (args(i).string_value () == "Title") + title = args(i + 1).string_value (); + else if (args(i).string_value () == "Artist") + artist = args(i + 1).string_value (); + else if (args(i).string_value () == "Comment") + comment = args(i + 1).string_value (); + else + error ("audiowrite: wrong argument name"); + } + info.samplerate = args(2).int_value (); + info.channels = audio.cols (); + info.format |= extension_to_format[extension]; + file = sf_open (filename.c_str (), SFM_WRITE, &info); + if (title != "") + sf_set_string (file, SF_STR_TITLE, title.c_str ()); + if (artist != "") + sf_set_string (file, SF_STR_ARTIST, artist.c_str ()); + if (comment != "") + sf_set_string (file, SF_STR_COMMENT, comment.c_str ()); + sf_write_float (file, data, audio.rows () * audio.cols ()); + sf_close (file); + free (data); +#else + error ("sndfile not found on your system and thus audiowrite is not functional"); +#endif + return octave_value (retval); +} + +DEFUN_DLD (audioinfo, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{info} =} audioinfo (@var{filename})\n\ +Return information about an audio file specified by @var{filename}.\n\ +@end deftypefn") +{ + octave_scalar_map retval; + if (args.length () != 1 || not args(0).is_string ()) + { + print_usage (); + return octave_value (retval); + } +#ifdef HAVE_SNDFILE + Matrix audio; + SNDFILE *file; + SF_INFO info; + info.format = 0; + int start, end; + file = sf_open (args(0).string_value ().c_str (), SFM_READ, &info); + retval.assign ("Filename", args(0).string_value ()); + retval.assign ("CompressionMethod", ""); + retval.assign ("NumChannels", info.channels); + retval.assign ("SampleRate", info.samplerate); + retval.assign ("TotalSamples", info.frames); + retval.assign ("Duration", (float)info.frames / (float)info.samplerate); + + int bits; + if (info.format & SF_FORMAT_PCM_S8) + bits = 8; + else if (info.format & SF_FORMAT_PCM_U8) + bits = 8; + else if (info.format & SF_FORMAT_PCM_16) + bits = 16; + else if (info.format & SF_FORMAT_PCM_24) + bits = 24; + else if (info.format & SF_FORMAT_PCM_32) + bits = 32; + else + bits = -1; + + retval.assign ("BitsPerSample", bits); + retval.assign ("BitRate", -1); + retval.assign ("Title", sf_get_string (file, SF_STR_TITLE)); + retval.assign ("Artist", sf_get_string (file, SF_STR_ARTIST)); + retval.assign ("Comment", sf_get_string (file, SF_STR_COMMENT)); +#else + error ("sndfile not found on your system and thus audioinfo is not functional"); +#endif + return octave_value (retval); +} diff -r 2a16dac2176f -r 99522db5b911 libinterp/dldfcn/audiowrite.cc --- a/libinterp/dldfcn/audiowrite.cc Wed Dec 31 15:38:13 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -/* - -Copyright (C) 2013 Vytautas Jančauskas - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -. - -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "oct.h" -#include "ov-struct.h" -#ifdef HAVE_SNDFILE -#include -#endif -#include -#include - -#ifdef HAVE_SNDFILE -static void -fill_extension_table (std::map &table) -{ - table["wav"] = SF_FORMAT_WAV; - table["aiff"] = SF_FORMAT_AIFF; - table["au"] = SF_FORMAT_AU; - table["raw"] = SF_FORMAT_RAW; - table["paf"] = SF_FORMAT_PAF; - table["svx"] = SF_FORMAT_SVX; - table["nist"] = SF_FORMAT_NIST; - table["voc"] = SF_FORMAT_VOC; - table["ircam"] = SF_FORMAT_IRCAM; - table["w64"] = SF_FORMAT_W64; - table["mat4"] = SF_FORMAT_MAT4; - table["mat5"] = SF_FORMAT_MAT5; - table["pvf"] = SF_FORMAT_PVF; - table["xi"] = SF_FORMAT_XI; - table["htk"] = SF_FORMAT_HTK; - table["sds"] = SF_FORMAT_SDS; - table["avr"] = SF_FORMAT_AVR; - table["wavex"] = SF_FORMAT_WAVEX; - table["sd2"] = SF_FORMAT_SD2; - table["flac"] = SF_FORMAT_FLAC; - table["caf"] = SF_FORMAT_CAF; - table["wve"] = SF_FORMAT_WVE; - table["ogg"] = SF_FORMAT_OGG; - table["mpc2k"] = SF_FORMAT_MPC2K; - table["rf64"] = SF_FORMAT_RF64; -} -#endif - -DEFUN_DLD (audiowrite, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} audiowrite (@var{filename}, @var{y}, @var{fs})\n\ -\n\ -Write audio data from the matrix @var{y} to a file specified by @var{filename},\n\ -file format will be determined by the file extension.\n\ -\n\ -@end deftypefn\n\ -@deftypefn {Loadable Function} {} audiowrite (@var{filename}, @var{y}, @var{fs}, @var{name}, @var{value})\n\ -\n\ -Lets you specify additional parameters when writing the file. Those parameters\n\ -are given in the table below:\n\ -\n\ -@table @samp\n\ -@item BitsPerSample\n\ -Number of bits per sample, valid values are 8, 16, 24 and 32. Default is 16.\n\ -@item BitRate\n\ -Valid argument name, but ignored. Left for compatibility with MATLAB.\n\ -@item Quality\n\ -Quality setting for the Ogg Vorbis compressor. Values can range between 0 and 100 with 100 being the highest quality setting. Default is 75.\n\ -@item Title\n\ -Title for the audio file.\n\ -@item Artist\n\ -Artist name.\n\ -@item Comment\n\ -Comment.\n\ -@end table\n\ -@end deftypefn") -{ - octave_scalar_map retval; -#ifdef HAVE_SNDFILE - std::map extension_to_format; - fill_extension_table (extension_to_format); - std::string filename = args(0).string_value (); - std::string extension = filename.substr (filename.find_last_of (".") + 1); - std::transform (extension.begin (), extension.end (), extension.begin (), ::tolower); - Matrix audio = args(1).matrix_value (); - SNDFILE *file; - SF_INFO info; - float *data = (float *)malloc (audio.rows () * audio.cols () * sizeof (float)); - for (int i = 0; i < audio.cols (); i++) - { - for (int j = 0; j < audio.rows (); j++) - { - data[j * audio.cols () + i] = audio(j, i); - } - } - - if (extension == "ogg") - info.format = SF_FORMAT_VORBIS; - else - info.format = SF_FORMAT_PCM_16; - - std::string title = ""; - std::string artist = ""; - std::string comment = ""; - float quality = 0.75; - for (int i = 3; i < args.length (); i += 2) - { - if (args(i).string_value () == "BitsPerSample") - { - int bits = args(i + 1).int_value (); - if (bits == 8) - info.format |= SF_FORMAT_PCM_S8; - else if (bits == 16) - info.format |= SF_FORMAT_PCM_16; - else if (bits == 24) - info.format |= SF_FORMAT_PCM_24; - else if (bits == 32) - info.format |= SF_FORMAT_PCM_32; - else - error ("audiowrite: wrong number of bits specified"); - } - else if (args(i).string_value () == "BitRate") - ; - else if (args(i).string_value () == "Quality") - quality = args(i + 1).int_value () * 0.01; - else if (args(i).string_value () == "Title") - title = args(i + 1).string_value (); - else if (args(i).string_value () == "Artist") - artist = args(i + 1).string_value (); - else if (args(i).string_value () == "Comment") - comment = args(i + 1).string_value (); - else - error ("audiowrite: wrong argument name"); - } - info.samplerate = args(2).int_value (); - info.channels = audio.cols (); - info.format |= extension_to_format[extension]; - file = sf_open (filename.c_str (), SFM_WRITE, &info); - if (title != "") - sf_set_string (file, SF_STR_TITLE, title.c_str ()); - if (artist != "") - sf_set_string (file, SF_STR_ARTIST, artist.c_str ()); - if (comment != "") - sf_set_string (file, SF_STR_COMMENT, comment.c_str ()); - sf_write_float (file, data, audio.rows () * audio.cols ()); - sf_close (file); - free (data); -#else - error ("sndfile not found on your system and thus audiowrite is not functional"); -#endif - return octave_value (retval); -} diff -r 2a16dac2176f -r 99522db5b911 libinterp/dldfcn/module-files --- a/libinterp/dldfcn/module-files Wed Dec 31 15:38:13 2014 -0500 +++ b/libinterp/dldfcn/module-files Fri Jan 02 00:40:35 2015 -0500 @@ -22,8 +22,4 @@ symrcm.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS) tsearch.cc audioread.cc|$(SNDFILE_CPPFLAGS)|$(SNDFILE_LDFLAGS)|$(SNDFILE_LIBS) -audiowrite.cc|$(SNDFILE_CPPFLAGS)|$(SNDFILE_LDFLAGS)|$(SNDFILE_LIBS) -audioinfo.cc|$(SNDFILE_CPPFLAGS)|$(SNDFILE_LDFLAGS)|$(SNDFILE_LIBS) audiodevinfo.cc|$(PORTAUDIO_CPPFLAGS)|$(PORTAUDIO_LDFLAGS)|$(PORTAUDIO_LIBS) -__player_audioplayer__.cc|$(PORTAUDIO_CPPFLAGS)|$(PORTAUDIO_LDFLAGS)|$(PORTAUDIO_LIBS) -__recorder_audiorecorder__.cc|$(PORTAUDIO_CPPFLAGS)|$(PORTAUDIO_LDFLAGS)|$(PORTAUDIO_LIBS) diff -r 2a16dac2176f -r 99522db5b911 libinterp/dldfcn/player_class.cc --- a/libinterp/dldfcn/player_class.cc Wed Dec 31 15:38:13 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,633 +0,0 @@ -/* - -Copyright (C) 2013 Vytautas Jančauskas - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -. - -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "oct.h" -#include "ov.h" -#include "parse.h" -#include -#include - -#include "player_class.h" - -PaSampleFormat -bits_to_format (int bits) -{ - if (bits == 8) - return paInt8; - else if (bits == 16) - return paInt16; - else if (bits == 24) - return paInt24; - else if (bits == 32) - return paInt32; - else if (bits == -1) - return paFloat32; - else - return 0; -} - -#define BUFFER_SIZE 512 - -DEFINE_OCTAVE_ALLOCATOR (audioplayer); -DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (audioplayer, "audioplayer", "audioplayer"); - -int -is_big_endian (void) -{ - union - { - uint32_t i; - char c[4]; - } bint = { 0x01020304 }; - return bint.c[0] == 1; -} - -static int -octave_play_callback (const void *input, void *output, - unsigned long frames, - const PaStreamCallbackTimeInfo *time, - PaStreamCallbackFlags status, - void *data) -{ - audioplayer *player = (audioplayer *)data; - int big_endian = is_big_endian (); - octave_value_list args, retval; - args(0) = frames; - retval = feval (player->octave_callback_function, args, 1); - RowVector sound_l, sound_r; - Matrix sound = retval(0).matrix_value (); - int return_status = retval(1).int_value (); - sound_l.resize (frames); - sound_r.resize (frames); - if (sound.cols () == 1) - { - for (int i = 0; i < frames; i++) - { - sound_l(i) = sound(i, 0); - sound_r(i) = sound(i, 0); - } - } - else if (sound.cols () == 2) - { - for (int i = 0; i < frames; i++) - { - sound_l(i) = sound(i, 0); - sound_r(i) = sound(i, 1); - } - } - else - return paAbort; - - for (int i = 0; i < frames; i++) - { - if (player->get_nbits () == 8) - { - int8_t *buffer = (int8_t *)output; - buffer[2 * i] = sound_l.elem (i) * (pow (2.0, 7) - 1); - buffer[2 * i + 1] = sound_r.elem (i) * (pow (2.0, 7) - 1); - } - else if (player->get_nbits () == 16) - { - int16_t *buffer = (int16_t *)output; - buffer[2 * i] = sound_l.elem (i) * (pow (2.0, 15) - 1); - buffer[2 * i + 1] = sound_r.elem (i) * (pow (2.0, 15) - 1); - } - else if (player->get_nbits () == 24) - { - uint8_t *buffer = (uint8_t *)output; - int32_t sample_l = sound_l.elem (i) * (pow (2.0, 23) - 1); - int32_t sample_r = sound_r.elem (i) * (pow (2.0, 23) - 1); - sample_l &= 0x00ffffff; - sample_r &= 0x00ffffff; - uint8_t *_sample_l = (uint8_t *)&sample_l; - uint8_t *_sample_r = (uint8_t *)&sample_r; - buffer[i * 6 + 0] = _sample_l[0 + big_endian]; - buffer[i * 6 + 1] = _sample_l[1 + big_endian]; - buffer[i * 6 + 2] = _sample_l[2 + big_endian]; - buffer[i * 6 + 3] = _sample_r[0 + big_endian]; - buffer[i * 6 + 4] = _sample_r[1 + big_endian]; - buffer[i * 6 + 5] = _sample_r[2 + big_endian]; - } - } - return return_status; -} - -static int -portaudio_play_callback (const void *input, void *output, - unsigned long frames, - const PaStreamCallbackTimeInfo* time, - PaStreamCallbackFlags status, - void *data) -{ - audioplayer *player = (audioplayer *)data; - int big_endian = is_big_endian (); - int channels = player->get_channels (); - RowVector *sound_l = player->get_left (); - RowVector *sound_r; - - if (channels > 1) - sound_r = player->get_right (); - else - sound_r = sound_l; - - for (int j = 0, k = 0; j < frames; j++, k += 2) - { - unsigned int sample_number = player->get_sample_number (); - if (sample_number > player->get_end_sample ()) - return paAbort; - - if (player->get_type () == DOUBLE) - { - if (player->get_nbits () == 8) - { - int8_t *buffer = (int8_t *)output; - buffer[k] = sound_l->elem (sample_number) * (pow (2.0, 7) - 1); - buffer[k + 1] = sound_r->elem (sample_number) * (pow (2.0, 7) - 1); - } - else if (player->get_nbits () == 16) - { - int16_t *buffer = (int16_t *)output; - buffer[k] = sound_l->elem (sample_number) * (pow (2.0, 15) - 1); - buffer[k + 1] = sound_r->elem (sample_number) * (pow (2.0, 15) - 1); - } - else if (player->get_nbits () == 24) - { - uint8_t *buffer = (uint8_t *)output; - int32_t sample_l = sound_l->elem (sample_number) * (pow (2.0, 23) - 1); - int32_t sample_r = sound_r->elem (sample_number) * (pow (2.0, 23) - 1); - sample_l &= 0x00ffffff; - sample_r &= 0x00ffffff; - uint8_t *_sample_l = (uint8_t *)&sample_l; - uint8_t *_sample_r = (uint8_t *)&sample_r; - buffer[j * 6 + 0] = _sample_l[0 + big_endian]; - buffer[j * 6 + 1] = _sample_l[1 + big_endian]; - buffer[j * 6 + 2] = _sample_l[2 + big_endian]; - buffer[j * 6 + 3] = _sample_r[0 + big_endian]; - buffer[j * 6 + 4] = _sample_r[1 + big_endian]; - buffer[j * 6 + 5] = _sample_r[2 + big_endian]; - } - } - else if (player->get_type () == INT8) - { - int8_t *buffer = (int8_t *)output; - buffer[k] = sound_l->elem (sample_number); - buffer[k + 1] = sound_r->elem (sample_number); - } - else if (player->get_type () == UINT8) - { - uint8_t *buffer = (uint8_t *)output; - buffer[k] = sound_l->elem (sample_number); - buffer[k + 1] = sound_r->elem (sample_number); - } - else if (player->get_type () == INT16) - { - int16_t *buffer = (int16_t *)output; - buffer[k] = sound_l->elem (sample_number); - buffer[k + 1] = sound_r->elem (sample_number); - } - player->set_sample_number (sample_number + 1); - } - return paContinue; -} - -audioplayer::audioplayer (void) -{ - this->nbits = 16; - this->id = -1; - this->sample_number = 0; - this->tag = charMatrix (""); - Matrix userdata; - this->userdata = octave_value (userdata); - this->stream = 0; - this->octave_callback_function = 0; -} - -void -audioplayer::print (std::ostream& os, bool pr_as_read_syntax) const -{ - print_raw (os, pr_as_read_syntax); - newline (os); -} - -void -audioplayer::print_raw (std::ostream& os, bool pr_as_read_syntax) const -{ - os << 0; -} - -void -audioplayer::init_fn (void) -{ - PaError err; - int device; - - err = Pa_Initialize (); - if (err != paNoError) - { - error ("audioplayer: Initialization error!"); - return; - } - - int numDevices = Pa_GetDeviceCount (); - if (numDevices < 0) - { - error ("audioplayer: No audio devices found!"); - return; - } - - if (this->get_id () == -1) - device = Pa_GetDefaultOutputDevice (); - else - device = this->get_id (); - - output_parameters.device = device; - output_parameters.channelCount = 2; - output_parameters.sampleFormat = bits_to_format (this->get_nbits ()); - output_parameters.suggestedLatency = Pa_GetDeviceInfo (device)->defaultHighOutputLatency; - output_parameters.hostApiSpecificStreamInfo = NULL; -} - -void -audioplayer::init (void) -{ - PaError err; - int channels = this->y.rows (); - RowVector *sound_l = this->get_left (); - int device; - - err = Pa_Initialize (); - if (err != paNoError) - { - error ("audioplayer: Initialization error!"); - return; - } - - int numDevices = Pa_GetDeviceCount (); - if (numDevices < 0) - { - error ("audioplayer: No audio devices found!"); - return; - } - - if (this->get_id () == -1) - device = Pa_GetDefaultOutputDevice (); - else - device = this->get_id (); - - output_parameters.device = device; - output_parameters.channelCount = 2; - - if (this->type == DOUBLE) - output_parameters.sampleFormat = bits_to_format (this->get_nbits ()); - else if (this->type == INT8) - output_parameters.sampleFormat = paInt8; - else if (this->type == UINT8) - output_parameters.sampleFormat = paUInt8; - else if (this->type == INT16) - output_parameters.sampleFormat = paInt16; - - output_parameters.suggestedLatency = Pa_GetDeviceInfo (device)->defaultHighOutputLatency; - output_parameters.hostApiSpecificStreamInfo = NULL; -} - -void -audioplayer::set_y (octave_value y) -{ - if (y.is_int8_type ()) - this->type = INT8; - else if (y.is_uint8_type ()) - this->type = UINT8; - else if (y.is_int16_type ()) - this->type = INT16; - else - this->type = DOUBLE; - - this->y = y.matrix_value (); - if (this->y.rows () > 2) - this->y = this->y.transpose (); - - this->channels = this->y.rows (); - this->left = this->y.row (0); - if (this->channels == 2) - this->right = this->y.row (1); - - this->reset_end_sample (); -} - -void -audioplayer::set_y (octave_function *fn) -{ - this->octave_callback_function = fn; - this->channels = 2; - this->reset_end_sample (); -} - -Matrix& -audioplayer::get_y (void) -{ - return this->y; -} - -RowVector * -audioplayer::get_left (void) -{ - return &(this->left); -} - -RowVector * -audioplayer::get_right (void) -{ - return &(this->right); -} - -void -audioplayer::set_fs (int fs) -{ - this->fs = fs; -} - -int -audioplayer::get_fs (void) -{ - return this->fs; -} - -void -audioplayer::set_nbits (int nbits) -{ - this->nbits = nbits; -} - -int -audioplayer::get_nbits (void) -{ - return this->nbits; -} - -void -audioplayer::set_id (int id) -{ - this->id = id; -} - -int -audioplayer::get_id (void) -{ - return this->id; -} - -int -audioplayer::get_channels (void) -{ - return this->channels; -} - -audio_type -audioplayer::get_type (void) -{ - return this->type; -} - -void -audioplayer::set_sample_number (unsigned int sample_number) -{ - this->sample_number = sample_number; -} - -unsigned int -audioplayer::get_sample_number (void) -{ - return this->sample_number; -} - -unsigned int -audioplayer::get_total_samples (void) -{ - return this->left.length (); -} - -void -audioplayer::set_end_sample (unsigned int end_sample) -{ - this->end_sample = end_sample; -} - -unsigned int -audioplayer::get_end_sample (void) -{ - return this->end_sample; -} - -void -audioplayer::reset_end_sample (void) -{ - this->set_end_sample (this->left.length ()); -} - -void -audioplayer::set_tag (charMatrix tag) -{ - this->tag = tag; -} - -charMatrix -audioplayer::get_tag (void) -{ - return this->tag; -} - -void -audioplayer::set_userdata (octave_value userdata) -{ - this->userdata = userdata; -} - -octave_value -audioplayer::get_userdata (void) -{ - return this->userdata; -} - -void -audioplayer::playblocking (void) -{ - if (this->get_stream ()) - this->stop (); - - PaError err; - uint32_t buffer[BUFFER_SIZE * 2]; - err = Pa_OpenStream (&stream, NULL, &(this->output_parameters), this->get_fs (), BUFFER_SIZE, paClipOff, NULL, NULL); - if (err != paNoError) - { - error ("audioplayer: Error opening audio playback stream"); - return; - } - - err = Pa_StartStream (stream); - if (err != paNoError) - { - error ("audioplayer: Error starting audio playback stream"); - return; - } - - unsigned int start, end; - start = this->get_sample_number (); - end = this->get_end_sample (); - for (int i = start; i < end; i += BUFFER_SIZE) - { - if (this->octave_callback_function != 0) - octave_play_callback (0, (void *)buffer, BUFFER_SIZE, 0, 0, (void *)this); - else - portaudio_play_callback (0, (void *)buffer, BUFFER_SIZE, 0, 0, (void *)this); - err = Pa_WriteStream (stream, buffer, BUFFER_SIZE); - } - - err = Pa_StopStream (stream); - if (err != paNoError) - { - error ("audioplayer: Error stoping audio playback stream"); - return; - } - - err = Pa_CloseStream (stream); - if (err != paNoError) - { - error ("audioplayer: Error closing audio playback stream"); - return; - } - - stream = 0; - this->set_sample_number (0); - this->reset_end_sample (); -} - -void -audioplayer::play (void) -{ - if (this->get_stream ()) - this->stop (); - - PaError err; - if (this->octave_callback_function != 0) - err = Pa_OpenStream (&stream, NULL, &(this->output_parameters), this->get_fs (), BUFFER_SIZE, paClipOff, octave_play_callback, (void *)this); - else - err = Pa_OpenStream (&stream, NULL, &(this->output_parameters), this->get_fs (), BUFFER_SIZE, paClipOff, portaudio_play_callback, (void *)this); - - if (err != paNoError) - { - error ("audioplayer: Error opening audio playback stream"); - return; - } - - err = Pa_StartStream (stream); - if (err != paNoError) - { - error ("audioplayer: Error starting audio playback stream"); - return; - } -} - -void -audioplayer::pause (void) -{ - if (this->get_stream () == 0) - return; - - PaError err; - err = Pa_StopStream (stream); - if (err != paNoError) - { - error ("audiorecorder: Error stoping audio recording stream"); - return; - } -} - -void -audioplayer::resume (void) -{ - if (this->get_stream () == 0) - return; - - PaError err; - err = Pa_StartStream (stream); - if (err != paNoError) - { - error ("audiorecorder: Error starting audio recording stream"); - return; - } -} - -PaStream * -audioplayer::get_stream (void) -{ - return this->stream; -} - -void -audioplayer::stop (void) -{ - if (this->get_stream () == 0) - return; - - PaError err; - this->set_sample_number (0); - this->reset_end_sample (); - if (not Pa_IsStreamStopped (this->get_stream ())) - { - err = Pa_AbortStream (this->get_stream ()); - if (err != paNoError) - { - error ("audioplayer: Error stopping audio playback stream"); - return; - } - } - - err = Pa_CloseStream (this->get_stream ()); - if (err != paNoError) - { - error ("audioplayer: Error closing audio playback stream"); - return; - } - - stream = 0; -} - -bool -audioplayer::isplaying (void) -{ - if (this->get_stream () == 0) - return false; - - PaError err; - err = Pa_IsStreamActive (stream); - if (err != 0 and err != 1) - { - error ("audiorecorder: Error checking stream activity status"); - return false; - } - - return (err == 1); -} diff -r 2a16dac2176f -r 99522db5b911 libinterp/dldfcn/player_class.h --- a/libinterp/dldfcn/player_class.h Wed Dec 31 15:38:13 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - -Copyright (C) 2013 Vytautas Jančauskas - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -. - -*/ - -#ifndef PLAYER_CLASS_H -#define PLAYER_CLASS_H - -#include -#include "oct.h" -#include "ov-int32.h" -#include - -#include "player_class.h" - -enum audio_type { INT8, UINT8, INT16, DOUBLE }; - -class audioplayer : public octave_base_value -{ -public: - audioplayer (void); - ~audioplayer (void) {}; - - // Overloaded base functions - double player_value (void) const { return 0; } - virtual double scalar_value (bool frc_str_conv = false) const { return 0; } - void print (std::ostream& os, bool pr_as_read_syntax = false) const; - void print_raw (std::ostream& os, bool pr_as_read_syntax) const; - - // Properties - bool is_constant (void) const { return true; } - bool is_defined (void) const { return true; } - bool print_as_scalar (void) const { return true; } - - void init (void); - void init_fn (void); - void set_y (octave_value y); - void set_y (octave_function *fn); - void set_y (std::string fn); - Matrix& get_y (void); - RowVector *get_left (void); - RowVector *get_right (void); - void set_fs (int fs); - int get_fs (void); - void set_nbits (int nbits); - int get_nbits (void); - void set_id (int id); - int get_id (void); - int get_channels (void); - audio_type get_type (void); - - void set_sample_number (unsigned int sample); - unsigned int get_sample_number (void); - unsigned int get_total_samples (void); - void set_end_sample (unsigned int sample); - unsigned int get_end_sample (void); - void reset_end_sample (void); - void set_tag (charMatrix tag); - charMatrix get_tag (void); - void set_userdata (octave_value userdata); - octave_value get_userdata (void); - PaStream *get_stream (void); - octave_function *octave_callback_function; - - void playblocking (void); - void play (void); - void pause (void); - void resume (void); - void stop (void); - bool isplaying (void); - -private: - Matrix y; - RowVector left; - RowVector right; - charMatrix tag; - octave_value userdata; - int channels; - int fs; - int nbits; - int id; - unsigned int sample_number; - unsigned int end_sample; - PaStream *stream; - PaStreamParameters output_parameters; - audio_type type; - DECLARE_OCTAVE_ALLOCATOR - DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA -}; - -#endif // PLAYER_CLASS_H diff -r 2a16dac2176f -r 99522db5b911 libinterp/dldfcn/recorder_class.cc --- a/libinterp/dldfcn/recorder_class.cc Wed Dec 31 15:38:13 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,512 +0,0 @@ -/* - -Copyright (C) 2013 Vytautas Jančauskas - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -. - -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "oct.h" -#include "ov.h" -#include "parse.h" -#include -#include - -#include "player_class.h" -#include "recorder_class.h" - -#define BUFFER_SIZE 512 - -DEFINE_OCTAVE_ALLOCATOR (audiorecorder); -DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (audiorecorder, "audiorecorder", "audiorecorder"); - -static int -octave_record_callback (const void *input, void *output, - unsigned long frames, - const PaStreamCallbackTimeInfo* time, - PaStreamCallbackFlags status, - void *data) -{ - audiorecorder *recorder = (audiorecorder *)data; - int channels = recorder->get_channels (); - float sample_l, sample_r; - Matrix sound; - sound.resize (frames, 2); - if (recorder->get_nbits () == 8) - { - int8_t *input8 = (int8_t *)input; - for (int i = 0; i < frames; i++) - { - sample_l = input8[i * channels] / (pow (2.0, 7) - 1.0); - sample_r = input8[i * channels + (channels - 1)] / (pow (2.0, 7) - 1.0); - sound(i, 0) = sample_l; - sound(i, 1) = sample_r; - } - } - else if (recorder->get_nbits () == 16) - { - int16_t *input16 = (int16_t *)input; - for (int i = 0; i < frames; i++) - { - sample_l = input16[i * channels] / (pow (2.0, 15) - 1.0); - sample_r = input16[i * channels + (channels - 1)] / (pow (2.0, 15) - 1.0); - sound(i, 0) = sample_l; - sound(i, 1) = sample_r; - } - } - else if (recorder->get_nbits () == 24) - { - uint8_t *input24 = (uint8_t *)input; - int32_t sample_l32, sample_r32; - uint8_t *_sample_l = (uint8_t *)&sample_l; - uint8_t *_sample_r = (uint8_t *)&sample_r; - for (int i = 0; i < frames; i++) - { - for (int j = 0; j < 3; j++) - { - _sample_l[j] = input24[i * channels * 3 + j]; - _sample_r[j] = input24[i * channels * 3 + (channels - 1) * 3 + j]; - } - if (sample_l32 & 0x00800000) - sample_l32 |= 0xff000000; - if (sample_r32 & 0x00800000) - sample_r32 |= 0xff000000; - sound(i, 0) = sample_l32 / pow (2.0, 23); - sound(i, 1) = sample_r32 / pow (2.0, 23); - } - } - - octave_value_list args, retval; - args(0) = sound; - retval = feval (recorder->octave_callback_function, args, 1); - return retval(0).int_value (); -} - -static int -portaudio_record_callback (const void *input, void *output, - unsigned long frames, - const PaStreamCallbackTimeInfo* time, - PaStreamCallbackFlags status, - void *data) -{ - audiorecorder *recorder = (audiorecorder *)data; - int channels = recorder->get_channels (); - float sample_l, sample_r; - if (recorder->get_nbits () == 8) - { - int8_t *input8 = (int8_t *)input; - for (int i = 0; i < frames; i++) - { - sample_l = input8[i * channels] / (pow (2.0, 7) - 1.0); - sample_r = input8[i * channels + (channels - 1)] / (pow (2.0, 7) - 1.0); - recorder->append (sample_l, sample_r); - } - } - else if (recorder->get_nbits () == 16) - { - int16_t *input16 = (int16_t *)input; - for (int i = 0; i < frames; i++) - { - sample_l = input16[i * channels] / (pow (2.0, 15) - 1.0); - sample_r = input16[i * channels + (channels - 1)] / (pow (2.0, 15) - 1.0); - recorder->append (sample_l, sample_r); - } - } - else if (recorder->get_nbits () == 24) - { - uint8_t *input24 = (uint8_t *)input; - int32_t sample_l32, sample_r32; - uint8_t *_sample_l = (uint8_t *)&sample_l; - uint8_t *_sample_r = (uint8_t *)&sample_r; - for (int i = 0; i < frames; i++) - { - for (int j = 0; j < 3; j++) - { - _sample_l[j] = input24[i * channels * 3 + j]; - _sample_r[j] = input24[i * channels * 3 + (channels - 1) * 3 + j]; - } - if (sample_l32 & 0x00800000) - sample_l32 |= 0xff000000; - if (sample_r32 & 0x00800000) - sample_r32 |= 0xff000000; - recorder->append (sample_l32 / pow (2.0, 23), sample_r32 / pow (2.0, 23)); - } - } - - if (recorder->get_sample_number () > recorder->get_end_sample ()) - return paComplete; - - return paContinue; -} - -audiorecorder::audiorecorder (void) -{ - this->id = -1; - this->sample_number = 0; - this->channels = 1; - this->tag = charMatrix (""); - Matrix userdata; - this->userdata = octave_value (userdata); - this->stream = 0; - this->end_sample = -1; - this->set_fs (44100); - this->set_nbits (16); - this->set_channels (2); - this->octave_callback_function = 0; -} - -void -audiorecorder::print (std::ostream& os, bool pr_as_read_syntax) const -{ - print_raw (os, pr_as_read_syntax); - newline (os); -} - -void -audiorecorder::print_raw (std::ostream& os, bool pr_as_read_syntax) const -{ - os << 0; -} - -void -audiorecorder::init (void) -{ - PaError err; - int device; - err = Pa_Initialize (); - if (err != paNoError) - { - error ("audiorecorder: Initialization error!"); - return; - } - - int numDevices = Pa_GetDeviceCount (); - if (numDevices < 0) - { - error ("audiorecorder: No audio devices found!"); - return; - } - - if (this->get_id () == -1) - device = Pa_GetDefaultInputDevice (); - else - device = this->get_id (); - - this->input_parameters.device = device; - this->input_parameters.channelCount = this->get_channels (); - this->input_parameters.sampleFormat = bits_to_format (this->get_nbits ()); - this->input_parameters.suggestedLatency = Pa_GetDeviceInfo (device)->defaultHighInputLatency; - this->input_parameters.hostApiSpecificStreamInfo = NULL; -} - -void -audiorecorder::set_fs (int fs) -{ - this->fs = fs; -} - -int -audiorecorder::get_fs (void) -{ - return this->fs; -} - -void -audiorecorder::set_nbits (int nbits) -{ - this->nbits = nbits; -} - -int -audiorecorder::get_nbits (void) -{ - return this->nbits; -} - -void -audiorecorder::set_id (int id) -{ - this->id = id; -} - -int -audiorecorder::get_id (void) -{ - return this->id; -} - -void -audiorecorder::set_channels (int channels) -{ - assert (channels == 1 or channels == 2); - this->channels = channels; -} - -int -audiorecorder::get_channels (void) -{ - return this->channels; -} - -audio_type -audiorecorder::get_type (void) -{ - return this->type; -} - -void -audiorecorder::set_sample_number (unsigned int sample_number) -{ - this->sample_number = sample_number; -} - -unsigned int -audiorecorder::get_sample_number (void) -{ - return this->sample_number; -} - -unsigned int -audiorecorder::get_total_samples (void) -{ - return this->left.size (); -} - -void -audiorecorder::set_end_sample (unsigned int end_sample) -{ - this->end_sample = end_sample; -} - -unsigned int -audiorecorder::get_end_sample (void) -{ - return this->end_sample; -} - -void -audiorecorder::reset_end_sample (void) -{ - this->set_end_sample (this->left.size ()); -} - -void -audiorecorder::set_tag (charMatrix tag) -{ - this->tag = tag; -} - -charMatrix -audiorecorder::get_tag (void) -{ - return this->tag; -} - -void -audiorecorder::set_userdata (octave_value userdata) -{ - this->userdata = userdata; -} - -octave_value -audiorecorder::get_userdata (void) -{ - return this->userdata; -} - -octave_value -audiorecorder::getaudiodata (void) -{ - Matrix audio (2, this->left.size ()); - for (int i = 0; i < this->left.size (); i++) - { - audio(0, i) = this->left[i]; - audio(1, i) = this->right[i]; - } - return octave_value (audio); -} - -audioplayer * -audiorecorder::getplayer (void) -{ - audioplayer *player = new audioplayer (); - player->set_y (this->getaudiodata ()); - player->set_fs (this->get_fs ()); - player->set_nbits (this->get_nbits ()); - player->init (); - return player; -} - -bool -audiorecorder::isrecording (void) -{ - if (this->get_stream () == 0) - return false; - - PaError err; - err = Pa_IsStreamActive (stream); - if (err != 0 and err != 1) - { - error ("audiorecorder: Error checking stream activity status"); - return false; - } - - return (err == 1); -} - -void -audiorecorder::record (void) -{ - if (this->get_stream ()) - this->stop (); - - this->left.clear (); - this->right.clear (); - PaError err; - if (this->octave_callback_function != 0) - { - err = Pa_OpenStream (&stream, &(this->input_parameters), NULL, this->get_fs (), BUFFER_SIZE, paClipOff, octave_record_callback, (void *)this); - } - else - { - err = Pa_OpenStream (&stream, &(this->input_parameters), NULL, this->get_fs (), BUFFER_SIZE, paClipOff, portaudio_record_callback, (void *)this); - } - if (err != paNoError) - { - error ("audiorecorder: Error opening audio recording stream"); - return; - } - err = Pa_StartStream (stream); - if (err != paNoError) - { - error ("audiorecorder: Error starting audio recording stream"); - return; - } -} - -void -audiorecorder::recordblocking (float seconds) -{ - if (this->get_stream ()) - this->stop (); - - this->left.clear (); - this->right.clear (); - - PaError err; - err = Pa_OpenStream (&stream, &(this->input_parameters), NULL, this->get_fs (), BUFFER_SIZE, paClipOff, NULL, (void *)this); - if (err != paNoError) - { - error ("audiorecorder: Error opening audio recording stream"); - return; - } - - err = Pa_StartStream (stream); - if (err != paNoError) - { - error ("audiorecorder: Error starting audio recording stream"); - return; - } - - unsigned int frames = seconds * this->get_fs (); - uint8_t buffer[BUFFER_SIZE * 2 * 3]; - for (int i = 0; i < frames / BUFFER_SIZE; i++) - { - Pa_ReadStream (this->get_stream (), (void *)buffer, BUFFER_SIZE); - if (this->octave_callback_function != 0) - octave_record_callback ((void *)buffer, NULL, BUFFER_SIZE, 0, 0, (void *)this); - else - portaudio_record_callback ((void *)buffer, NULL, BUFFER_SIZE, 0, 0, (void *)this); - } -} - -void -audiorecorder::pause (void) -{ - if (this->get_stream () == 0) - return; - - PaError err; - err = Pa_StopStream (stream); - if (err != paNoError) - { - error ("audiorecorder: Error stoping audio recording stream"); - return; - } -} - -void -audiorecorder::resume (void) -{ - if (this->get_stream () == 0) - return; - - PaError err; - err = Pa_StartStream (stream); - if (err != paNoError) - { - error ("audiorecorder: Error starting audio recording stream"); - return; - } -} - -void -audiorecorder::stop (void) -{ - if (this->get_stream () == 0) - return; - - PaError err; - if (not Pa_IsStreamStopped (this->get_stream ())) - { - err = Pa_AbortStream (this->get_stream ()); - if (err != paNoError) - { - error ("audioplayer: Error stopping audio playback stream"); - return; - } - } - - err = Pa_CloseStream (stream); - if (err != paNoError) - { - error ("audiorecorder: Error closing audio recording stream"); - return; - } - - this->set_sample_number (0); - this->reset_end_sample (); - stream = 0; -} - -void -audiorecorder::append (float sample_l, float sample_r) -{ - this->left.push_back (sample_l); - this->right.push_back (sample_r); - this->set_sample_number (this->get_sample_number () + 1); -} - -PaStream * -audiorecorder::get_stream (void) -{ - return this->stream; -} diff -r 2a16dac2176f -r 99522db5b911 libinterp/dldfcn/recorder_class.h --- a/libinterp/dldfcn/recorder_class.h Wed Dec 31 15:38:13 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ -/* - -Copyright (C) 2013 Vytautas Jančauskas - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -. - -*/ - -#ifndef RECORDER_CLASS_H -#define RECORDER_CLASS_H - -#include - -#include "oct.h" -#include "ov-int32.h" -#include - -#include "player_class.h" - -class audiorecorder : public octave_base_value -{ -public: - audiorecorder (void); - ~audiorecorder (void) {}; - - // Overloaded base functions - double player_value (void) const { return 0; } - virtual double scalar_value (bool frc_str_conv = false) const { return 0; } - void print (std::ostream& os, bool pr_as_read_syntax = false) const; - void print_raw (std::ostream& os, bool pr_as_read_syntax) const; - - // Properties - bool is_constant (void) const { return true; } - bool is_defined (void) const { return true; } - bool print_as_scalar (void) const { return true; } - - void init (void); - void set_fs (int fs); - int get_fs (void); - void set_nbits (int nbits); - int get_nbits (void); - void set_id (int id); - int get_id (void); - void set_channels (int channels); - int get_channels (void); - audio_type get_type (void); - - void set_sample_number (unsigned int sample); - unsigned int get_sample_number (void); - unsigned int get_total_samples (void); - void set_end_sample (unsigned int sample); - unsigned int get_end_sample (void); - void reset_end_sample (void); - void set_tag (charMatrix tag); - charMatrix get_tag (void); - void set_userdata (octave_value userdata); - octave_value get_userdata (void); - PaStream *get_stream (void); - octave_function *octave_callback_function; - - octave_value getaudiodata (void); - audioplayer *getplayer (void); - bool isrecording (void); - audioplayer play (void); - void record (void); - void recordblocking (float seconds); - void pause (void); - void resume (void); - void stop (void); - void append (float sample_l, float sample_r); - -private: - Matrix y; - std::vector left; - std::vector right; - charMatrix tag; - octave_value userdata; - int channels; - int fs; - int nbits; - int id; - unsigned int sample_number; - unsigned int end_sample; - PaStream *stream; - PaStreamParameters input_parameters; - audio_type type; - DECLARE_OCTAVE_ALLOCATOR - DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA -}; - -#endif // RECORDER_CLASS_H