/* interruption listeners */ void audio_unit_interruption_listener(void *closure, UInt32 inInterruptionState) { OSStatus err = 0; aubio_audio_unit_t *o = (aubio_audio_unit_t *) closure; AudioUnit this_unit = o->audio_unit; if (inInterruptionState == kAudioSessionEndInterruption) { AUBIO_WRN("audio_unit: session interruption ended\n"); err = AudioSessionSetActive(true); if (err) { AUBIO_ERR("audio_unit: could not make session active after interruption (%d)\n", (int)err); goto fail; } err = AudioOutputUnitStart(this_unit); if (err) { AUBIO_ERR("audio_unit: failed starting unit (%d)\n", (int)err); goto fail; } } if (inInterruptionState == kAudioSessionBeginInterruption) { AUBIO_WRN("audio_unit: session interruption started\n"); err = AudioOutputUnitStop(this_unit); if (err) { AUBIO_ERR("audio_unit: could not stop unit at interruption (%d)\n", (int)err); goto fail; } err = AudioSessionSetActive(false); if (err) { AUBIO_ERR("audio_unit: could not make session inactive after interruption (%d)\n", (int)err); goto fail; } } fail: return; }
aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s, uint_t channels) { aubio_pvoc_t * pv = AUBIO_NEW(aubio_pvoc_t); if (win_s < 2*hop_s) { AUBIO_ERR("Hop size bigger than half the window size!\n"); AUBIO_ERR("Resetting hop size to half the window size.\n"); hop_s = win_s / 2; } if (hop_s < 1) { AUBIO_ERR("Hop size is smaller than 1!\n"); AUBIO_ERR("Resetting hop size to half the window size.\n"); hop_s = win_s / 2; } pv->fft = new_aubio_mfft(win_s,channels); /* remember old */ pv->data = new_fvec (win_s, channels); pv->synth = new_fvec (win_s, channels); /* new input output */ pv->dataold = new_fvec (win_s-hop_s, channels); pv->synthold = new_fvec (win_s-hop_s, channels); pv->w = AUBIO_ARRAY(smpl_t,win_s); aubio_window(pv->w,win_s,aubio_win_hanningz); pv->channels = channels; pv->hop_s = hop_s; pv->win_s = win_s; return pv; }
aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s) { aubio_pvoc_t * pv = AUBIO_NEW(aubio_pvoc_t); /* if (win_s < 2*hop_s) { AUBIO_WRN("Hop size bigger than half the window size!\n"); } */ if (hop_s < 1) { AUBIO_ERR("Hop size is smaller than 1!\n"); AUBIO_ERR("Resetting hop size to half the window size.\n"); hop_s = win_s / 2; } pv->fft = new_aubio_fft (win_s); /* remember old */ pv->data = new_fvec (win_s); pv->synth = new_fvec (win_s); /* new input output */ pv->dataold = new_fvec (win_s-hop_s); pv->synthold = new_fvec (win_s-hop_s); pv->w = new_aubio_window ("hanningz", win_s); pv->hop_s = hop_s; pv->win_s = win_s; return pv; }
OSStatus audio_unit_set_audio_session_category(bool has_input, bool verbose) { //if we have input, set the session category accordingly OSStatus err = 0; UInt32 category; if (has_input) { category = kAudioSessionCategory_PlayAndRecord; if (verbose) AUBIO_MSG("audio_unit: setting category to PlayAndRecord\n"); } else { category = kAudioSessionCategory_MediaPlayback; if (verbose) AUBIO_MSG("audio_unit: setting category to MediaPlayback\n"); } err = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category); if (err) { AUBIO_ERR("audio_unit: could not set audio category\n"); } // Audiob.us style UInt32 allowMixing = 1; AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof (allowMixing), &allowMixing); if (err) { AUBIO_ERR("audio_unit: could not set audio session to mix with others\n"); } return err; }
aubio_filterbank_t * new_aubio_filterbank (uint_t n_filters, uint_t win_s) { /* allocate space for filterbank object */ aubio_filterbank_t *fb = AUBIO_NEW (aubio_filterbank_t); if ((sint_t)n_filters <= 0) { AUBIO_ERR("filterbank: n_filters should be > 0, got %d\n", n_filters); goto fail; } if ((sint_t)win_s <= 0) { AUBIO_ERR("filterbank: win_s should be > 0, got %d\n", win_s); goto fail; } fb->win_s = win_s; fb->n_filters = n_filters; /* allocate filter tables, a matrix of length win_s and of height n_filters */ fb->filters = new_fmat (n_filters, win_s / 2 + 1); fb->norm = 1; fb->power = 1; return fb; fail: AUBIO_FREE (fb); return NULL; }
void fmat_copy(fmat_t *s, fmat_t *t) { uint_t i; #if !HAVE_MEMCPY_HACKS uint_t j; #endif if (s->height != t->height) { AUBIO_ERR("trying to copy %d rows to %d rows \n", s->height, t->height); return; } if (s->length != t->length) { AUBIO_ERR("trying to copy %d columns to %d columns\n", s->length, t->length); return; } #if HAVE_MEMCPY_HACKS for (i=0; i< s->height; i++) { memcpy(t->data[i], s->data[i], t->length * sizeof(smpl_t)); } #else for (i=0; i< t->height; i++) { for (j=0; j< t->length; j++) { t->data[i][j] = s->data[i][j]; } } #endif }
int main (void) { fprintf(stdout, "### testing normal logging\n"); AUBIO_ERR("testing normal AUBIO_LOG_ERR\n"); AUBIO_WRN("testing normal AUBIO_LOG_WRN\n"); AUBIO_MSG("testing normal AUBIO_LOG_MSG\n"); AUBIO_DBG("testing normal AUBIO_LOG_DBG\n"); fprintf(stdout, "### testing with one custom function\n"); aubio_log_set_function(logging, (void *)hdr); AUBIO_ERR("testing recustom AUBIO_LOG_ERR\n"); AUBIO_WRN("testing recustom AUBIO_LOG_WRN\n"); AUBIO_MSG("testing recustom AUBIO_LOG_MSG\n"); AUBIO_DBG("testing recustom AUBIO_LOG_DBG\n"); fprintf(stdout, "### testing resetted logging\n"); aubio_log_reset(); AUBIO_ERR("testing uncustom AUBIO_LOG_ERR\n"); AUBIO_WRN("testing uncustom AUBIO_LOG_WRN\n"); AUBIO_MSG("testing uncustom AUBIO_LOG_MSG\n"); AUBIO_DBG("testing uncustom AUBIO_LOG_DBG\n"); fprintf(stdout, "### testing per level customization\n"); aubio_log_set_level_function(AUBIO_LOG_ERR, logging, (void *)hdr2); aubio_log_set_level_function(AUBIO_LOG_WRN, logging, NULL); aubio_log_set_level_function(AUBIO_LOG_MSG, logging, (void *)hdr); AUBIO_ERR("testing custom AUBIO_LOG_ERR\n"); AUBIO_WRN("testing custom AUBIO_LOG_WRN with data=NULL\n"); AUBIO_MSG("testing custom AUBIO_LOG_MSG\n"); AUBIO_DBG("testing uncustomized AUBIO_LOG_DBG\n"); return 0; }
uint_t aubio_sink_sndfile_open(aubio_sink_sndfile_t *s) { /* set output format */ SF_INFO sfinfo; AUBIO_MEMSET(&sfinfo, 0, sizeof (sfinfo)); sfinfo.samplerate = s->samplerate; sfinfo.channels = s->channels; sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; /* try creating the file */ s->handle = sf_open (s->path, SFM_WRITE, &sfinfo); if (s->handle == NULL) { /* show libsndfile err msg */ AUBIO_ERR("sink_sndfile: Failed opening %s. %s\n", s->path, sf_strerror (NULL)); return AUBIO_FAIL; } s->scratch_size = s->max_size*s->channels; /* allocate data for de/interleaving reallocated when needed. */ if (s->scratch_size >= MAX_SIZE * MAX_CHANNELS) { AUBIO_ERR("sink_sndfile: %d x %d exceeds maximum aubio_sink_sndfile buffer size %d\n", s->max_size, s->channels, MAX_CHANNELS * MAX_CHANNELS); return AUBIO_FAIL; } s->scratch_data = AUBIO_ARRAY(smpl_t,s->scratch_size); return AUBIO_OK; }
/** del_aubio_alsa_seq_driver */ int del_aubio_alsa_seq_driver(aubio_midi_driver_t* p) { aubio_alsa_seq_driver_t* dev; dev = (aubio_alsa_seq_driver_t*) p; if (dev == NULL) { return AUBIO_OK; } dev->status = AUBIO_MIDI_DONE; /* cancel the thread and wait for it before cleaning up */ if (dev->thread) { if (pthread_cancel(dev->thread)) { AUBIO_ERR( "Failed to cancel the midi thread"); return AUBIO_FAIL; } if (pthread_join(dev->thread, NULL)) { AUBIO_ERR( "Failed to join the midi thread"); return AUBIO_FAIL; } } if (dev->seq_port >= 0) { snd_seq_delete_simple_port (dev->seq_handle, dev->seq_port); } if (dev->seq_handle) { snd_seq_drain_output(dev->seq_handle); snd_seq_close(dev->seq_handle); } AUBIO_FREE(dev); return AUBIO_OK; }
void audio_unit_check_audio_route(aubio_audio_unit_t *o) { CFStringRef currentRoute; UInt32 val, thissize = sizeof(currentRoute); OSStatus err = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &thissize, ¤tRoute); if (err) { AUBIO_ERR("audio_unit: could not get current route\n"); goto fail; } else { char *route = (char *)CFStringGetCStringPtr ( currentRoute, kCFStringEncodingUTF8); if (route == NULL) { int bufferSize = 25; route = calloc(bufferSize, sizeof(char)); CFStringGetCString ( currentRoute, route, bufferSize, kCFStringEncodingUTF8); } if (o->verbose) { AUBIO_MSG ("audio_unit: current route is %s\n", route); } //free(route); } if( currentRoute ) { if( CFStringCompare( currentRoute, CFSTR("Headset"), 0 ) == kCFCompareEqualTo ) { val = kAudioSessionOverrideAudioRoute_None; } else if( CFStringCompare( currentRoute, CFSTR("Receiver" ), 0 ) == kCFCompareEqualTo ) { val = kAudioSessionOverrideAudioRoute_Speaker; } else if( CFStringCompare( currentRoute, CFSTR("ReceiverAndMicrophone" ), 0 ) == kCFCompareEqualTo ) { val = kAudioSessionOverrideAudioRoute_Speaker; } else if( CFStringCompare( currentRoute, CFSTR("SpeakerAndMicrophone" ), 0 ) == kCFCompareEqualTo ) { val = kAudioSessionOverrideAudioRoute_Speaker; } else if( CFStringCompare( currentRoute, CFSTR("HeadphonesAndMicrophone" ), 0 ) == kCFCompareEqualTo ) { val = kAudioSessionOverrideAudioRoute_None; } else if( CFStringCompare( currentRoute, CFSTR("HeadsetInOut" ), 0 ) == kCFCompareEqualTo ) { val = kAudioSessionOverrideAudioRoute_None; } else { val = kAudioSessionOverrideAudioRoute_None; } o->input_enabled = true; if (val == kAudioSessionOverrideAudioRoute_Speaker) { if (o->prevent_feedback) { o->input_enabled = false; if (o->verbose) { AUBIO_MSG ("audio_unit: disabling input to avoid feedback\n"); } } else { AUBIO_WRN ("audio_unit: input not disabled as prevent_feedback set to 0, risking feedback\n"); } } err = AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(UInt32), &val); if (err) { AUBIO_ERR("audio_unit: could not set session OverrideAudioRoute to Speaker\n"); } } fail: if ( currentRoute ) free((void*)currentRoute); return; }
aubio_jack_t * new_aubio_jack(uint_t ichan, uint_t ochan, aubio_process_func_t callback) { aubio_jack_t * jack_setup = aubio_jack_alloc (ichan, ochan); uint_t i; char * client_name = "aubio"; char name[64]; /* initial jack client setup */ if ((jack_setup->client = jack_client_new (client_name)) == 0) { AUBIO_ERR ("jack server not running?\n"); AUBIO_QUIT(AUBIO_FAIL); } /* set callbacks */ jack_set_process_callback (jack_setup->client, aubio_jack_process, (void*) jack_setup); jack_on_shutdown (jack_setup->client, aubio_jack_shutdown, (void*) jack_setup); /* register jack output ports */ for (i = 0; i < ochan; i++) { AUBIO_SPRINTF(name, "out_%d", i+1); AUBIO_MSG("%s\n", name); if ((jack_setup->oports[i] = jack_port_register (jack_setup->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == 0) { AUBIO_ERR("failed registering output port \"%s\"!\n", name); jack_client_close (jack_setup->client); AUBIO_QUIT(AUBIO_FAIL); } } /* register jack input ports */ for (i = 0; i < ichan; i++) { AUBIO_SPRINTF(name, "in_%d", i+1); AUBIO_MSG("%s\n", name); if ((jack_setup->iports[i] = jack_port_register (jack_setup->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == 0) { AUBIO_ERR("failed registering input port \"%s\"!\n", name); jack_client_close (jack_setup->client); AUBIO_QUIT(AUBIO_FAIL); } } /* set processing callback */ jack_setup->callback = callback; return jack_setup; }
aubio_audio_unit_t * new_aubio_audio_unit(uint_t samplerate, uint_t sw_input_channels, uint_t sw_output_channels, uint_t blocksize) { aubio_audio_unit_t * o = AUBIO_NEW(aubio_audio_unit_t); o->hw_output_channels = 2; o->hw_input_channels = 2; o->sw_output_channels = sw_output_channels; o->sw_input_channels = sw_input_channels; o->samplerate = samplerate; o->latency = PREFERRED_LATENCY; o->blocksize = blocksize; o->au_ios_start = 0; o->au_ios_end = 0; o->verbose = 0; o->input_enabled = true; o->prevent_feedback = 1; o->dio_error = 0; o->total_frames = 0; /* the integers coming from and to the audio unit */ o->au_ios_outbuf = AUBIO_ARRAY(SInt16, AU_IOS_MAX_FRAMES * o->hw_output_channels); o->au_ios_inbuf = AUBIO_ARRAY(SInt16, AU_IOS_MAX_FRAMES * o->hw_input_channels); /* the floats coming from and to the device callback */ o->output_frames = new_fmat(sw_output_channels, blocksize); o->input_frames = new_fmat(sw_input_channels, blocksize); /* check for some sizes */ if ( o->hw_output_channels != o->output_frames->height ) { AUBIO_ERR ("got hw_output_channels = %d, but output_frames has %d rows\n", o->hw_output_channels, o->output_frames->height); } if ( o->blocksize != o->output_frames->length ) { AUBIO_ERR ("got blocksize = %d, but output_frames has length %d\n", o->blocksize, o->output_frames->length); } if ( o->hw_input_channels != o->input_frames->height ) { AUBIO_ERR ("got hw_input_channels = %d, but input_frames has %d rows\n", o->hw_input_channels, o->input_frames->height); } if ( o->blocksize != o->input_frames->length ) { AUBIO_ERR ("got blocksize = %d, but input_frames has length %d\n", o->blocksize, o->input_frames->length); } return o; }
SInt32 audio_unit_get_route_change_reason(CFDictionaryRef routeChangeDic) { CFNumberRef routeChangeReasonRef = (CFNumberRef)CFDictionaryGetValue(routeChangeDic, CFSTR(kAudioSession_AudioRouteChangeKey_Reason)); SInt32 change_reason_number; CFNumberGetValue ( routeChangeReasonRef, kCFNumberSInt32Type, &change_reason_number); switch (change_reason_number) { case kAudioSessionRouteChangeReason_NewDeviceAvailable: AUBIO_MSG("audio_unit: route changed to NewDeviceAvailable\n"); break; case kAudioSessionRouteChangeReason_OldDeviceUnavailable: AUBIO_MSG("audio_unit: route changed to OldDeviceUnavailable\n"); break; case kAudioSessionRouteChangeReason_CategoryChange: AUBIO_MSG("audio_unit: route changed to CategoryChange\n"); audio_unit_get_audio_session_category(); break; case kAudioSessionRouteChangeReason_Override: AUBIO_MSG("audio_unit: route changed to Override\n"); break; case kAudioSessionRouteChangeReason_WakeFromSleep: AUBIO_MSG("audio_unit: route changed to WakeFromSleep\n"); break; case kAudioSessionRouteChangeReason_NoSuitableRouteForCategory: AUBIO_MSG("audio_unit: route changed to NoSuitableRouteForCategory\n"); break; case kAudioSessionRouteChangeReason_Unknown: default: AUBIO_ERR("audio_unit: route changed for an unknown reason!?\n"); break; } return change_reason_number; }
aubio_sink_sndfile_t * new_aubio_sink_sndfile(const char_t * path, uint_t samplerate) { aubio_sink_sndfile_t * s = AUBIO_NEW(aubio_sink_sndfile_t); s->max_size = MAX_SIZE; if (path == NULL) { AUBIO_ERR("sink_sndfile: Aborted opening null path\n"); return NULL; } if (s->path) AUBIO_FREE(s->path); s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1); strncpy(s->path, path, strnlen(path, PATH_MAX) + 1); s->samplerate = 0; s->channels = 0; // negative samplerate given, abort if ((sint_t)samplerate < 0) goto beach; // zero samplerate given. do not open yet if ((sint_t)samplerate == 0) return s; s->samplerate = samplerate; s->channels = 1; if (aubio_sink_sndfile_open(s) != AUBIO_OK) {; goto beach; } return s; beach: del_aubio_sink_sndfile(s); return NULL; }
aubio_wavetable_t *new_aubio_wavetable(uint_t samplerate, uint_t blocksize) { uint_t i = 0; aubio_wavetable_t *s = AUBIO_NEW(aubio_wavetable_t); if ((sint_t)samplerate <= 0) { AUBIO_ERR("Can not create wavetable with samplerate %d\n", samplerate); goto beach; } s->samplerate = samplerate; s->blocksize = blocksize; s->wavetable_length = WAVETABLE_LEN; s->wavetable = new_fvec(s->wavetable_length + 3); for (i = 0; i < s->wavetable_length; i++) { s->wavetable->data[i] = SIN(TWO_PI * i / (smpl_t) s->wavetable_length ); } s->wavetable->data[s->wavetable_length] = s->wavetable->data[0]; s->wavetable->data[s->wavetable_length + 1] = s->wavetable->data[1]; s->wavetable->data[s->wavetable_length + 2] = s->wavetable->data[2]; s->playing = 0; s->last_pos = 0.; s->freq = new_aubio_parameter( 0., s->samplerate / 2., 10 ); s->amp = new_aubio_parameter( 0., 1., 100 ); return s; beach: AUBIO_FREE(s); return NULL; }
void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s, uint_t multi) { if ( (multi != s->multi) || (s->avr == NULL) ) { int64_t input_layout = av_get_default_channel_layout(s->input_channels); uint_t output_channels = multi ? s->input_channels : 1; int64_t output_layout = av_get_default_channel_layout(output_channels); if (s->avr != NULL) { avresample_close( s->avr ); av_free ( s->avr ); s->avr = NULL; } AVAudioResampleContext *avr = s->avr; avr = avresample_alloc_context(); av_opt_set_int(avr, "in_channel_layout", input_layout, 0); av_opt_set_int(avr, "out_channel_layout", output_layout, 0); av_opt_set_int(avr, "in_sample_rate", s->input_samplerate, 0); av_opt_set_int(avr, "out_sample_rate", s->samplerate, 0); av_opt_set_int(avr, "in_sample_fmt", s->avCodecCtx->sample_fmt, 0); av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0); int err; if ( ( err = avresample_open(avr) ) < 0) { char errorstr[256]; av_strerror (err, errorstr, sizeof(errorstr)); AUBIO_ERR("source_avcodec: Could not open AVAudioResampleContext for %s (%s)\n", s->path, errorstr); //goto beach; return; } s->avr = avr; s->multi = multi; } }
/* Allocate memory for an onset detection */ aubio_onset_t * new_aubio_onset (const char_t * onset_mode, uint_t buf_size, uint_t hop_size, uint_t samplerate) { aubio_onset_t * o = AUBIO_NEW(aubio_onset_t); /* check parameters are valid */ if ((sint_t)hop_size < 1) { AUBIO_ERR("onset: got hop_size %d, but can not be < 1\n", hop_size); goto beach; } else if ((sint_t)buf_size < 2) { AUBIO_ERR("onset: got buffer_size %d, but can not be < 2\n", buf_size); goto beach; } else if (buf_size < hop_size) { AUBIO_ERR("onset: hop size (%d) is larger than win size (%d)\n", hop_size, buf_size); goto beach; } else if ((sint_t)samplerate < 1) { AUBIO_ERR("onset: samplerate (%d) can not be < 1\n", samplerate); goto beach; } /* store creation parameters */ o->samplerate = samplerate; o->hop_size = hop_size; /* allocate memory */ o->pv = new_aubio_pvoc(buf_size, o->hop_size); o->pp = new_aubio_peakpicker(); o->od = new_aubio_specdesc(onset_mode,buf_size); if (o->od == NULL) goto beach_specdesc; o->fftgrain = new_cvec(buf_size); o->desc = new_fvec(1); o->spectral_whitening = new_aubio_spectral_whitening(buf_size, hop_size, samplerate); /* initialize internal variables */ aubio_onset_set_default_parameters (o, onset_mode); aubio_onset_reset(o); return o; beach_specdesc: del_aubio_peakpicker(o->pp); del_aubio_pvoc(o->pv); beach: AUBIO_FREE(o); return NULL; }
/* Allocate memory for an onset detection */ aubio_onset_t * new_aubio_onset (const char_t * onset_mode, uint_t buf_size, uint_t hop_size, uint_t samplerate) { aubio_onset_t * o = AUBIO_NEW(aubio_onset_t); /* check parameters are valid */ if ((sint_t)hop_size < 1) { AUBIO_ERR("onset: got hop_size %d, but can not be < 1\n", hop_size); goto beach; } else if ((sint_t)buf_size < 2) { AUBIO_ERR("onset: got buffer_size %d, but can not be < 2\n", buf_size); goto beach; } else if (buf_size < hop_size) { AUBIO_ERR("onset: hop size (%d) is larger than win size (%d)\n", buf_size, hop_size); goto beach; } else if ((sint_t)samplerate < 1) { AUBIO_ERR("onset: samplerate (%d) can not be < 1\n", samplerate); goto beach; } /* store creation parameters */ o->samplerate = samplerate; o->hop_size = hop_size; /* allocate memory */ o->pv = new_aubio_pvoc(buf_size, o->hop_size); o->pp = new_aubio_peakpicker(); o->od = new_aubio_specdesc(onset_mode,buf_size); o->fftgrain = new_cvec(buf_size); o->desc = new_fvec(1); /* set some default parameter */ aubio_onset_set_threshold (o, 0.3); aubio_onset_set_delay(o, 4.3 * hop_size); aubio_onset_set_minioi_ms(o, 20.); aubio_onset_set_silence(o, -70.); /* initialize internal variables */ o->last_onset = 0; o->total_frames = 0; return o; beach: AUBIO_FREE(o); return NULL; }
uint_t aubio_sampler_load( aubio_sampler_t * o, char_t * uri ) { if (o->source) del_aubio_source(o->source); o->uri = uri; o->source = new_aubio_source(uri, o->samplerate, o->blocksize); if (o->source) return 0; AUBIO_ERR("sampler: failed loading %s", uri); return 1; }