Mercurial > octave-nkf
view libinterp/dldfcn/recorder_class.cc @ 19537:36a26a131209
Apply Octave coding style to audio project additions
* libinterp/dldfcn/__player_audioplayer__.cc,
libinterp/dldfcn/__recorder_audiorecorder__.cc,
libinterp/dldfcn/audiodevinfo.cc, libinterp/dldfcn/audioinfo.cc,
libinterp/dldfcn/audioread.cc, libinterp/dldfcn/audiowrite.cc,
libinterp/dldfcn/player_class.cc, libinterp/dldfcn/player_class.h,
libinterp/dldfcn/recorder_class.cc, libinterp/dldfcn/recorder_class.h,
scripts/audio/@audioplayer/__get_properties__.m,
scripts/audio/@audioplayer/audioplayer.m,
scripts/audio/@audioplayer/display.m, scripts/audio/@audioplayer/get.m,
scripts/audio/@audioplayer/isplaying.m, scripts/audio/@audioplayer/pause.m,
scripts/audio/@audioplayer/play.m,
scripts/audio/@audioplayer/playblocking.m,
scripts/audio/@audioplayer/resume.m, scripts/audio/@audioplayer/set.m,
scripts/audio/@audioplayer/stop.m, scripts/audio/@audioplayer/subsasgn.m,
scripts/audio/@audioplayer/subsref.m,
scripts/audio/@audiorecorder/__get_properties__.m,
scripts/audio/@audiorecorder/audiorecorder.m,
scripts/audio/@audiorecorder/display.m, scripts/audio/@audiorecorder/get.m,
scripts/audio/@audiorecorder/getaudiodata.m,
scripts/audio/@audiorecorder/getplayer.m,
scripts/audio/@audiorecorder/isrecording.m,
scripts/audio/@audiorecorder/pause.m, scripts/audio/@audiorecorder/play.m,
scripts/audio/@audiorecorder/record.m,
scripts/audio/@audiorecorder/recordblocking.m,
scripts/audio/@audiorecorder/resume.m, scripts/audio/@audiorecorder/set.m,
scripts/audio/@audiorecorder/stop.m,
scripts/audio/@audiorecorder/subsasgn.m,
scripts/audio/@audiorecorder/subsref.m: Apply consistent Octave indentation,
spacing, and quoting styles. Strip trailing whitespace. Remove braces from
one-line if-else blocks. Simplify some variable declarations.
author | Mike Miller <mtmiller@ieee.org> |
---|---|
date | Thu, 03 Oct 2013 07:52:58 -0400 |
parents | 1f551d169db2 |
children |
line wrap: on
line source
/* 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 <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include "oct.h" #include "ov.h" #include "parse.h" #include <portaudio.h> #include <stdint.h> #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; }