int inp_alsa_upload (VisPluginData *plugin, VisAudio *audio) { int16_t data[PCM_BUF_SIZE]; alsaPrivate *priv = NULL; int rcnt; visual_return_val_if_fail(audio != NULL, -1); visual_return_val_if_fail(plugin != NULL, -1); priv = visual_object_get_private (VISUAL_OBJECT (plugin)); visual_return_val_if_fail(priv != NULL, -1); #if 0 { /* DEBUG STUFF, REMOVE IN RELEASE FIXME FIXME XXX TODO WHATEVER */ VisBuffer buffer; visual_buffer_init (&buffer, data, 512, NULL); for (i = 0; i < 16; i++) { visual_audio_samplepool_input (audio->samplepool, &buffer, VISUAL_AUDIO_SAMPLE_RATE_44100, VISUAL_AUDIO_SAMPLE_FORMAT_S16, VISUAL_AUDIO_SAMPLE_CHANNEL_STEREO); } return 0; } #endif do { rcnt = snd_pcm_readi(priv->chandle, data, PCM_BUF_SIZE / 2); if (rcnt > 0) { VisBuffer buffer; visual_buffer_init (&buffer, data, rcnt, NULL); visual_audio_samplepool_input (audio->samplepool, &buffer, VISUAL_AUDIO_SAMPLE_RATE_44100, VISUAL_AUDIO_SAMPLE_FORMAT_S16, VISUAL_AUDIO_SAMPLE_CHANNEL_STEREO); } if (rcnt < 0) { if (rcnt == -EPIPE) { visual_log(VISUAL_LOG_WARNING, _("ALSA: Buffer Overrun")); if (snd_pcm_prepare(priv->chandle) < 0) { visual_log(VISUAL_LOG_ERROR, _("Failed to prepare interface")); return(-1); } } } } while (rcnt > 0); return 0; }
static int upload_callback( VisInput*, VisAudio *audio, void* ) { VisBuffer buf; visual_buffer_init( &buf, pcm_data, 1024, 0 ); visual_audio_samplepool_input( audio->samplepool, &buf, VISUAL_AUDIO_SAMPLE_RATE_44100, VISUAL_AUDIO_SAMPLE_FORMAT_S16, VISUAL_AUDIO_SAMPLE_CHANNEL_STEREO ); return 0; }
static void update_lv(void * data, gavl_audio_frame_t * frame) { lv_priv_t * priv; VisBuffer buffer; priv = (lv_priv_t*)data; visual_buffer_init(&buffer, frame->samples.s_16, frame->valid_samples * 2, NULL); visual_audio_samplepool_input(priv->audio->samplepool, &buffer, VISUAL_AUDIO_SAMPLE_RATE_44100, VISUAL_AUDIO_SAMPLE_FORMAT_S16, VISUAL_AUDIO_SAMPLE_CHANNEL_STEREO); visual_audio_analyze(priv->audio); }
int visual_audio_analyze (VisAudio *audio) { short pcm[3][1024]; #if 0 float temp_out[256]; float temp_audio[2][512]; double scale; int i, j, y; #endif visual_return_val_if_fail (audio != NULL, -VISUAL_ERROR_AUDIO_NULL); /* Load the pcm data */ #if 0 for (i = 0; i < 512; i++) { audio->pcm[0][i] = audio->plugpcm[0][i]; audio->pcm[1][i] = audio->plugpcm[1][i]; audio->pcm[2][i] = (audio->plugpcm[0][i] + audio->plugpcm[1][i]) >> 1; } #endif /* -------------------------------- audio pool testing */ { /* VisBuffer *buffer = visual_buffer_new_allocate (sizeof (int16_t) * 512, visual_buffer_destroyer_free); VisTime timestamp; VisAudioSample *sample; visual_mem_copy (visual_buffer_get_data (buffer), audio->plugpcm[2], sizeof (int16_t) * 512); visual_time_get (×tamp); sample = visual_audio_sample_new (buffer, ×tamp, VISUAL_AUDIO_SAMPLE_RATE_44100, VISUAL_AUDIO_SAMPLE_FORMAT_S8); visual_audio_samplepool_add (audio->samplepool, sample, "front"); */ VisAudioSamplePoolChannel *channel; VisBuffer buffer; visual_audio_samplepool_flush_old (audio->samplepool); channel = visual_audio_samplepool_get_channel (audio->samplepool, VISUAL_AUDIO_CHANNEL_LEFT); if (channel != 0) { visual_buffer_init (&buffer, pcm[0], 1024, NULL); // printf ("--channel debug: %s: %d\n", channel->channelid, visual_ringbuffer_get_size (channel->samples)); visual_ringbuffer_get_data (channel->samples, &buffer, 1024); visual_object_unref (VISUAL_OBJECT (&buffer)); } channel = visual_audio_samplepool_get_channel (audio->samplepool, VISUAL_AUDIO_CHANNEL_RIGHT); if (channel != 0) { visual_buffer_init (&buffer, pcm[1], 1024, NULL); // printf ("--channel debug: %s: %d\n", channel->channelid, visual_ringbuffer_get_size (channel->samples)); visual_ringbuffer_get_data (channel->samples, &buffer, 1024); visual_object_unref (VISUAL_OBJECT (&buffer)); } } /* /-------------------------------- audio pool testing */ // for (i = 0; i < 512; i++) { // audio->pcm[2][i] = (audio->pcm[0][i] + audio->pcm[1][i]) >> 1; // } #if 0 /* Convert int16_t audio to float audio, (won't be needed when the rest of the new audio * core lands). */ for (i = 0; i < 512; i++) { temp_audio[0][i] = audio->pcm[0][i]; temp_audio[1][i] = audio->pcm[1][i]; } /* Fourier analyze the pcm data */ visual_fourier_perform (audio->fourier, temp_audio[0], temp_out); for (i = 0; i < 256; i++) audio->freq[0][i] = temp_out[i] * 50; visual_fourier_perform (audio->fourier, temp_audio[1], temp_out); for (i = 0; i < 256; i++) audio->freq[1][i] = temp_out[i] * 50; /* Average channel */ for (i = 0; i < 256; i++) audio->freq[2][i] = (audio->freq[0][i] + audio->freq[1][i]) >> 1; /* Normalized frequency analyzer */ /** @todo FIXME Not sure if this is totally correct */ for (i = 0; i < 3; i++) { for (j = 0; j < 256; j++) { /* (Height / log (256)) */ scale = 256 / log (256); y = audio->freq[i][j]; y = log (y) * scale; if (y < 0) y = 0; audio->freqnorm[i][j] = y; } } #endif #if 0 /* BPM stuff, used for the audio energy only right now */ for (i = 1023; i > 0; i--) { visual_mem_copy (&audio->bpmhistory[i], &audio->bpmhistory[i - 1], 6 * sizeof (short int)); visual_mem_copy (&audio->bpmdata[i], &audio->bpmdata[i - 1], 6 * sizeof (short int)); } /* Calculate the audio energy */ audio->energy = 0; for (i = 0; i < 6; i++) { audio->bpmhistory[0][i] = audio_band_total (audio, i * 2, (i * 2) + 3); audio->bpmenergy[i] = audio_band_energy (audio, i, 10); audio->bpmdata[0][i] = audio->bpmhistory[0][i] - audio->bpmenergy[i]; audio->energy += audio_band_energy(audio, i, 50); } audio->energy >>= 7; if (audio->energy > 100) audio->energy = 100; #endif return VISUAL_OK; }
int visual_ringbuffer_get_data_offset (VisRingBuffer *ringbuffer, VisBuffer *data, int offset, int nbytes) { VisListEntry *le = NULL; VisRingBufferEntry *entry; int curposition = 0; int curoffset = 0; int positioncorr = 0; int startat = 0; int buffercorr = 0; visual_log_return_val_if_fail (ringbuffer != NULL, -VISUAL_ERROR_RINGBUFFER_NULL); visual_log_return_val_if_fail (data != NULL, -VISUAL_ERROR_BUFFER_NULL); /* Fixate possible partial buffer */ if (offset > 0) startat = fixate_with_partial_data_request (ringbuffer, data, offset, nbytes, &buffercorr); curposition = buffercorr; /* Buffer fixated with partial segment, request the other segments */ while (curposition < nbytes) { int lindex = 0; le = NULL; /* return immediately if there are no elements in the list */ if(visual_list_count(ringbuffer->entries) == 0) return VISUAL_OK; while ((entry = visual_list_next (ringbuffer->entries, &le)) != NULL) { VisBuffer *tempbuf; lindex++; /* Skip to the right offset buffer fragment */ if (lindex <= startat) continue; if (entry->type == VISUAL_RINGBUFFER_ENTRY_TYPE_BUFFER) { tempbuf = entry->buffer; } else if (entry->type == VISUAL_RINGBUFFER_ENTRY_TYPE_FUNCTION) { /* Will bail out through visual_error_raise(), this is fatal, let's not try to * recover, it's a very obvious bug in the software */ if (entry->datafunc == NULL) { visual_log (VISUAL_LOG_ERROR, _("No VisRingBufferDataFunc data provider function set on " "type VISUAL_RINGBUFFER_ENTRY_TYPE_FUNCTION")); return -VISUAL_ERROR_IMPOSSIBLE; } tempbuf = entry->datafunc (ringbuffer, entry); } if (curposition + visual_buffer_get_size (tempbuf) > nbytes) { VisBuffer buf; visual_buffer_init (&buf, visual_buffer_get_data (tempbuf), nbytes - curposition, NULL); visual_buffer_put (data, &buf, curposition); if (entry->type == VISUAL_RINGBUFFER_ENTRY_TYPE_FUNCTION) visual_object_unref (VISUAL_OBJECT (tempbuf)); return VISUAL_OK; } visual_buffer_put (data, tempbuf, curposition); curposition += visual_buffer_get_size (tempbuf); if (entry->type == VISUAL_RINGBUFFER_ENTRY_TYPE_FUNCTION) visual_object_unref (VISUAL_OBJECT (tempbuf)); /* Filled without room for partial buffer addition */ if (curposition == nbytes) return VISUAL_OK; } startat = 0; } return VISUAL_OK; }