23 #if defined (HAVE_CONFIG_H) 50 #if defined (HAVE_PORTAUDIO) 52 #include <portaudio.h> 55 bits_to_format (
int bits)
110 #if defined (HAVE_PORTAUDIO) 112 int nargin = args.length ();
121 PaError
err = Pa_Initialize ();
123 if (
err != paNoError)
124 error (
"audiodevinfo: PortAudio initialization failed");
126 int num_devices = Pa_GetDeviceCount ();
132 for (
int i = 0;
i < num_devices;
i++)
134 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (
i);
138 warning (
"Octave:invalid-audio-device",
139 "invalid audio device ID = %d",
i);
143 if (device_info->maxInputChannels != 0)
146 if (device_info->maxOutputChannels != 0)
158 for (
int i = 0;
i < num_devices;
i++)
160 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (
i);
164 warning (
"Octave:invalid-audio-device",
165 "invalid audio device ID = %d",
i);
169 const PaHostApiInfo *api_info = Pa_GetHostApiInfo (device_info->hostApi);
171 const char *driver = (api_info ? api_info->name :
"");
174 sprintf (
name,
"%s (%s)", device_info->name, driver);
176 if (device_info->maxInputChannels != 0)
178 input_name(idx_i) =
name;
179 input_driver_version(idx_i) = driver;
184 if (device_info->maxOutputChannels != 0)
186 output_name(idx_o) =
name;
187 output_driver_version(idx_o) = driver;
188 output_id(idx_o) =
i;
194 inputdev.
setfield (
"Name", input_name);
195 inputdev.
setfield (
"DriverVersion", input_driver_version);
197 outputdev.
setfield (
"Name", output_name);
198 outputdev.
setfield (
"DriverVersion", output_driver_version);
199 outputdev.
setfield (
"ID", output_id);
200 devinfo.
setfield (
"input", inputdev);
201 devinfo.
setfield (
"output", outputdev);
212 if (args(0).int_value () == 0)
214 else if (args(0).int_value () == 1)
217 error (
"audiodevinfo: please specify 0 for output and 1 for input devices");
223 int outin = args(0).int_value ();
224 if (args(1).is_string ())
228 for (
int i = 0;
i < numoutput;
i++)
230 if (output_name(
i).string_value () == args(1).string_value ())
240 for (
int i = 0;
i < numinput;
i++)
242 if (input_name(
i).string_value () == args(1).string_value ())
251 error (
"audiodevinfo: please specify 0 for output and 1 for input devices");
257 for (
int i = 0;
i < numoutput;
i++)
259 if (output_id(
i).int_value () == args(1).int_value ())
269 for (
int i = 0;
i < numinput;
i++)
271 if (input_id(
i).int_value () == args(1).int_value ())
280 error (
"audiodevinfo: please specify 0 for output and 1 for input devices");
284 error (
"audiodevinfo: no device meeting the specified criteria found");
293 int io = args(0).int_value ();
294 int rate = args(1).int_value ();
295 int bits = args(2).int_value ();
296 int chans = args(3).int_value ();
298 for (
int i = 0;
i < num_devices;
i++)
300 PaStreamParameters stream_parameters;
301 stream_parameters.device =
i;
302 stream_parameters.channelCount = chans;
303 PaSampleFormat
format = bits_to_format (bits);
306 stream_parameters.sampleFormat =
format;
308 error (
"audiodevinfo: no such bits per sample format");
310 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (
i);
314 warning (
"Octave:invalid-audio-device",
315 "invalid audio device ID = %d",
i);
319 stream_parameters.suggestedLatency
320 = device_info->defaultLowInputLatency;
322 stream_parameters.hostApiSpecificStreamInfo =
nullptr;
326 if (device_info->maxOutputChannels < chans)
329 err = Pa_IsFormatSupported (
nullptr, &stream_parameters, rate);
331 if (
err == paFormatIsSupported)
339 if (device_info->maxInputChannels < chans)
342 err = Pa_IsFormatSupported (&stream_parameters,
nullptr, rate);
343 if (
err == paFormatIsSupported)
356 int id = args(1).int_value ();
357 int rate = args(2).int_value ();
358 int bits = args(3).int_value ();
359 int chans = args(4).int_value ();
360 PaStreamParameters stream_parameters;
361 stream_parameters.device =
id;
362 stream_parameters.channelCount = chans;
363 PaSampleFormat
format = bits_to_format (bits);
365 stream_parameters.sampleFormat =
format;
367 error (
"audiodevinfo: no such bits per sample format");
369 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (
id);
372 error (
"audiodevinfo: invalid audio device ID = %d",
id);
374 stream_parameters.suggestedLatency
375 = device_info->defaultLowInputLatency;
377 stream_parameters.hostApiSpecificStreamInfo =
nullptr;
380 if (device_info->maxOutputChannels < chans)
385 err = Pa_IsFormatSupported (
nullptr, &stream_parameters, rate);
386 if (
err == paFormatIsSupported)
394 if (device_info->maxInputChannels < chans)
399 err = Pa_IsFormatSupported (&stream_parameters,
nullptr, rate);
400 if (
err == paFormatIsSupported)
407 error (
"audiodevinfo: please specify 0 for output and 1 for input devices");
415 octave_unused_parameter (args);
418 "audio playback and recording through PortAudio");
458 #if defined (HAVE_PORTAUDIO) 460 enum audio_type { TYPE_INT8, TYPE_UINT8, TYPE_UINT16, TYPE_DOUBLE };
469 double player_value (
void)
const {
return 0; }
470 virtual double scalar_value (
bool =
false)
const {
return 0; }
471 void print (std::ostream&
os,
bool pr_as_read_syntax =
false);
472 void print_raw (std::ostream&
os,
bool pr_as_read_syntax)
const;
487 void set_fs (
int fs);
489 void set_nbits (
int nbits);
490 int get_nbits (
void);
491 void set_id (
int id);
493 int get_channels (
void);
494 audio_type get_type (
void);
496 void set_sample_number (
unsigned int sample);
497 unsigned int get_sample_number (
void);
498 unsigned int get_total_samples (
void);
499 void set_end_sample (
unsigned int sample);
500 unsigned int get_end_sample (
void);
501 void reset_end_sample (
void);
506 PaStream * get_stream (
void);
508 void playblocking (
void);
513 bool isplaying (
void);
522 unsigned int sample_number;
523 unsigned int end_sample;
530 PaStreamParameters output_parameters;
539 octave_play_callback (
const void *,
void *output,
unsigned long frames,
540 const PaStreamCallbackTimeInfo *,
541 PaStreamCallbackFlags,
void *data)
543 audioplayer *player =
static_cast<audioplayer *
> (data);
546 error (
"audio player callback function called without player");
550 ovl (static_cast<double> (frames)), 1);
553 error (
"audio player callback function failed");
558 if (frames - sound.
rows () != 0 || sound.
columns () < 1
560 error (
"audio player callback function failed");
568 ? sound_l : sound.
column (1));
570 const double *p_l = sound_l.
data ();
571 const double *p_r = sound_r.
data ();
573 switch (player->get_nbits ())
577 static double scale_factor =
std::pow (2.0, 7) - 1.0;
579 int8_t *buffer =
static_cast<int8_t *
> (output);
581 for (
unsigned long i = 0;
i < frames;
i++)
583 buffer[2*
i] = p_l[
i] * scale_factor;
584 buffer[2*
i+1] = p_r[
i] * scale_factor;
591 static double scale_factor =
std::pow (2.0, 15) - 1.0;
593 int16_t *buffer =
static_cast<int16_t *
> (output);
595 for (
unsigned long i = 0;
i < frames;
i++)
597 buffer[2*
i] = p_l[
i] * scale_factor;
598 buffer[2*
i+1] = p_r[
i] * scale_factor;
605 static double scale_factor =
std::pow (2.0, 23) - 1.0;
609 uint8_t *buffer =
static_cast<uint8_t *
> (output);
611 for (
unsigned long i = 0;
i < frames;
i++)
613 int32_t sample_l = p_l[
i];
614 int32_t sample_r = p_r[
i];
616 sample_l &= 0x00ffffff;
617 sample_r &= 0x00ffffff;
620 uint8_t *_sample_l =
reinterpret_cast<uint8_t *
> (&sample_l);
621 uint8_t *_sample_r =
reinterpret_cast<uint8_t *
> (&sample_r);
623 unsigned long offset =
i * 6;
625 buffer[offset+0] = _sample_l[0+big_endian] * scale_factor;
626 buffer[offset+1] = _sample_l[1+big_endian] * scale_factor;
627 buffer[offset+2] = _sample_l[2+big_endian] * scale_factor;
629 buffer[offset+3] = _sample_r[0+big_endian] * scale_factor;
630 buffer[offset+4] = _sample_r[1+big_endian] * scale_factor;
631 buffer[offset+5] = _sample_r[2+big_endian] * scale_factor;
637 error (
"invalid player bit depth in callback function");
640 return return_status;
644 portaudio_play_callback (
const void *,
void *output,
unsigned long frames,
645 const PaStreamCallbackTimeInfo*,
646 PaStreamCallbackFlags,
void *data)
648 audioplayer *player =
static_cast<audioplayer *
> (data);
651 error (
"audio player callback function called without player");
659 const RowVector sound_l = player->get_left ();
660 const RowVector sound_r = player->get_right ();
662 const double *pl = sound_l.
data ();
663 const double *pr = sound_r.
data ();
665 if (player->get_type () == TYPE_DOUBLE)
667 switch (player->get_nbits ())
671 static double scale_factor =
std::pow (2.0, 7) - 1.0;
673 int8_t *buffer =
static_cast<int8_t *
> (output);
675 for (
unsigned long j = 0; j < frames; j++)
677 unsigned int sample_number = player->get_sample_number ();
679 if (sample_number >= player->get_end_sample ())
682 unsigned long offset = j * 2;
684 buffer[offset+0] = pl[sample_number] * scale_factor;
685 buffer[offset+1] = pr[sample_number] * scale_factor;
687 player->set_sample_number (sample_number + 1);
694 static double scale_factor =
std::pow (2.0, 15) - 1.0;
696 int16_t *buffer =
static_cast<int16_t *
> (output);
698 for (
unsigned long j = 0; j < frames; j++)
700 unsigned int sample_number = player->get_sample_number ();
702 if (sample_number >= player->get_end_sample ())
705 unsigned long offset = j * 2;
707 buffer[offset+0] = pl[sample_number] * scale_factor;
708 buffer[offset+1] = pr[sample_number] * scale_factor;
710 player->set_sample_number (sample_number + 1);
717 static double scale_factor =
std::pow (2.0, 23) - 1.0;
721 uint8_t *buffer =
static_cast<uint8_t *
> (output);
723 for (
unsigned long j = 0; j < frames; j++)
725 unsigned int sample_number = player->get_sample_number ();
727 if (sample_number >= player->get_end_sample ())
730 int32_t sample_l = pl[sample_number] * scale_factor;
731 int32_t sample_r = pr[sample_number] * scale_factor;
733 sample_l &= 0x00ffffff;
734 sample_r &= 0x00ffffff;
737 uint8_t *_sample_l =
reinterpret_cast<uint8_t *
> (&sample_l);
738 uint8_t *_sample_r =
reinterpret_cast<uint8_t *
> (&sample_r);
740 unsigned long offset = j * 6;
742 buffer[offset+0] = _sample_l[0+big_endian];
743 buffer[offset+1] = _sample_l[1+big_endian];
744 buffer[offset+2] = _sample_l[2+big_endian];
746 buffer[offset+3] = _sample_r[0+big_endian];
747 buffer[offset+4] = _sample_r[1+big_endian];
748 buffer[offset+5] = _sample_r[2+big_endian];
750 player->set_sample_number (sample_number + 1);
756 error (
"invalid player bit depth in callback function");
759 else if (player->get_type () == TYPE_INT8)
761 int8_t *buffer =
static_cast<int8_t *
> (output);
763 for (
unsigned long j = 0; j < frames; j++)
765 unsigned int sample_number = player->get_sample_number ();
767 if (sample_number >= player->get_end_sample ())
770 unsigned long offset = j * 2;
772 buffer[offset+0] = pl[sample_number];
773 buffer[offset+1] = pr[sample_number];
775 player->set_sample_number (sample_number + 1);
778 else if (player->get_type () == TYPE_UINT8)
780 uint8_t *buffer =
static_cast<uint8_t *
> (output);
782 for (
unsigned long j = 0; j < frames; j++)
784 unsigned int sample_number = player->get_sample_number ();
786 if (sample_number >= player->get_end_sample ())
789 unsigned long offset = j * 2;
791 buffer[offset+0] = pl[sample_number];
792 buffer[offset+1] = pr[sample_number];
794 player->set_sample_number (sample_number + 1);
797 else if (player->get_type () == TYPE_UINT16)
799 int16_t *buffer =
static_cast<int16_t *
> (output);
801 for (
unsigned long j = 0; j < frames; j++)
803 unsigned int sample_number = player->get_sample_number ();
805 if (sample_number >= player->get_end_sample ())
808 unsigned long offset = j * 2;
810 buffer[offset+0] = pl[sample_number];
811 buffer[offset+1] = pr[sample_number];
813 player->set_sample_number (sample_number + 1);
821 safe_audioplayer_stop (audioplayer *player)
826 audioplayer::audioplayer (
void)
827 : octave_callback_function (nullptr),
828 id (-1),
fs (0), nbits (16), channels (0), sample_number (0),
829 end_sample (-1), tag (
""),
y (), userdata (
Matrix ()),
830 left (),
right (), stream (nullptr), output_parameters (),
type ()
833 audioplayer::~audioplayer (
void)
837 warning (
"Octave:audio-interrupt",
838 "interrupting playing audioplayer");
844 audioplayer::print (std::ostream&
os,
bool pr_as_read_syntax)
846 print_raw (
os, pr_as_read_syntax);
851 audioplayer::print_raw (std::ostream&
os,
bool)
const 857 audioplayer::init_fn (
void)
859 if (Pa_Initialize () != paNoError)
860 error (
"audioplayer: initialization error!");
862 if (Pa_GetDeviceCount () < 1)
863 error (
"audioplayer: no audio devices found or available!");
865 int device = get_id ();
868 device = Pa_GetDefaultOutputDevice ();
870 output_parameters.device = device;
871 output_parameters.channelCount = 2;
872 output_parameters.sampleFormat = bits_to_format (get_nbits ());
874 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
877 warning (
"Octave:invalid-default-audio-device",
878 "invalid default audio device ID = %d", device);
880 output_parameters.suggestedLatency
881 = (device_info ? device_info->defaultHighOutputLatency : -1);
883 output_parameters.hostApiSpecificStreamInfo =
nullptr;
887 audioplayer::init (
void)
895 if (Pa_Initialize () != paNoError)
896 error (
"audioplayer: initialization error!");
898 if (Pa_GetDeviceCount () < 1)
899 error (
"audioplayer: no audio devices found or available!");
901 int device = get_id ();
904 device = Pa_GetDefaultOutputDevice ();
906 output_parameters.device = device;
907 output_parameters.channelCount = 2;
909 if (
type == TYPE_DOUBLE)
910 output_parameters.sampleFormat = bits_to_format (get_nbits ());
911 else if (
type == TYPE_INT8)
912 output_parameters.sampleFormat = paInt8;
913 else if (
type == TYPE_UINT8)
914 output_parameters.sampleFormat = paUInt8;
915 else if (
type == TYPE_UINT16)
916 output_parameters.sampleFormat = paInt16;
918 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
921 warning (
"Octave:invalid-default-audio-device",
922 "invalid default audio device ID = %d", device);
924 output_parameters.suggestedLatency
925 = (device_info ? device_info->defaultHighOutputLatency : -1);
927 output_parameters.hostApiSpecificStreamInfo =
nullptr;
947 channels =
y.rows ();
959 octave_callback_function = fn;
965 audioplayer::get_y (
void)
971 audioplayer::get_left (
void)
const 977 audioplayer::get_right (
void)
const 983 audioplayer::set_fs (
int fs_arg)
989 audioplayer::get_fs (
void)
995 audioplayer::set_nbits (
int nbits_arg)
1001 audioplayer::get_nbits (
void)
1007 audioplayer::set_id (
int id_arg)
1013 audioplayer::get_id (
void)
1019 audioplayer::get_channels (
void)
1025 audioplayer::get_type (
void)
1031 audioplayer::set_sample_number (
unsigned int sample_number_arg)
1033 sample_number = sample_number_arg;
1037 audioplayer::get_sample_number (
void)
1039 return sample_number;
1043 audioplayer::get_total_samples (
void)
1045 return left.numel ();
1049 audioplayer::set_end_sample (
unsigned int end_sample_arg)
1051 end_sample = end_sample_arg;
1055 audioplayer::get_end_sample (
void)
1061 audioplayer::reset_end_sample (
void)
1063 set_end_sample (
left.numel ());
1067 audioplayer::set_tag (
const charMatrix& tag_arg)
1073 audioplayer::get_tag (
void)
1079 audioplayer::set_userdata (
const octave_value& userdata_arg)
1081 userdata = userdata_arg;
1085 audioplayer::get_userdata (
void)
1091 audioplayer::playblocking (
void)
1096 const unsigned int buffer_size = get_fs () / 20;
1100 err = Pa_OpenStream (&stream,
nullptr, &(output_parameters), get_fs (),
1101 buffer_size, paClipOff,
nullptr,
nullptr);
1102 if (
err != paNoError)
1103 error (
"audioplayer: unable to open audio playback stream");
1105 err = Pa_StartStream (stream);
1106 if (
err != paNoError)
1107 error (
"audioplayer: unable to start audio playback stream");
1109 unsigned int start, end;
1110 start = get_sample_number ();
1111 end = get_end_sample ();
1117 for (
unsigned int i =
start;
i < end;
i += buffer_size)
1121 if (octave_callback_function !=
nullptr)
1122 octave_play_callback (
nullptr, buffer, buffer_size,
nullptr, 0,
this);
1124 portaudio_play_callback (
nullptr, buffer, buffer_size,
nullptr, 0,
this);
1126 err = Pa_WriteStream (stream, buffer, buffer_size);
1131 audioplayer::play (
void)
1136 const unsigned int buffer_size = get_fs () / 20;
1139 if (octave_callback_function !=
nullptr)
1140 err = Pa_OpenStream (&stream,
nullptr, &(output_parameters),
1141 get_fs (), buffer_size, paClipOff,
1142 octave_play_callback,
this);
1144 err = Pa_OpenStream (&stream,
nullptr, &(output_parameters),
1145 get_fs (), buffer_size, paClipOff,
1146 portaudio_play_callback,
this);
1148 if (
err != paNoError)
1149 error (
"audioplayer: failed to open audio playback stream");
1151 err = Pa_StartStream (stream);
1152 if (
err != paNoError)
1153 error (
"audioplayer: failed to start audio playback stream");
1159 if (get_stream () ==
nullptr)
1163 err = Pa_StopStream (stream);
1164 if (
err != paNoError)
1165 error (
"audiorecorder: failed to stop audio recording stream");
1169 audioplayer::resume (
void)
1171 if (get_stream () ==
nullptr)
1175 err = Pa_StartStream (stream);
1176 if (
err != paNoError)
1177 error (
"audiorecorder: failed to start audio recording stream");
1181 audioplayer::get_stream (
void)
1187 audioplayer::stop (
void)
1189 if (get_stream () ==
nullptr)
1193 set_sample_number (0);
1194 reset_end_sample ();
1195 if (! Pa_IsStreamStopped (get_stream ()))
1197 err = Pa_AbortStream (get_stream ());
1198 if (
err != paNoError)
1199 error (
"audioplayer: failed to stop audio playback stream");
1202 err = Pa_CloseStream (get_stream ());
1203 if (
err != paNoError)
1204 error (
"audioplayer: failed to close audio playback stream");
1210 audioplayer::isplaying (
void)
1212 if (get_stream () ==
nullptr)
1216 err = Pa_IsStreamActive (stream);
1217 if (
err != 0 &&
err != 1)
1218 error (
"audiorecorder: checking stream activity status failed");
1226 audiorecorder (
void);
1227 ~audiorecorder (
void);
1230 double player_value (
void)
const {
return 0; }
1231 virtual double scalar_value (
bool =
false)
const {
return 0; }
1232 void print (std::ostream&
os,
bool pr_as_read_syntax =
false);
1233 void print_raw (std::ostream&
os,
bool pr_as_read_syntax)
const;
1237 bool is_defined (
void)
const {
return true; }
1241 void set_fs (
int fs);
1243 void set_nbits (
int nbits);
1244 int get_nbits (
void);
1245 void set_id (
int id);
1247 void set_channels (
int channels);
1248 int get_channels (
void);
1249 audio_type get_type (
void);
1251 void set_sample_number (
unsigned int sample);
1252 unsigned int get_sample_number (
void);
1253 unsigned int get_total_samples (
void);
1254 void set_end_sample (
unsigned int sample);
1255 unsigned int get_end_sample (
void);
1256 void reset_end_sample (
void);
1261 PaStream * get_stream (
void);
1264 audioplayer * getplayer (
void);
1265 bool isrecording (
void);
1266 audioplayer play (
void);
1268 void recordblocking (
float seconds);
1272 void append (
float sample_l,
float sample_r);
1281 unsigned int sample_number;
1282 unsigned int end_sample;
1286 std::vector<float>
left;
1287 std::vector<float>
right;
1289 PaStreamParameters input_parameters;
1298 octave_record_callback (
const void *
input,
void *,
unsigned long frames,
1299 const PaStreamCallbackTimeInfo *,
1300 PaStreamCallbackFlags,
void *data)
1302 audiorecorder *recorder =
static_cast<audiorecorder *
> (data);
1305 error (
"audio recorder callback function called without player");
1307 int channels = recorder->get_channels ();
1309 Matrix sound (frames, 2);
1310 sound.
resize (frames, 2);
1312 if (recorder->get_nbits () == 8)
1314 static double scale_factor =
std::pow (2.0, 7) - 1.0;
1316 const int8_t *input8 =
static_cast<const int8_t *
> (
input);
1318 for (
unsigned long i = 0;
i < frames;
i++)
1320 float sample_l = input8[
i*channels] / scale_factor;
1321 float sample_r = input8[
i*channels + (channels - 1)] / scale_factor;
1323 sound(
i,0) = sample_l;
1324 sound(
i,1) = sample_r;
1327 else if (recorder->get_nbits () == 16)
1329 static double scale_factor =
std::pow (2.0, 15) - 1.0;
1331 const int16_t *input16 =
static_cast<const int16_t *
> (
input);
1333 for (
unsigned long i = 0;
i < frames;
i++)
1335 float sample_l = input16[
i*channels] / scale_factor;
1336 float sample_r = input16[
i*channels + (channels - 1)] / scale_factor;
1338 sound(
i,0) = sample_l;
1339 sound(
i,1) = sample_r;
1342 else if (recorder->get_nbits () == 24)
1344 static double scale_factor =
std::pow (2.0, 23);
1347 const uint8_t *input24 =
static_cast<const uint8_t *
> (
input);
1349 int32_t sample_l32 = 0, sample_r32 = 0;
1351 uint8_t *sample_l =
reinterpret_cast<uint8_t *
> (&sample_l32);
1352 uint8_t *sample_r =
reinterpret_cast<uint8_t *
> (&sample_r32);
1354 for (
unsigned long i = 0;
i < frames;
i++)
1356 for (
int j = 0; j < 3; j++)
1358 sample_l[j] = input24[
i*channels*3 + j];
1359 sample_r[j] = input24[
i*channels*3 + (channels - 1)*3 + j];
1362 if (sample_l32 & 0x00800000)
1363 sample_l32 |= 0xff000000;
1365 if (sample_r32 & 0x00800000)
1366 sample_r32 |= 0xff000000;
1368 sound(
i,0) = sample_l32 / scale_factor;
1369 sound(
i,1) = sample_r32 / scale_factor;
1380 portaudio_record_callback (
const void *
input,
void *,
unsigned long frames,
1381 const PaStreamCallbackTimeInfo *,
1382 PaStreamCallbackFlags,
void *data)
1384 audiorecorder *recorder =
static_cast<audiorecorder *
> (data);
1387 error (
"audio recorder callback function called without player");
1389 int channels = recorder->get_channels ();
1391 if (recorder->get_nbits () == 8)
1393 static float scale_factor =
std::pow (2.0
f, 7) - 1.0f;
1395 const int8_t *input8 =
static_cast<const int8_t *
> (
input);
1397 for (
unsigned long i = 0;
i < frames;
i++)
1399 float sample_l = input8[
i*channels] / scale_factor;
1400 float sample_r = input8[
i*channels + (channels - 1)] / scale_factor;
1402 recorder->append (sample_l, sample_r);
1405 else if (recorder->get_nbits () == 16)
1407 static float scale_factor =
std::pow (2.0
f, 15) - 1.0f;
1409 const int16_t *input16 =
static_cast<const int16_t *
> (
input);
1411 for (
unsigned long i = 0;
i < frames;
i++)
1413 float sample_l = input16[
i*channels] / scale_factor;
1414 float sample_r = input16[
i*channels + (channels - 1)] / scale_factor;
1416 recorder->append (sample_l, sample_r);
1419 else if (recorder->get_nbits () == 24)
1421 static float scale_factor =
std::pow (2.0
f, 23);
1424 const uint8_t *input24 =
static_cast<const uint8_t *
> (
input);
1426 int32_t sample_l32 = 0, sample_r32 = 0;
1428 uint8_t *sample_l =
reinterpret_cast<uint8_t *
> (&sample_l32);
1429 uint8_t *sample_r =
reinterpret_cast<uint8_t *
> (&sample_r32);
1431 for (
unsigned long i = 0;
i < frames;
i++)
1433 for (
int j = 0; j < 3; j++)
1435 sample_l[j] = input24[
i*channels*3 + j];
1436 sample_r[j] = input24[
i*channels*3 + (channels - 1)*3 + j];
1439 if (sample_l32 & 0x00800000)
1440 sample_l32 |= 0xff000000;
1442 if (sample_r32 & 0x00800000)
1443 sample_r32 |= 0xff000000;
1445 recorder->append (sample_l32 / scale_factor,
1446 sample_r32 / scale_factor);
1450 if (recorder->get_sample_number () >= recorder->get_end_sample ())
1457 safe_audiorecorder_stop (audiorecorder *recorder)
1462 audiorecorder::audiorecorder (
void)
1463 : octave_callback_function (nullptr),
1464 id (-1),
fs (44100), nbits (16), channels (2), sample_number (0),
1465 end_sample (-1), tag (
""),
y (), userdata (
Matrix ()),
1466 left (),
right (), stream (nullptr), input_parameters (),
type ()
1469 audiorecorder::~audiorecorder (
void)
1473 warning (
"Octave:audio-interrupt",
1474 "interrupting recording audiorecorder");
1480 audiorecorder::print (std::ostream&
os,
bool pr_as_read_syntax)
1482 print_raw (
os, pr_as_read_syntax);
1487 audiorecorder::print_raw (std::ostream&
os,
bool)
const 1493 audiorecorder::init (
void)
1495 if (Pa_Initialize () != paNoError)
1496 error (
"audiorecorder: initialization error!");
1498 if (Pa_GetDeviceCount () < 1)
1499 error (
"audiorecorder: no audio devices found or available!");
1501 int device = get_id ();
1504 device = Pa_GetDefaultInputDevice ();
1506 input_parameters.device = device;
1507 input_parameters.channelCount = get_channels ();
1508 input_parameters.sampleFormat = bits_to_format (get_nbits ());
1510 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
1513 warning (
"Octave:invalid-default-audio-device",
1514 "invalid default audio device ID = %d", device);
1516 input_parameters.suggestedLatency
1517 = (device_info ? device_info->defaultHighInputLatency : -1);
1519 input_parameters.hostApiSpecificStreamInfo =
nullptr;
1523 audiorecorder::set_fs (
int fs_arg)
1529 audiorecorder::get_fs (
void)
1535 audiorecorder::set_nbits (
int nbits_arg)
1541 audiorecorder::get_nbits (
void)
1547 audiorecorder::set_id (
int id_arg)
1553 audiorecorder::get_id (
void)
1559 audiorecorder::set_channels (
int channels_arg)
1561 assert (channels_arg == 1 || channels_arg == 2);
1562 channels = channels_arg;
1566 audiorecorder::get_channels (
void)
1572 audiorecorder::get_type (
void)
1578 audiorecorder::set_sample_number (
unsigned int sample_number_arg)
1580 sample_number = sample_number_arg;
1584 audiorecorder::get_sample_number (
void)
1586 return sample_number;
1590 audiorecorder::get_total_samples (
void)
1592 return left.size ();
1596 audiorecorder::set_end_sample (
unsigned int end_sample_arg)
1598 end_sample = end_sample_arg;
1602 audiorecorder::get_end_sample (
void)
1608 audiorecorder::reset_end_sample (
void)
1610 set_end_sample (
left.size ());
1614 audiorecorder::set_tag (
const charMatrix& tag_arg)
1620 audiorecorder::get_tag (
void)
1626 audiorecorder::set_userdata (
const octave_value& userdata_arg)
1628 userdata = userdata_arg;
1632 audiorecorder::get_userdata (
void)
1638 audiorecorder::getaudiodata (
void)
1642 for (
unsigned int i = 0;
i <
left.size ();
i++)
1652 audiorecorder::getplayer (
void)
1654 audioplayer *player =
new audioplayer ();
1656 player->set_y (getaudiodata ());
1657 player->set_fs (get_fs ());
1658 player->set_nbits (get_nbits ());
1665 audiorecorder::isrecording (
void)
1667 if (get_stream () ==
nullptr)
1671 err = Pa_IsStreamActive (stream);
1672 if (
err != 0 &&
err != 1)
1673 error (
"audiorecorder: checking stream activity status failed");
1679 audiorecorder::record (
void)
1687 const unsigned int buffer_size = get_fs () / 20;
1690 if (octave_callback_function !=
nullptr)
1692 err = Pa_OpenStream (&stream, &(input_parameters),
nullptr,
1693 get_fs (), buffer_size, paClipOff,
1694 octave_record_callback,
this);
1698 err = Pa_OpenStream (&stream, &(input_parameters),
nullptr,
1699 get_fs (), buffer_size, paClipOff,
1700 portaudio_record_callback,
this);
1702 if (
err != paNoError)
1703 error (
"audiorecorder: unable to open audio recording stream");
1705 err = Pa_StartStream (stream);
1706 if (
err != paNoError)
1707 error (
"audiorecorder: unable to start audio recording stream");
1711 audiorecorder::recordblocking (
float seconds)
1719 const unsigned int buffer_size = get_fs () / 20;
1723 err = Pa_OpenStream (&stream, &(input_parameters),
nullptr,
1724 get_fs (), buffer_size, paClipOff,
nullptr,
this);
1725 if (
err != paNoError)
1726 error (
"audiorecorder: unable to open audio recording stream");
1728 err = Pa_StartStream (stream);
1729 if (
err != paNoError)
1730 error (
"audiorecorder: unable to start audio recording stream");
1732 unsigned int frames = seconds * get_fs ();
1738 for (
unsigned int i = 0;
i < frames;
i += buffer_size)
1742 Pa_ReadStream (get_stream (), buffer, buffer_size);
1744 if (octave_callback_function !=
nullptr)
1745 octave_record_callback (buffer,
nullptr, buffer_size,
nullptr, 0,
this);
1747 portaudio_record_callback (buffer,
nullptr, buffer_size,
nullptr, 0,
this);
1754 if (get_stream () ==
nullptr)
1758 err = Pa_StopStream (stream);
1759 if (
err != paNoError)
1760 error (
"audiorecorder: unable to stop audio recording stream");
1764 audiorecorder::resume (
void)
1766 if (get_stream () ==
nullptr)
1770 err = Pa_StartStream (stream);
1771 if (
err != paNoError)
1772 error (
"audiorecorder: unable to start audio recording stream");
1776 audiorecorder::stop (
void)
1778 if (get_stream () ==
nullptr)
1782 if (! Pa_IsStreamStopped (get_stream ()))
1784 err = Pa_AbortStream (get_stream ());
1785 if (
err != paNoError)
1786 error (
"audioplayer: unable to stop audio playback stream");
1789 err = Pa_CloseStream (stream);
1790 if (
err != paNoError)
1791 error (
"audiorecorder: unable to close audio recording stream");
1793 set_sample_number (0);
1794 reset_end_sample ();
1801 left.push_back (sample_l);
1802 right.push_back (sample_r);
1803 set_sample_number (get_sample_number () + 1);
1807 audiorecorder::get_stream (
void)
1814 DEFUN_DLD (__recorder_audiorecorder__, args, ,
1824 #if ! defined (HAVE_PORTAUDIO) 1825 octave_unused_parameter (args);
1828 "audio playback and recording through PortAudio");
1831 int nargin = args.length ();
1833 audiorecorder *recorder =
new audiorecorder ();
1837 bool is_function = (args(0).is_string () || args(0).is_function_handle ()
1838 || args(0).is_inline_function ());
1841 error (
"audioplayer: callbacks not yet implemented");
1846 recorder->set_fs (args(0).int_value ());
1847 recorder->set_nbits (args(1).int_value ());
1848 recorder->set_channels (args(2).int_value ());
1853 recorder->set_id (args(3).int_value ());
1864 #if defined (HAVE_PORTAUDIO) 1866 static audiorecorder *
1873 audiorecorder *rec =
dynamic_cast<audiorecorder *
> (ncrep);
1875 error (
"audiodevinfo.cc get_recorder: dynamic_cast to audiorecorder failed");
1882 DEFUN_DLD (__recorder_getaudiodata__, args, ,
1889 #if ! defined (HAVE_PORTAUDIO) 1890 octave_unused_parameter (args);
1893 "audio playback and recording through PortAudio");
1895 retval = get_recorder (args(0))->getaudiodata ();
1900 DEFUN_DLD (__recorder_get_channels__, args, ,
1907 #if ! defined (HAVE_PORTAUDIO) 1908 octave_unused_parameter (args);
1911 "audio playback and recording through PortAudio");
1913 retval = get_recorder (args(0))->get_channels ();
1925 #if ! defined (HAVE_PORTAUDIO) 1926 octave_unused_parameter (args);
1929 "audio playback and recording through PortAudio");
1931 retval = get_recorder (args(0))->get_fs ();
1943 #if ! defined (HAVE_PORTAUDIO) 1944 octave_unused_parameter (args);
1947 "audio playback and recording through PortAudio");
1949 retval = get_recorder (args(0))->get_id ();
1954 DEFUN_DLD (__recorder_get_nbits__, args, ,
1961 #if ! defined (HAVE_PORTAUDIO) 1962 octave_unused_parameter (args);
1965 "audio playback and recording through PortAudio");
1967 retval = get_recorder (args(0))->get_nbits ();
1972 DEFUN_DLD (__recorder_get_sample_number__, args, ,
1979 #if ! defined (HAVE_PORTAUDIO) 1980 octave_unused_parameter (args);
1983 "audio playback and recording through PortAudio");
1985 retval = get_recorder (args(0))->get_sample_number ();
1990 DEFUN_DLD (__recorder_get_tag__, args, ,
1997 #if ! defined (HAVE_PORTAUDIO) 1998 octave_unused_parameter (args);
2001 "audio playback and recording through PortAudio");
2003 retval = get_recorder (args(0))->get_tag ();
2008 DEFUN_DLD (__recorder_get_total_samples__, args, ,
2015 #if ! defined (HAVE_PORTAUDIO) 2016 octave_unused_parameter (args);
2019 "audio playback and recording through PortAudio");
2021 retval = get_recorder (args(0))->get_total_samples ();
2026 DEFUN_DLD (__recorder_get_userdata__, args, ,
2033 #if ! defined (HAVE_PORTAUDIO) 2034 octave_unused_parameter (args);
2037 "audio playback and recording through PortAudio");
2039 retval = get_recorder (args(0))->get_userdata ();
2044 DEFUN_DLD (__recorder_isrecording__, args, ,
2051 #if ! defined (HAVE_PORTAUDIO) 2052 octave_unused_parameter (args);
2055 "audio playback and recording through PortAudio");
2057 retval = get_recorder (args(0))->isrecording ();
2068 #if ! defined (HAVE_PORTAUDIO) 2069 octave_unused_parameter (args);
2072 "audio playback and recording through PortAudio");
2074 get_recorder (args(0))->pause ();
2079 DEFUN_DLD (__recorder_recordblocking__, args, ,
2085 #if ! defined (HAVE_PORTAUDIO) 2086 octave_unused_parameter (args);
2089 "audio playback and recording through PortAudio");
2091 float seconds = args(1).float_value ();
2092 get_recorder (args(0))->recordblocking (seconds);
2104 #if ! defined (HAVE_PORTAUDIO) 2105 octave_unused_parameter (args);
2108 "audio playback and recording through PortAudio");
2110 audiorecorder *recorder = get_recorder (args(0));
2112 if (args.length () == 2)
2113 recorder->set_end_sample (args(1).int_value () * recorder->get_fs ());
2115 recorder->record ();
2126 #if ! defined (HAVE_PORTAUDIO) 2127 octave_unused_parameter (args);
2130 "audio playback and recording through PortAudio");
2132 if (args.length () == 1)
2133 get_recorder (args(0))->resume ();
2144 #if ! defined (HAVE_PORTAUDIO) 2145 octave_unused_parameter (args);
2148 "audio playback and recording through PortAudio");
2150 if (args.length () == 2)
2151 get_recorder (args(0))->set_fs (args(1).int_value ());
2156 DEFUN_DLD (__recorder_set_tag__, args, ,
2162 #if ! defined (HAVE_PORTAUDIO) 2163 octave_unused_parameter (args);
2166 "audio playback and recording through PortAudio");
2168 if (args.length () == 2)
2169 get_recorder (args(0))->set_tag (args(1).char_matrix_value ());
2174 DEFUN_DLD (__recorder_set_userdata__, args, ,
2180 #if ! defined (HAVE_PORTAUDIO) 2181 octave_unused_parameter (args);
2184 "audio playback and recording through PortAudio");
2186 if (args.length () == 2)
2187 get_recorder (args(0))->set_userdata (args(1));
2198 #if ! defined (HAVE_PORTAUDIO) 2199 octave_unused_parameter (args);
2202 "audio playback and recording through PortAudio");
2204 if (args.length () == 1)
2205 get_recorder (args(0))->stop ();
2210 DEFUN_DLD (__player_audioplayer__, args, ,
2219 #if ! defined (HAVE_PORTAUDIO) 2220 octave_unused_parameter (args);
2223 "audio playback and recording through PortAudio");
2226 audioplayer *recorder =
new audioplayer ();
2229 error (
"__player_audioplayer__: Couldn't instantiate new audioplayer");
2231 bool is_function = (args(0).is_string () || args(0).is_function_handle ()
2232 || args(0).is_inline_function ());
2235 error (
"audioplayer: callbacks not yet implemented");
2237 recorder->set_y (args(0));
2238 recorder->set_fs (args(1).int_value ());
2240 switch (args.length ())
2243 recorder->set_nbits (args(2).int_value ());
2247 recorder->set_nbits (args(2).int_value ());
2248 recorder->set_id (args(3).int_value ());
2253 recorder->init_fn ();
2262 #if defined (HAVE_PORTAUDIO) 2264 static audioplayer *
2271 audioplayer *pl =
dynamic_cast<audioplayer *
> (ncrep);
2273 error (
"audiodevinfo.cc get_player: dynamic_cast to audioplayer failed");
2280 DEFUN_DLD (__player_get_channels__, args, ,
2287 #if ! defined (HAVE_PORTAUDIO) 2288 octave_unused_parameter (args);
2291 "audio playback and recording through PortAudio");
2293 if (args.length () == 1)
2294 retval = get_player (args(0))->get_channels ();
2306 #if ! defined (HAVE_PORTAUDIO) 2307 octave_unused_parameter (args);
2310 "audio playback and recording through PortAudio");
2312 if (args.length () == 1)
2313 retval = get_player (args(0))->get_fs ();
2325 #if ! defined (HAVE_PORTAUDIO) 2326 octave_unused_parameter (args);
2329 "audio playback and recording through PortAudio");
2331 if (args.length () == 1)
2332 retval = get_player (args(0))->get_id ();
2337 DEFUN_DLD (__player_get_nbits__, args, ,
2344 #if ! defined (HAVE_PORTAUDIO) 2345 octave_unused_parameter (args);
2348 "audio playback and recording through PortAudio");
2350 if (args.length () == 1)
2351 retval = get_player (args(0))->get_nbits ();
2356 DEFUN_DLD (__player_get_sample_number__, args, ,
2363 #if ! defined (HAVE_PORTAUDIO) 2364 octave_unused_parameter (args);
2367 "audio playback and recording through PortAudio");
2369 if (args.length () == 1)
2370 retval = get_player (args(0))->get_sample_number ();
2382 #if ! defined (HAVE_PORTAUDIO) 2383 octave_unused_parameter (args);
2386 "audio playback and recording through PortAudio");
2388 if (args.length () == 1)
2389 retval = get_player (args(0))->get_tag ();
2394 DEFUN_DLD (__player_get_total_samples__, args, ,
2401 #if ! defined (HAVE_PORTAUDIO) 2402 octave_unused_parameter (args);
2405 "audio playback and recording through PortAudio");
2407 if (args.length () == 1)
2408 retval = get_player (args(0))->get_total_samples ();
2413 DEFUN_DLD (__player_get_userdata__, args, ,
2420 #if ! defined (HAVE_PORTAUDIO) 2421 octave_unused_parameter (args);
2424 "audio playback and recording through PortAudio");
2426 if (args.length () == 1)
2427 retval = get_player (args(0))->get_userdata ();
2432 DEFUN_DLD (__player_isplaying__, args, ,
2439 #if ! defined (HAVE_PORTAUDIO) 2440 octave_unused_parameter (args);
2443 "audio playback and recording through PortAudio");
2445 if (args.length () == 1)
2446 retval = get_player (args(0))->isplaying ();
2457 #if ! defined (HAVE_PORTAUDIO) 2458 octave_unused_parameter (args);
2461 "audio playback and recording through PortAudio");
2463 if (args.length () == 1)
2464 get_player (args(0))->
pause ();
2469 DEFUN_DLD (__player_playblocking__, args, ,
2477 #if ! defined (HAVE_PORTAUDIO) 2478 octave_unused_parameter (args);
2481 "audio playback and recording through PortAudio");
2484 audioplayer *player = get_player (args(0));
2486 if (args.length () == 1)
2488 player->playblocking ();
2490 else if (args.length () == 2)
2492 if (args(1).is_matrix_type ())
2499 if (
start > player->get_total_samples ()
2500 ||
start > end || end > player->get_total_samples ())
2501 error (
"audioplayer: invalid range specified for playback");
2503 player->set_sample_number (
start);
2504 player->set_end_sample (end);
2508 unsigned int start = args(1).int_value () - 1;
2510 if (
start > player->get_total_samples ())
2511 error (
"audioplayer: invalid range specified for playback");
2513 player->set_sample_number (
start);
2516 player->playblocking ();
2531 #if ! defined (HAVE_PORTAUDIO) 2532 octave_unused_parameter (args);
2535 "audio playback and recording through PortAudio");
2538 if (args.length () == 1)
2540 get_player (args(0))->play ();
2542 else if (args.length () == 2)
2544 audioplayer *player = get_player (args(0));
2546 if (args(1).is_matrix_type ())
2553 if (
start > player->get_total_samples ()
2554 ||
start > end || end > player->get_total_samples ())
2555 error (
"audioplayer: invalid range specified for playback");
2557 player->set_sample_number (
start);
2558 player->set_end_sample (end);
2562 unsigned int start = args(1).int_value () - 1;
2564 if (
start > player->get_total_samples ())
2565 error (
"audioplayer: invalid range specified for playback");
2567 player->set_sample_number (
start);
2583 #if ! defined (HAVE_PORTAUDIO) 2584 octave_unused_parameter (args);
2587 "audio playback and recording through PortAudio");
2589 if (args.length () == 1)
2590 get_player (args(0))->resume ();
2601 #if ! defined (HAVE_PORTAUDIO) 2602 octave_unused_parameter (args);
2605 "audio playback and recording through PortAudio");
2607 if (args.length () == 2)
2608 get_player (args(0))->set_fs (args(1).int_value ());
2619 #if ! defined (HAVE_PORTAUDIO) 2620 octave_unused_parameter (args);
2623 "audio playback and recording through PortAudio");
2625 if (args.length () == 2)
2626 get_player (args(0))->set_tag (args(1).char_matrix_value ());
2631 DEFUN_DLD (__player_set_userdata__, args, ,
2637 #if ! defined (HAVE_PORTAUDIO) 2638 octave_unused_parameter (args);
2641 "audio playback and recording through PortAudio");
2643 if (args.length () == 2)
2644 get_player (args(0))->set_userdata (args(1));
2655 #if ! defined (HAVE_PORTAUDIO) 2656 octave_unused_parameter (args);
2659 "audio playback and recording through PortAudio");
2661 if (args.length () == 1)
2662 get_player (args(0))->stop ();
OCTINTERP_API octave_value_list feval(const std::string &name, const octave_value_list &args=octave_value_list(), int nargout=0)
octave_idx_type rows(void) const
is already an absolute the name is checked against the file system instead of Octave s loadpath In this if otherwise an empty string is returned If the first argument is a cell array of search each directory of the loadpath for element of the cell array and return the first that matches If the second optional argument return a cell array containing the list of all files that have the same name in the path If no files are found
int int_value(bool req_int=false, bool frc_str_conv=false) const
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
const T * data(void) const
OCTINTERP_API void print_usage(void)
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE * f
void add_fcn(void(*fcn)(void))
void error(const char *fmt,...)
void setfield(const std::string &key, const octave_value &val)
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
const octave_base_value & get_rep(void) const
octave_idx_type columns(void) const
in this the arguments are accumulated from left to right
bool is_int16_type(void) const
virtual bool is_constant(void) const
virtual void print(std::ostream &os, bool pr_as_read_syntax=false)
octave_value & elem(octave_idx_type n)
#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
nd deftypefn *std::string name
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
ColumnVector column(octave_idx_type i) const
virtual bool print_as_scalar(void) const
virtual double scalar_value(bool frc_str_conv=false) const
OCTAVE_EXPORT octave_value_list or cell arrays Arguments are concatenated vertically The returned values are padded with blanks as needed to make each row of the string array have the same length Empty input strings are significant and will concatenated in the output For numerical input
bool is_int8_type(void) const
bool words_big_endian(void)
void setfield(const std::string &key, const Cell &val)
void warning(const char *fmt,...)
octave::unwind_protect frame
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).isinteger())
virtual bool is_defined(void) const
the element is set to zero In other the statement xample y
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
octave::sys::file_stat fs(filename)
#define DEFUN_DLD(name, args_name, nargout_name, doc)
Macro to define an at run time dynamically loadable builtin function.
OCTAVE_EXPORT octave_value_list error nd deftypefn *const octave_scalar_map err
OCTAVE_EXPORT octave_value_list or cell arrays Arguments are concatenated vertically The returned values are padded with blanks as needed to make each row of the string array have the same length Empty input strings are significant and will concatenated in the output For numerical each element is converted to the corresponding ASCII character A range error results if an input is outside the ASCII range(0-255). For cell arrays
octave_idx_type length(void) const
virtual void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
Vector representing the dimensions (size) of an Array.
bool is_uint8_type(void) const
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Matrix matrix_value(bool frc_str_conv=false) const