26#if defined (HAVE_CONFIG_H)
53#if defined (HAVE_PORTAUDIO)
54# include <portaudio.h>
59#if defined (HAVE_PORTAUDIO)
62bits_to_format (
int bits)
120#if defined (HAVE_PORTAUDIO)
122 int nargin = args.length ();
131 PaError err = Pa_Initialize ();
133 if (err != paNoError)
134 error (
"audiodevinfo: PortAudio initialization failed");
136 int num_devices = Pa_GetDeviceCount ();
142 numinput = numoutput = 0;
143 for (
int i = 0; i < num_devices; i++)
145 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (i);
150 "invalid audio device ID = %d", i);
154 if (device_info->maxInputChannels != 0)
157 if (device_info->maxOutputChannels != 0)
170 for (
int i = 0; i < num_devices; i++)
172 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (i);
177 "invalid audio device ID = %d", i);
181 const PaHostApiInfo *api_info = Pa_GetHostApiInfo (device_info->hostApi);
183 const char *driver = (api_info ? api_info->name :
"");
186 sprintf (
name,
"%s (%s)", device_info->name, driver);
188 if (device_info->maxInputChannels != 0)
190 input_name(idx_i) =
name;
191 input_driver_version(idx_i) = driver;
196 if (device_info->maxOutputChannels != 0)
198 output_name(idx_o) =
name;
199 output_driver_version(idx_o) = driver;
200 output_id(idx_o) = i;
206 inputdev.
setfield (
"Name", input_name);
207 inputdev.
setfield (
"DriverVersion", input_driver_version);
209 outputdev.
setfield (
"Name", output_name);
210 outputdev.
setfield (
"DriverVersion", output_driver_version);
211 outputdev.
setfield (
"ID", output_id);
212 devinfo.
setfield (
"input", inputdev);
213 devinfo.
setfield (
"output", outputdev);
223 else if (nargin == 1)
225 if (args(0).int_value () == 0)
227 else if (args(0).int_value () == 1)
230 error (
"audiodevinfo: specify 0 for output and 1 for input devices");
233 else if (nargin == 2)
236 int outin = args(0).int_value ();
237 if (args(1).is_string ())
239 std::string
name = args(1).string_value ();
242 for (
int i = 0; i < numoutput; i++)
244 if (output_name(i).string_value () ==
name)
246 retval = output_id(i);
254 for (
int i = 0; i < numinput; i++)
256 if (input_name(i).string_value () ==
name)
258 retval = input_id(i);
265 error (
"audiodevinfo: specify 0 for output and 1 for input devices");
271 for (
int i = 0; i < numoutput; i++)
273 if (output_id(i).int_value () == args(1).int_value ())
275 retval = output_name(i);
283 for (
int i = 0; i < numinput; i++)
285 if (input_id(i).int_value () == args(1).int_value ())
287 retval = input_name(i);
294 error (
"audiodevinfo: specify 0 for output and 1 for input devices");
298 error (
"audiodevinfo: no device found for the specified criteria");
301 else if (nargin == 3)
304 int outin = args(0).int_value ();
305 int id = args(1).int_value ();
307 std::string arg3 = args(2).string_value ();
308 std::transform (arg3.begin (), arg3.end (), arg3.begin (), tolower);
309 if (arg3 !=
"driverversion")
310 error (R
"(audiodevinfo: third argument must be "DriverVersion")");
314 for (
int i = 0; i < numoutput; i++)
316 if (output_id(i).int_value () ==
id)
319 retval = output_driver_version(i);
326 for (
int i = 0; i < numinput; i++)
328 if (input_id(i).int_value () ==
id)
331 retval = input_driver_version(i);
337 error (
"audiodevinfo: specify 0 for output and 1 for input devices");
340 error (
"audiodevinfo: no device found for the specified criteria");
343 else if (nargin == 4)
345 int io = args(0).int_value ();
346 int rate = args(1).int_value ();
347 int bits = args(2).int_value ();
348 int chans = args(3).int_value ();
350 for (
int i = 0; i < num_devices; i++)
352 PaStreamParameters stream_parameters;
353 stream_parameters.device = i;
354 stream_parameters.channelCount = chans;
355 PaSampleFormat
format = bits_to_format (bits);
358 stream_parameters.sampleFormat =
format;
360 error (
"audiodevinfo: invalid bits per sample format");
362 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (i);
367 "invalid audio device ID = %d", i);
371 stream_parameters.suggestedLatency
372 = device_info->defaultLowInputLatency;
374 stream_parameters.hostApiSpecificStreamInfo =
nullptr;
378 if (device_info->maxOutputChannels < chans)
381 err = Pa_IsFormatSupported (
nullptr, &stream_parameters, rate);
383 if (err == paFormatIsSupported)
391 if (device_info->maxInputChannels < chans)
394 err = Pa_IsFormatSupported (&stream_parameters,
nullptr, rate);
395 if (err == paFormatIsSupported)
405 else if (nargin == 5)
408 int id = args(1).int_value ();
409 int rate = args(2).int_value ();
410 int bits = args(3).int_value ();
411 int chans = args(4).int_value ();
412 PaStreamParameters stream_parameters;
413 stream_parameters.device = id;
414 stream_parameters.channelCount = chans;
415 PaSampleFormat
format = bits_to_format (bits);
417 stream_parameters.sampleFormat =
format;
419 error (
"audiodevinfo: invalid bits per sample format");
421 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (
id);
424 error (
"audiodevinfo: invalid audio device ID = %d",
id);
426 stream_parameters.suggestedLatency
427 = device_info->defaultLowInputLatency;
429 stream_parameters.hostApiSpecificStreamInfo =
nullptr;
432 if (device_info->maxOutputChannels < chans)
437 err = Pa_IsFormatSupported (
nullptr, &stream_parameters, rate);
438 if (err == paFormatIsSupported)
446 if (device_info->maxInputChannels < chans)
451 err = Pa_IsFormatSupported (&stream_parameters,
nullptr, rate);
452 if (err == paFormatIsSupported)
459 error (
"audiodevinfo: specify 0 for output and 1 for input devices");
467 octave_unused_parameter (args);
470 "audio playback and recording through PortAudio");
516#if defined (HAVE_PORTAUDIO)
518enum audio_type { TYPE_INT8, TYPE_UINT8, TYPE_UINT16, TYPE_DOUBLE };
527 double player_value (
void)
const {
return 0; }
528 virtual double scalar_value (
bool =
false)
const {
return 0; }
529 void print (std::ostream& os,
bool pr_as_read_syntax =
false);
530 void print_raw (std::ostream& os,
bool pr_as_read_syntax)
const;
541 void set_y (std::string fn);
545 void set_fs (
int fs);
547 void set_nbits (
int nbits);
548 int get_nbits (
void);
549 void set_id (
int id);
551 int get_channels (
void);
552 audio_type get_type (
void);
554 void set_sample_number (
unsigned int sample);
555 unsigned int get_sample_number (
void);
556 unsigned int get_total_samples (
void);
557 void set_end_sample (
unsigned int sample);
558 unsigned int get_end_sample (
void);
559 void reset_end_sample (
void);
564 PaStream * get_stream (
void);
566 void playblocking (
void);
571 bool isplaying (
void);
580 unsigned int sample_number;
581 unsigned int end_sample;
588 PaStreamParameters output_parameters;
597octave_play_callback (
const void *,
void *output,
unsigned long frames,
598 const PaStreamCallbackTimeInfo *,
599 PaStreamCallbackFlags,
void *data)
601 audioplayer *player =
static_cast<audioplayer *
> (data);
604 error (
"audioplayer callback function called without player");
607 =
feval (player->octave_callback_function,
608 ovl (
static_cast<double> (frames)), 1);
611 error (
"audioplayer callback function failed");
613 const Matrix sound = retval(0).matrix_value ();
614 int return_status = retval(1).int_value ();
616 if (frames - sound.
rows () != 0 || sound.
columns () < 1
618 error (
"audioplayer callback function failed");
626 ? sound_l : sound.
column (1));
628 const double *p_l = sound_l.
data ();
629 const double *p_r = sound_r.
data ();
631 switch (player->get_nbits ())
635 static double scale_factor =
std::pow (2.0, 7) - 1.0;
637 int8_t *buffer =
static_cast<int8_t *
> (output);
639 for (
unsigned long i = 0; i < frames; i++)
641 buffer[2*i] = p_l[i] * scale_factor;
642 buffer[2*i+1] = p_r[i] * scale_factor;
649 static double scale_factor =
std::pow (2.0, 15) - 1.0;
651 int16_t *buffer =
static_cast<int16_t *
> (output);
653 for (
unsigned long i = 0; i < frames; i++)
655 buffer[2*i] = p_l[i] * scale_factor;
656 buffer[2*i+1] = p_r[i] * scale_factor;
663 static double scale_factor =
std::pow (2.0, 23) - 1.0;
667 uint8_t *buffer =
static_cast<uint8_t *
> (output);
669 for (
unsigned long i = 0; i < frames; i++)
671 int32_t sample_l = p_l[i];
672 int32_t sample_r = p_r[i];
674 sample_l &= 0x00ffffff;
675 sample_r &= 0x00ffffff;
677 uint8_t *_sample_l =
reinterpret_cast<uint8_t *
> (&sample_l);
678 uint8_t *_sample_r =
reinterpret_cast<uint8_t *
> (&sample_r);
680 unsigned long offset = i * 6;
682 buffer[offset+0] = _sample_l[0+big_endian] * scale_factor;
683 buffer[offset+1] = _sample_l[1+big_endian] * scale_factor;
684 buffer[offset+2] = _sample_l[2+big_endian] * scale_factor;
686 buffer[offset+3] = _sample_r[0+big_endian] * scale_factor;
687 buffer[offset+4] = _sample_r[1+big_endian] * scale_factor;
688 buffer[offset+5] = _sample_r[2+big_endian] * scale_factor;
694 error (
"invalid bit depth in audioplayer callback function");
697 return return_status;
701portaudio_play_callback (
const void *,
void *output,
unsigned long frames,
702 const PaStreamCallbackTimeInfo *,
703 PaStreamCallbackFlags,
void *data)
705 audioplayer *player =
static_cast<audioplayer *
> (data);
708 error (
"audioplayer callback function called without player");
715 const RowVector sound_l = player->get_left ();
716 const RowVector sound_r = player->get_right ();
718 const double *pl = sound_l.
data ();
719 const double *pr = sound_r.
data ();
721 if (player->get_type () == TYPE_DOUBLE)
723 switch (player->get_nbits ())
727 static double scale_factor =
std::pow (2.0, 7) - 1.0;
729 int8_t *buffer =
static_cast<int8_t *
> (output);
731 for (
unsigned long j = 0; j < frames; j++)
733 unsigned int sample_number = player->get_sample_number ();
735 if (sample_number >= player->get_end_sample ())
738 unsigned long offset = j * 2;
740 buffer[offset+0] = pl[sample_number] * scale_factor;
741 buffer[offset+1] = pr[sample_number] * scale_factor;
743 player->set_sample_number (sample_number + 1);
750 static double scale_factor =
std::pow (2.0, 15) - 1.0;
752 int16_t *buffer =
static_cast<int16_t *
> (output);
754 for (
unsigned long j = 0; j < frames; j++)
756 unsigned int sample_number = player->get_sample_number ();
758 if (sample_number >= player->get_end_sample ())
761 unsigned long offset = j * 2;
763 buffer[offset+0] = pl[sample_number] * scale_factor;
764 buffer[offset+1] = pr[sample_number] * scale_factor;
766 player->set_sample_number (sample_number + 1);
773 static double scale_factor =
std::pow (2.0, 23) - 1.0;
777 uint8_t *buffer =
static_cast<uint8_t *
> (output);
779 for (
unsigned long j = 0; j < frames; j++)
781 unsigned int sample_number = player->get_sample_number ();
783 if (sample_number >= player->get_end_sample ())
786 int32_t sample_l = pl[sample_number] * scale_factor;
787 int32_t sample_r = pr[sample_number] * scale_factor;
789 sample_l &= 0x00ffffff;
790 sample_r &= 0x00ffffff;
792 uint8_t *_sample_l =
reinterpret_cast<uint8_t *
> (&sample_l);
793 uint8_t *_sample_r =
reinterpret_cast<uint8_t *
> (&sample_r);
795 unsigned long offset = j * 6;
797 buffer[offset+0] = _sample_l[0+big_endian];
798 buffer[offset+1] = _sample_l[1+big_endian];
799 buffer[offset+2] = _sample_l[2+big_endian];
801 buffer[offset+3] = _sample_r[0+big_endian];
802 buffer[offset+4] = _sample_r[1+big_endian];
803 buffer[offset+5] = _sample_r[2+big_endian];
805 player->set_sample_number (sample_number + 1);
811 error (
"invalid bit depth in audioplayer callback function");
814 else if (player->get_type () == TYPE_INT8)
816 int8_t *buffer =
static_cast<int8_t *
> (output);
818 for (
unsigned long j = 0; j < frames; j++)
820 unsigned int sample_number = player->get_sample_number ();
822 if (sample_number >= player->get_end_sample ())
825 unsigned long offset = j * 2;
827 buffer[offset+0] = pl[sample_number];
828 buffer[offset+1] = pr[sample_number];
830 player->set_sample_number (sample_number + 1);
833 else if (player->get_type () == TYPE_UINT8)
835 uint8_t *buffer =
static_cast<uint8_t *
> (output);
837 for (
unsigned long j = 0; j < frames; j++)
839 unsigned int sample_number = player->get_sample_number ();
841 if (sample_number >= player->get_end_sample ())
844 unsigned long offset = j * 2;
846 buffer[offset+0] = pl[sample_number];
847 buffer[offset+1] = pr[sample_number];
849 player->set_sample_number (sample_number + 1);
852 else if (player->get_type () == TYPE_UINT16)
854 int16_t *buffer =
static_cast<int16_t *
> (output);
856 for (
unsigned long j = 0; j < frames; j++)
858 unsigned int sample_number = player->get_sample_number ();
860 if (sample_number >= player->get_end_sample ())
863 unsigned long offset = j * 2;
865 buffer[offset+0] = pl[sample_number];
866 buffer[offset+1] = pr[sample_number];
868 player->set_sample_number (sample_number + 1);
875audioplayer::audioplayer (
void)
876 : octave_callback_function (nullptr),
877 id (-1), fs (0), nbits (16), channels (0), sample_number (0),
878 end_sample (-1), tag (
""), y (), userdata (
Matrix ()),
879 left (), right (), stream (nullptr), output_parameters (), type ()
882audioplayer::~audioplayer (
void)
887 "interrupting playing audioplayer");
893audioplayer::print (std::ostream& os,
bool pr_as_read_syntax)
895 print_raw (os, pr_as_read_syntax);
900audioplayer::print_raw (std::ostream& os,
bool)
const
906audioplayer::init_fn (
void)
908 if (Pa_Initialize () != paNoError)
909 error (
"audioplayer: initialization error");
911 if (Pa_GetDeviceCount () < 1)
912 error (
"audioplayer: no audio devices found or available");
914 int device = get_id ();
917 device = Pa_GetDefaultOutputDevice ();
919 output_parameters.device = device;
920 output_parameters.channelCount = 2;
921 output_parameters.sampleFormat = bits_to_format (get_nbits ());
923 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
927 "invalid default audio device ID = %d", device);
929 output_parameters.suggestedLatency
930 = (device_info ? device_info->defaultHighOutputLatency : -1);
932 output_parameters.hostApiSpecificStreamInfo =
nullptr;
936audioplayer::init (
void)
944 if (Pa_Initialize () != paNoError)
945 error (
"audioplayer: initialization error");
947 if (Pa_GetDeviceCount () < 1)
948 error (
"audioplayer: no audio devices found or available");
950 int device = get_id ();
953 device = Pa_GetDefaultOutputDevice ();
955 output_parameters.device = device;
956 output_parameters.channelCount = 2;
958 if (type == TYPE_DOUBLE)
959 output_parameters.sampleFormat = bits_to_format (get_nbits ());
960 else if (type == TYPE_INT8)
961 output_parameters.sampleFormat = paInt8;
962 else if (type == TYPE_UINT8)
963 output_parameters.sampleFormat = paUInt8;
964 else if (type == TYPE_UINT16)
965 output_parameters.sampleFormat = paInt16;
967 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
971 "invalid default audio device ID = %d", device);
973 output_parameters.suggestedLatency
974 = (device_info ? device_info->defaultHighOutputLatency : -1);
976 output_parameters.hostApiSpecificStreamInfo =
nullptr;
996 channels = y.
rows ();
1002 reset_end_sample ();
1008 octave_callback_function = fn;
1010 reset_end_sample ();
1014audioplayer::get_y (
void)
1020audioplayer::get_left (
void)
const
1026audioplayer::get_right (
void)
const
1028 return channels == 1 ?
left : right;
1032audioplayer::set_fs (
int fs_arg)
1038audioplayer::get_fs (
void)
1044audioplayer::set_nbits (
int nbits_arg)
1050audioplayer::get_nbits (
void)
1056audioplayer::set_id (
int id_arg)
1062audioplayer::get_id (
void)
1068audioplayer::get_channels (
void)
1074audioplayer::get_type (
void)
1080audioplayer::set_sample_number (
unsigned int sample_number_arg)
1082 sample_number = sample_number_arg;
1086audioplayer::get_sample_number (
void)
1088 return sample_number;
1092audioplayer::get_total_samples (
void)
1094 return left.numel ();
1098audioplayer::set_end_sample (
unsigned int end_sample_arg)
1100 end_sample = end_sample_arg;
1104audioplayer::get_end_sample (
void)
1110audioplayer::reset_end_sample (
void)
1112 set_end_sample (
left.numel ());
1116audioplayer::set_tag (
const charMatrix& tag_arg)
1122audioplayer::get_tag (
void)
1128audioplayer::set_userdata (
const octave_value& userdata_arg)
1130 userdata = userdata_arg;
1134audioplayer::get_userdata (
void)
1140audioplayer::playblocking (
void)
1145 const unsigned int buffer_size = get_fs () / 20;
1149 err = Pa_OpenStream (&stream,
nullptr, &(output_parameters), get_fs (),
1150 buffer_size, paClipOff,
nullptr,
nullptr);
1151 if (err != paNoError)
1152 error (
"audioplayer: unable to open audio playback stream");
1154 err = Pa_StartStream (stream);
1155 if (err != paNoError)
1156 error (
"audioplayer: unable to start audio playback stream");
1158 unsigned int start, end;
1159 start = get_sample_number ();
1160 end = get_end_sample ();
1162 unwind_action stop_audioplayer ([=] () { stop (); });
1164 for (
unsigned int i = start; i < end; i += buffer_size)
1168 if (octave_callback_function !=
nullptr)
1169 octave_play_callback (
nullptr, buffer, buffer_size,
nullptr, 0,
this);
1171 portaudio_play_callback (
nullptr, buffer, buffer_size,
nullptr, 0,
this);
1173 err = Pa_WriteStream (stream, buffer, buffer_size);
1178audioplayer::play (
void)
1183 const unsigned int buffer_size = get_fs () / 20;
1186 if (octave_callback_function !=
nullptr)
1187 err = Pa_OpenStream (&stream,
nullptr, &(output_parameters),
1188 get_fs (), buffer_size, paClipOff,
1189 octave_play_callback,
this);
1191 err = Pa_OpenStream (&stream,
nullptr, &(output_parameters),
1192 get_fs (), buffer_size, paClipOff,
1193 portaudio_play_callback,
this);
1195 if (err != paNoError)
1196 error (
"audioplayer: failed to open audio playback stream");
1198 err = Pa_StartStream (stream);
1199 if (err != paNoError)
1200 error (
"audioplayer: failed to start audio playback stream");
1204audioplayer::pause (
void)
1206 if (get_stream () ==
nullptr)
1210 err = Pa_StopStream (stream);
1211 if (err != paNoError)
1212 error (
"audioplayer: failed to stop audio playback stream");
1216audioplayer::resume (
void)
1218 if (get_stream () ==
nullptr)
1222 err = Pa_StartStream (stream);
1223 if (err != paNoError)
1224 error (
"audioplayer: failed to start audio playback stream");
1228audioplayer::get_stream (
void)
1234audioplayer::stop (
void)
1236 if (get_stream () ==
nullptr)
1240 set_sample_number (0);
1241 reset_end_sample ();
1242 if (! Pa_IsStreamStopped (get_stream ()))
1244 err = Pa_AbortStream (get_stream ());
1245 if (err != paNoError)
1246 error (
"audioplayer: failed to stop audio playback stream");
1249 err = Pa_CloseStream (get_stream ());
1250 if (err != paNoError)
1251 error (
"audioplayer: failed to close audio playback stream");
1257audioplayer::isplaying (
void)
1259 if (get_stream () ==
nullptr)
1263 err = Pa_IsStreamActive (stream);
1264 if (err != 0 && err != 1)
1265 error (
"audioplayer: checking stream activity status failed");
1273 audiorecorder (
void);
1274 ~audiorecorder (
void);
1277 double player_value (
void)
const {
return 0; }
1278 virtual double scalar_value (
bool =
false)
const {
return 0; }
1279 void print (std::ostream& os,
bool pr_as_read_syntax =
false);
1280 void print_raw (std::ostream& os,
bool pr_as_read_syntax)
const;
1284 bool is_defined (
void)
const {
return true; }
1288 void set_fs (
int fs);
1290 void set_nbits (
int nbits);
1291 int get_nbits (
void);
1292 PaSampleFormat get_sampleFormat (
void);
1293 void set_id (
int id);
1295 void set_channels (
int channels);
1296 int get_channels (
void);
1297 audio_type get_type (
void);
1299 void set_sample_number (
unsigned int sample);
1300 unsigned int get_sample_number (
void);
1301 unsigned int get_total_samples (
void);
1302 void set_end_sample (
unsigned int sample);
1303 unsigned int get_end_sample (
void);
1304 void reset_end_sample (
void);
1309 PaStream * get_stream (
void);
1312 audioplayer * getplayer (
void);
1313 bool isrecording (
void);
1314 audioplayer play (
void);
1316 void recordblocking (
float seconds);
1320 void append (
float sample_l,
float sample_r);
1329 unsigned int sample_number;
1330 unsigned int end_sample;
1334 std::vector<float>
left;
1335 std::vector<float> right;
1337 PaStreamParameters input_parameters;
1346octave_record_callback (
const void *
input,
void *,
unsigned long frames,
1347 const PaStreamCallbackTimeInfo *,
1348 PaStreamCallbackFlags,
void *data)
1350 audiorecorder *recorder =
static_cast<audiorecorder *
> (data);
1353 error (
"audiorecorder callback function called without recorder");
1355 int channels = recorder->get_channels ();
1357 Matrix sound (frames, 2);
1358 sound.
resize (frames, 2);
1360 if (recorder->get_sampleFormat () == bits_to_format (8))
1362 static double scale_factor =
std::pow (2.0, 7) - 1.0;
1364 const int8_t *input8 =
static_cast<const int8_t *
> (
input);
1366 for (
unsigned long i = 0; i < frames; i++)
1368 float sample_l = input8[i*channels] / scale_factor;
1369 float sample_r = input8[i*channels + (channels - 1)] / scale_factor;
1371 sound(i, 0) = sample_l;
1372 sound(i, 1) = sample_r;
1378 else if (recorder->get_sampleFormat () == bits_to_format (16)
1379 && recorder->get_nbits () == 8)
1381 static double scale_factor =
std::pow (2.0, 7) - 1.0;
1383 const int16_t *input16 =
static_cast<const int16_t *
> (
input);
1385 for (
unsigned long i = 0; i < frames; i++)
1387 float sample_l = (input16[i*channels] >> 8) / scale_factor;
1388 float sample_r = (input16[i*channels + (channels - 1)] >> 8)
1391 sound(i, 0) = sample_l;
1392 sound(i, 1) = sample_r;
1395 else if (recorder->get_sampleFormat () == bits_to_format (16))
1397 static double scale_factor =
std::pow (2.0, 15) - 1.0;
1399 const int16_t *input16 =
static_cast<const int16_t *
> (
input);
1401 for (
unsigned long i = 0; i < frames; i++)
1403 float sample_l = input16[i*channels] / scale_factor;
1404 float sample_r = input16[i*channels + (channels - 1)] / scale_factor;
1406 sound(i, 0) = sample_l;
1407 sound(i, 1) = sample_r;
1410 else if (recorder->get_sampleFormat () == bits_to_format (24))
1412 static double scale_factor =
std::pow (2.0, 23);
1416 const uint8_t *input24 =
static_cast<const uint8_t *
> (
input);
1418 int32_t sample_l32, sample_r32;
1420 uint8_t *sample_l =
reinterpret_cast<uint8_t *
> (&sample_l32);
1421 uint8_t *sample_r =
reinterpret_cast<uint8_t *
> (&sample_r32);
1423 for (
unsigned long i = 0; i < frames; i++)
1425 sample_l32 = sample_r32 = 0;
1426 for (
int j = 0; j < 3; j++)
1428 sample_l[j] = input24[i*channels*3 + j];
1429 sample_r[j] = input24[i*channels*3 + (channels - 1)*3 + j];
1432 if (sample_l32 & 0x00800000)
1433 sample_l32 |= 0xff000000;
1435 if (sample_r32 & 0x00800000)
1436 sample_r32 |= 0xff000000;
1438 sound(i, 0) = sample_l32 / scale_factor;
1439 sound(i, 1) = sample_r32 / scale_factor;
1444 =
feval (recorder->octave_callback_function,
ovl (sound), 1);
1446 return retval(0).int_value ();
1450portaudio_record_callback (
const void *
input,
void *,
unsigned long frames,
1451 const PaStreamCallbackTimeInfo *,
1452 PaStreamCallbackFlags,
void *data)
1454 audiorecorder *recorder =
static_cast<audiorecorder *
> (data);
1457 error (
"audiorecorder callback function called without recorder");
1459 int channels = recorder->get_channels ();
1461 if (recorder->get_sampleFormat () == bits_to_format (8))
1463 static float scale_factor =
std::pow (2.0f, 7) - 1.0f;
1465 const int8_t *input8 =
static_cast<const int8_t *
> (
input);
1467 for (
unsigned long i = 0; i < frames; i++)
1469 float sample_l = input8[i*channels] / scale_factor;
1470 float sample_r = input8[i*channels + (channels - 1)] / scale_factor;
1472 recorder->append (sample_l, sample_r);
1478 else if (recorder->get_sampleFormat () == bits_to_format (16)
1479 && recorder->get_nbits () == 8)
1481 static double scale_factor =
std::pow (2.0, 7) - 1.0;
1483 const int16_t *input16 =
static_cast<const int16_t *
> (
input);
1485 for (
unsigned long i = 0; i < frames; i++)
1487 float sample_l = (input16[i*channels] >> 8) / scale_factor;
1488 float sample_r = (input16[i*channels + (channels - 1)] >> 8)
1491 recorder->append (sample_l, sample_r);
1494 else if (recorder->get_sampleFormat () == bits_to_format (16))
1496 static float scale_factor =
std::pow (2.0f, 15) - 1.0f;
1498 const int16_t *input16 =
static_cast<const int16_t *
> (
input);
1500 for (
unsigned long i = 0; i < frames; i++)
1502 float sample_l = input16[i*channels] / scale_factor;
1503 float sample_r = input16[i*channels + (channels - 1)] / scale_factor;
1505 recorder->append (sample_l, sample_r);
1508 else if (recorder->get_sampleFormat () == bits_to_format (24))
1510 static float scale_factor =
std::pow (2.0f, 23);
1514 const uint8_t *input24 =
static_cast<const uint8_t *
> (
input);
1516 int32_t sample_l32, sample_r32;
1518 uint8_t *sample_l =
reinterpret_cast<uint8_t *
> (&sample_l32);
1519 uint8_t *sample_r =
reinterpret_cast<uint8_t *
> (&sample_r32);
1521 for (
unsigned long i = 0; i < frames; i++)
1523 sample_l32 = sample_r32 = 0;
1524 for (
int j = 0; j < 3; j++)
1526 sample_l[j] = input24[i*channels*3 + j];
1527 sample_r[j] = input24[i*channels*3 + (channels - 1)*3 + j];
1530 if (sample_l32 & 0x00800000)
1531 sample_l32 |= 0xff000000;
1533 if (sample_r32 & 0x00800000)
1534 sample_r32 |= 0xff000000;
1536 recorder->append (sample_l32 / scale_factor,
1537 sample_r32 / scale_factor);
1541 if (recorder->get_sample_number () >= recorder->get_end_sample ())
1547audiorecorder::audiorecorder (
void)
1548 : octave_callback_function (nullptr),
1549 id (-1), fs (8000), nbits (8), channels (1), sample_number (0),
1550 end_sample (-1), tag (
""), y (), userdata (
Matrix ()),
1551 left (), right (), stream (nullptr), input_parameters (), type ()
1554audiorecorder::~audiorecorder (
void)
1559 "interrupting recording audiorecorder");
1565audiorecorder::print (std::ostream& os,
bool pr_as_read_syntax)
1567 print_raw (os, pr_as_read_syntax);
1572audiorecorder::print_raw (std::ostream& os,
bool)
const
1578audiorecorder::init (
void)
1580 if (Pa_Initialize () != paNoError)
1581 error (
"audiorecorder: initialization error");
1583 if (Pa_GetDeviceCount () < 1)
1584 error (
"audiorecorder: no audio devices found or available");
1586 int device = get_id ();
1589 device = Pa_GetDefaultInputDevice ();
1591 input_parameters.device = device;
1592 input_parameters.channelCount = get_channels ();
1593 input_parameters.sampleFormat = bits_to_format (get_nbits ());
1598 if (get_nbits () == 8)
1599 input_parameters.sampleFormat = bits_to_format (16);
1601 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
1605 "invalid default audio device ID = %d", device);
1607 input_parameters.suggestedLatency
1608 = (device_info ? device_info->defaultHighInputLatency : -1);
1610 input_parameters.hostApiSpecificStreamInfo =
nullptr;
1614audiorecorder::set_fs (
int fs_arg)
1620audiorecorder::get_fs (
void)
1626audiorecorder::set_nbits (
int nbits_arg)
1632audiorecorder::get_nbits (
void)
1638audiorecorder::get_sampleFormat (
void)
1640 return input_parameters.sampleFormat;
1644audiorecorder::set_id (
int id_arg)
1650audiorecorder::get_id (
void)
1656audiorecorder::set_channels (
int channels_arg)
1658 assert (channels_arg == 1 || channels_arg == 2);
1659 channels = channels_arg;
1663audiorecorder::get_channels (
void)
1669audiorecorder::get_type (
void)
1675audiorecorder::set_sample_number (
unsigned int sample_number_arg)
1677 sample_number = sample_number_arg;
1681audiorecorder::get_sample_number (
void)
1683 return sample_number;
1687audiorecorder::get_total_samples (
void)
1689 return left.size ();
1693audiorecorder::set_end_sample (
unsigned int end_sample_arg)
1695 end_sample = end_sample_arg;
1699audiorecorder::get_end_sample (
void)
1705audiorecorder::reset_end_sample (
void)
1707 set_end_sample (
left.size ());
1711audiorecorder::set_tag (
const charMatrix& tag_arg)
1717audiorecorder::get_tag (
void)
1723audiorecorder::set_userdata (
const octave_value& userdata_arg)
1725 userdata = userdata_arg;
1729audiorecorder::get_userdata (
void)
1735audiorecorder::getaudiodata (
void)
1739 unsigned int ls =
left.size ();
1742 for (
unsigned int i = 0; i < ls; i++)
1744 audio(0, i) =
left[i];
1745 audio(1, i) = right[i];
1752audiorecorder::getplayer (
void)
1754 audioplayer *player =
new audioplayer ();
1756 player->set_y (getaudiodata ());
1757 player->set_fs (get_fs ());
1758 player->set_nbits (get_nbits ());
1765audiorecorder::isrecording (
void)
1767 if (get_stream () ==
nullptr)
1771 err = Pa_IsStreamActive (stream);
1772 if (err != 0 && err != 1)
1773 error (
"audiorecorder: checking stream activity status failed");
1779audiorecorder::record (
void)
1787 const unsigned int buffer_size = get_fs () / 20;
1790 if (octave_callback_function !=
nullptr)
1792 err = Pa_OpenStream (&stream, &(input_parameters),
nullptr,
1793 get_fs (), buffer_size, paClipOff,
1794 octave_record_callback,
this);
1798 err = Pa_OpenStream (&stream, &(input_parameters),
nullptr,
1799 get_fs (), buffer_size, paClipOff,
1800 portaudio_record_callback,
this);
1802 if (err != paNoError)
1803 error (
"audiorecorder: unable to open audio recording stream");
1805 err = Pa_StartStream (stream);
1806 if (err != paNoError)
1807 error (
"audiorecorder: unable to start audio recording stream");
1811audiorecorder::recordblocking (
float seconds)
1819 const unsigned int buffer_size = get_fs () / 20;
1823 err = Pa_OpenStream (&stream, &(input_parameters),
nullptr,
1824 get_fs (), buffer_size, paClipOff,
nullptr,
this);
1825 if (err != paNoError)
1826 error (
"audiorecorder: unable to open audio recording stream");
1828 err = Pa_StartStream (stream);
1829 if (err != paNoError)
1830 error (
"audiorecorder: unable to start audio recording stream");
1832 unsigned int frames = seconds * get_fs ();
1834 unwind_action stop_audiorecorder ([=] () { stop (); });
1836 for (
unsigned int i = 0; i < frames; i += buffer_size)
1840 Pa_ReadStream (get_stream (), buffer, buffer_size);
1842 if (octave_callback_function !=
nullptr)
1843 octave_record_callback (buffer,
nullptr, buffer_size,
nullptr, 0,
this);
1845 portaudio_record_callback (buffer,
nullptr, buffer_size,
nullptr, 0,
this);
1850audiorecorder::pause (
void)
1852 if (get_stream () ==
nullptr)
1856 err = Pa_StopStream (stream);
1857 if (err != paNoError)
1858 error (
"audiorecorder: unable to stop audio recording stream");
1862audiorecorder::resume (
void)
1864 if (get_stream () ==
nullptr)
1868 err = Pa_StartStream (stream);
1869 if (err != paNoError)
1870 error (
"audiorecorder: unable to start audio recording stream");
1874audiorecorder::stop (
void)
1876 if (get_stream () ==
nullptr)
1880 if (! Pa_IsStreamStopped (get_stream ()))
1882 err = Pa_AbortStream (get_stream ());
1883 if (err != paNoError)
1884 error (
"audioplayer: unable to stop audio playback stream");
1887 err = Pa_CloseStream (stream);
1888 if (err != paNoError)
1889 error (
"audiorecorder: unable to close audio recording stream");
1891 set_sample_number (0);
1892 reset_end_sample ();
1897audiorecorder::append (
float sample_l,
float sample_r)
1899 left.push_back (sample_l);
1900 right.push_back (sample_r);
1901 set_sample_number (get_sample_number () + 1);
1905audiorecorder::get_stream (
void)
1912DEFUN_DLD (__recorder_audiorecorder__, args, ,
1922#if defined (HAVE_PORTAUDIO)
1924 int nargin = args.
length ();
1926 audiorecorder *recorder =
new audiorecorder ();
1930 bool is_function = (args(0).is_string () || args(0).is_function_handle ()
1931 || args(0).is_inline_function ());
1934 error (
"audiorecorder: callbacks not yet implemented");
1939 recorder->set_fs (args(0).int_value ());
1940 recorder->set_nbits (args(1).int_value ());
1941 recorder->set_channels (args(2).int_value ());
1946 recorder->set_id (args(3).int_value ());
1953 octave_unused_parameter (args);
1956 "audio playback and recording through PortAudio");
1962#if defined (HAVE_PORTAUDIO)
1964static audiorecorder *
1971 audiorecorder *rec =
dynamic_cast<audiorecorder *
> (ncrep);
1973 error (
"audiodevinfo.cc (get_recorder): dynamic_cast to audiorecorder failed");
1980DEFUN_DLD (__recorder_getaudiodata__, args, ,
1988#if defined (HAVE_PORTAUDIO)
1989 retval = get_recorder (args(0))->getaudiodata ();
1991 octave_unused_parameter (args);
1994 "audio playback and recording through PortAudio");
2000DEFUN_DLD (__recorder_get_channels__, args, ,
2008#if defined (HAVE_PORTAUDIO)
2009 retval = get_recorder (args(0))->get_channels ();
2011 octave_unused_parameter (args);
2014 "audio playback and recording through PortAudio");
2028#if defined (HAVE_PORTAUDIO)
2029 retval = get_recorder (args(0))->get_fs ();
2031 octave_unused_parameter (args);
2034 "audio playback and recording through PortAudio");
2048#if defined (HAVE_PORTAUDIO)
2049 retval = get_recorder (args(0))->get_id ();
2051 octave_unused_parameter (args);
2054 "audio playback and recording through PortAudio");
2060DEFUN_DLD (__recorder_get_nbits__, args, ,
2068#if defined (HAVE_PORTAUDIO)
2069 retval = get_recorder (args(0))->get_nbits ();
2071 octave_unused_parameter (args);
2074 "audio playback and recording through PortAudio");
2080DEFUN_DLD (__recorder_get_sample_number__, args, ,
2088#if defined (HAVE_PORTAUDIO)
2089 retval = get_recorder (args(0))->get_sample_number ();
2091 octave_unused_parameter (args);
2094 "audio playback and recording through PortAudio");
2108#if defined (HAVE_PORTAUDIO)
2109 retval = get_recorder (args(0))->get_tag ();
2111 octave_unused_parameter (args);
2114 "audio playback and recording through PortAudio");
2120DEFUN_DLD (__recorder_get_total_samples__, args, ,
2128#if defined (HAVE_PORTAUDIO)
2129 retval = get_recorder (args(0))->get_total_samples ();
2131 octave_unused_parameter (args);
2134 "audio playback and recording through PortAudio");
2140DEFUN_DLD (__recorder_get_userdata__, args, ,
2148#if defined (HAVE_PORTAUDIO)
2149 retval = get_recorder (args(0))->get_userdata ();
2151 octave_unused_parameter (args);
2154 "audio playback and recording through PortAudio");
2160DEFUN_DLD (__recorder_isrecording__, args, ,
2168#if defined (HAVE_PORTAUDIO)
2169 retval = get_recorder (args(0))->isrecording ();
2171 octave_unused_parameter (args);
2174 "audio playback and recording through PortAudio");
2186#if defined (HAVE_PORTAUDIO)
2187 get_recorder (args(0))->pause ();
2190 octave_unused_parameter (args);
2193 "audio playback and recording through PortAudio");
2197DEFUN_DLD (__recorder_recordblocking__, args, ,
2203#if defined (HAVE_PORTAUDIO)
2204 float seconds = args(1).float_value ();
2205 get_recorder (args(0))->recordblocking (seconds);
2208 octave_unused_parameter (args);
2211 "audio playback and recording through PortAudio");
2222#if defined (HAVE_PORTAUDIO)
2223 audiorecorder *recorder = get_recorder (args(0));
2225 if (args.length () == 2)
2226 recorder->set_end_sample (args(1).int_value () * recorder->get_fs ());
2228 recorder->record ();
2231 octave_unused_parameter (args);
2234 "audio playback and recording through PortAudio");
2244#if defined (HAVE_PORTAUDIO)
2245 if (args.length () == 1)
2246 get_recorder (args(0))->resume ();
2249 octave_unused_parameter (args);
2252 "audio playback and recording through PortAudio");
2262#if defined (HAVE_PORTAUDIO)
2263 if (args.length () == 2)
2264 get_recorder (args(0))->set_fs (args(1).int_value ());
2267 octave_unused_parameter (args);
2270 "audio playback and recording through PortAudio");
2280#if defined (HAVE_PORTAUDIO)
2281 if (args.length () == 2)
2282 get_recorder (args(0))->set_tag (args(1).char_matrix_value ());
2285 octave_unused_parameter (args);
2288 "audio playback and recording through PortAudio");
2292DEFUN_DLD (__recorder_set_userdata__, args, ,
2298#if defined (HAVE_PORTAUDIO)
2299 if (args.length () == 2)
2300 get_recorder (args(0))->set_userdata (args(1));
2303 octave_unused_parameter (args);
2306 "audio playback and recording through PortAudio");
2316#if defined (HAVE_PORTAUDIO)
2317 if (args.length () == 1)
2318 get_recorder (args(0))->stop ();
2321 octave_unused_parameter (args);
2324 "audio playback and recording through PortAudio");
2328DEFUN_DLD (__player_audioplayer__, args, ,
2338#if defined (HAVE_PORTAUDIO)
2340 audioplayer *recorder =
new audioplayer ();
2342 bool is_function = (args(0).is_string () || args(0).is_function_handle ()
2343 || args(0).is_inline_function ());
2346 error (
"audioplayer: callbacks not yet implemented");
2348 recorder->set_y (args(0));
2349 recorder->set_fs (args(1).int_value ());
2351 if (args.length () > 2)
2354 int nbits = args(2).int_value ();
2355 if (nbits != 8 && nbits != 16 && nbits != 24)
2356 error (
"audioplayer: NBITS must be 8, 16, or 24");
2358 switch (args.length ())
2361 recorder->set_nbits (nbits);
2365 recorder->set_nbits (nbits);
2366 recorder->set_id (args(3).int_value ());
2372 recorder->init_fn ();
2378 octave_unused_parameter (args);
2381 "audio playback and recording through PortAudio");
2387#if defined (HAVE_PORTAUDIO)
2396 audioplayer *pl =
dynamic_cast<audioplayer *
> (ncrep);
2398 error (
"audiodevinfo.cc (get_player): dynamic_cast to audioplayer failed");
2405DEFUN_DLD (__player_get_channels__, args, ,
2413#if defined (HAVE_PORTAUDIO)
2414 if (args.length () == 1)
2415 retval = get_player (args(0))->get_channels ();
2417 octave_unused_parameter (args);
2420 "audio playback and recording through PortAudio");
2434#if defined (HAVE_PORTAUDIO)
2435 if (args.length () == 1)
2436 retval = get_player (args(0))->get_fs ();
2438 octave_unused_parameter (args);
2441 "audio playback and recording through PortAudio");
2455#if defined (HAVE_PORTAUDIO)
2456 if (args.length () == 1)
2457 retval = get_player (args(0))->get_id ();
2459 octave_unused_parameter (args);
2462 "audio playback and recording through PortAudio");
2476#if defined (HAVE_PORTAUDIO)
2477 if (args.length () == 1)
2478 retval = get_player (args(0))->get_nbits ();
2480 octave_unused_parameter (args);
2483 "audio playback and recording through PortAudio");
2489DEFUN_DLD (__player_get_sample_number__, args, ,
2497#if defined (HAVE_PORTAUDIO)
2498 if (args.length () == 1)
2499 retval = get_player (args(0))->get_sample_number ();
2501 octave_unused_parameter (args);
2504 "audio playback and recording through PortAudio");
2518#if defined (HAVE_PORTAUDIO)
2519 if (args.length () == 1)
2520 retval = get_player (args(0))->get_tag ();
2522 octave_unused_parameter (args);
2525 "audio playback and recording through PortAudio");
2531DEFUN_DLD (__player_get_total_samples__, args, ,
2539#if defined (HAVE_PORTAUDIO)
2540 if (args.length () == 1)
2541 retval = get_player (args(0))->get_total_samples ();
2543 octave_unused_parameter (args);
2546 "audio playback and recording through PortAudio");
2552DEFUN_DLD (__player_get_userdata__, args, ,
2560#if defined (HAVE_PORTAUDIO)
2561 if (args.length () == 1)
2562 retval = get_player (args(0))->get_userdata ();
2564 octave_unused_parameter (args);
2567 "audio playback and recording through PortAudio");
2581#if defined (HAVE_PORTAUDIO)
2582 if (args.length () == 1)
2583 retval = get_player (args(0))->isplaying ();
2585 octave_unused_parameter (args);
2588 "audio playback and recording through PortAudio");
2600#if defined (HAVE_PORTAUDIO)
2601 if (args.length () == 1)
2602 get_player (args(0))->pause ();
2605 octave_unused_parameter (args);
2608 "audio playback and recording through PortAudio");
2612DEFUN_DLD (__player_playblocking__, args, ,
2620#if defined (HAVE_PORTAUDIO)
2622 audioplayer *player = get_player (args(0));
2624 if (args.length () == 1)
2626 player->playblocking ();
2628 else if (args.length () == 2)
2630 if (args(1).is_matrix_type ())
2634 unsigned int start =
range.elem (0) - 1;
2635 unsigned int end =
range.elem (1) - 1;
2637 if (start > player->get_total_samples ()
2638 || start > end || end > player->get_total_samples ())
2639 error (
"audioplayer: invalid range specified for playback");
2641 player->set_sample_number (start);
2642 player->set_end_sample (end);
2646 unsigned int start = args(1).int_value () - 1;
2648 if (start > player->get_total_samples ())
2649 error (
"audioplayer: invalid range specified for playback");
2651 player->set_sample_number (start);
2654 player->playblocking ();
2659 octave_unused_parameter (args);
2662 "audio playback and recording through PortAudio");
2674#if defined (HAVE_PORTAUDIO)
2676 if (args.length () == 1)
2678 get_player (args(0))->play ();
2680 else if (args.length () == 2)
2682 audioplayer *player = get_player (args(0));
2684 if (args(1).is_matrix_type ())
2688 unsigned int start =
range.elem (0) - 1;
2689 unsigned int end =
range.elem (1) - 1;
2691 if (start > player->get_total_samples ()
2692 || start > end || end > player->get_total_samples ())
2693 error (
"audioplayer: invalid range specified for playback");
2695 player->set_sample_number (start);
2696 player->set_end_sample (end);
2700 unsigned int start = args(1).int_value () - 1;
2702 if (start > player->get_total_samples ())
2703 error (
"audioplayer: invalid range specified for playback");
2705 player->set_sample_number (start);
2713 octave_unused_parameter (args);
2716 "audio playback and recording through PortAudio");
2726#if defined (HAVE_PORTAUDIO)
2727 if (args.length () == 1)
2728 get_player (args(0))->resume ();
2731 octave_unused_parameter (args);
2734 "audio playback and recording through PortAudio");
2744#if defined (HAVE_PORTAUDIO)
2745 if (args.length () == 2)
2746 get_player (args(0))->set_fs (args(1).int_value ());
2749 octave_unused_parameter (args);
2752 "audio playback and recording through PortAudio");
2762#if defined (HAVE_PORTAUDIO)
2763 if (args.length () == 2)
2764 get_player (args(0))->set_tag (args(1).char_matrix_value ());
2767 octave_unused_parameter (args);
2770 "audio playback and recording through PortAudio");
2774DEFUN_DLD (__player_set_userdata__, args, ,
2780#if defined (HAVE_PORTAUDIO)
2781 if (args.length () == 2)
2782 get_player (args(0))->set_userdata (args(1));
2785 octave_unused_parameter (args);
2788 "audio playback and recording through PortAudio");
2798#if defined (HAVE_PORTAUDIO)
2799 if (args.length () == 1)
2800 get_player (args(0))->stop ();
2803 octave_unused_parameter (args);
2806 "audio playback and recording through PortAudio");
octave_idx_type rows(void) const
octave_idx_type columns(void) const
const T * data(void) const
Size of the specified dimension.
Matrix transpose(void) const
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
OCTAVE_API ColumnVector column(octave_idx_type i) const
Vector representing the dimensions (size) of an Array.
virtual bool is_constant(void) const
virtual bool print_as_scalar(void) const
virtual void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
virtual double scalar_value(bool frc_str_conv=false) const
virtual void print(std::ostream &os, bool pr_as_read_syntax=false)
virtual bool is_defined(void) const
void setfield(const std::string &key, const Cell &val)
void setfield(const std::string &key, const octave_value &val)
octave_idx_type length(void) const
int int_value(bool req_int=false, bool frc_str_conv=false) const
bool is_int8_type(void) const
bool is_int16_type(void) const
const octave_base_value & get_rep(void) const
bool is_uint8_type(void) const
Matrix matrix_value(bool frc_str_conv=false) const
#define DEFUN_DLD(name, args_name, nargout_name, doc)
Macro to define an at run time dynamically loadable builtin function.
OCTINTERP_API void print_usage(void)
void warning_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
ColumnVector transform(const Matrix &m, double x, double y, double z)
bool words_big_endian(void)
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
octave_value_list feval(const char *name, const octave_value_list &args, int nargout)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
static int input(yyscan_t yyscanner)
#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
std::size_t format(std::ostream &os, const char *fmt,...)