/** * Contiguous Fetch. * The simple API is blocking, which is perfect for tracter. Fab. */ Tracter::SizeType Tracter::PulseAudioSource::ContiguousFetch( IndexType iIndex, SizeType iLength, SizeType iOffset ) { if (mMaxIndex) if (iIndex > mMaxIndex) return 0; /* I'm assuming that it reads a whole buffer-full here */ int error; int ret = pa_simple_read( mHandle, GetPointer(iOffset), iLength * sizeof(float), &error ); if (ret < 0) throw Exception("%s: Failed to read %d samples. %s", mObjectName, iLength, pa_strerror(error)); if (mMaxIndex) if (iIndex + iLength > mMaxIndex) return mMaxIndex - iIndex; return iLength; }
int main(int argc, char*argv[]) { /* The sample type to use */ static const pa_sample_spec ss = { .format = PA_SAMPLE_S16LE, .rate = 44100, .channels = 2 }; pa_simple *s = NULL; int ret = 1; int error; /* Create the recording stream */ if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) { fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error)); goto finish; } for (;;) { uint8_t buf[BUFSIZE]; /* Record some data ... */ if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) { fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error)); goto finish; } /* And write it to STDOUT */ if (loop_write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf)) { fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno)); goto finish; } } ret = 0; finish: if (s) pa_simple_free(s); return ret; }
void MediaRecorder::RecordingThread() { int error; while ( run ) { printf("Read %d samples\n",actx->frame_size*2); short * buf = new short[actx->frame_size*2]; int ret = pa_simple_read(s,buf,actx->frame_size*4,&error); if ( ret < 0 ) { printf("Sound crashed\n"); delete[] buf; break; } for ( int i = 0; i < actx->frame_size*2; i++ ) { buf[i] = short(float(buf[i])*0.8); } fwrite(buf,sizeof(short)*actx->frame_size*2,1,debug_samples_out); pthread_mutex_lock(&sound_buffer_lock); sound_buffers.push_back(buf); pthread_mutex_unlock(&sound_buffer_lock); } }
int _recordSound(char *buf, int size) { int error; if (pa_simple_read(sr, buf, (size_t) size, &error) < 0) return error; return 0; }
static void *pulse_audio_update_recorder(ALLEGRO_THREAD *t, void *data) { ALLEGRO_AUDIO_RECORDER *r = (ALLEGRO_AUDIO_RECORDER *) data; PULSEAUDIO_RECORDER *pa = (PULSEAUDIO_RECORDER *) r->extra; ALLEGRO_EVENT user_event; uint8_t *null_buffer; unsigned int fragment_i = 0; null_buffer = al_malloc(1024); if (!null_buffer) { ALLEGRO_ERROR("Unable to create buffer for draining PulseAudio.\n"); return NULL; } while (!al_get_thread_should_stop(t)) { al_lock_mutex(r->mutex); if (!r->is_recording) { /* Even if not recording, we still want to read from the PA server. Otherwise it will buffer everything and spit it all out whenever the recording resumes. */ al_unlock_mutex(r->mutex); pa_simple_read(pa->s, null_buffer, 1024, NULL); } else { ALLEGRO_AUDIO_RECORDER_EVENT *e; al_unlock_mutex(r->mutex); if (pa_simple_read(pa->s, r->fragments[fragment_i], r->fragment_size, NULL) >= 0) { user_event.user.type = ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT; e = al_get_audio_recorder_event(&user_event); e->buffer = r->fragments[fragment_i]; e->samples = r->samples; al_emit_user_event(&r->source, &user_event, NULL); if (++fragment_i == r->fragment_count) { fragment_i = 0; } } } } al_free(null_buffer); return NULL; };
bool ManglerPulse::read(uint8_t *buf) {/*{{{*/ if (!pulse_stream) { return false; } if (pa_simple_read(pulse_stream, buf, buffer_attr.fragsize, &pulse_error) < 0) { fprintf(stderr, "pulse: pa_simple_read() failed: %s\n", pa_strerror(pulse_error)); return false; } return true; }/*}}}*/
static int pulse_input(struct iaxc_audio_driver *d, void *samples, int *nSamples) { int error; pa_simple *p = (pa_simple*)(d->priv); if(pa_simple_read(p, samples, *nSamples*sizeof(short) , &error) <0) { fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error)); } // always return 0, since pulse gives us a continuos stream of data return 0; }
int pulseaudio_read(pa_simple *s, short *buffer, int count){ int number_read; int channels; if (sound_channels == SOUND_CHANNELS_MONO) channels = 1; else channels = 2; number_read = pa_simple_read(s,buffer,(size_t)(count * sizeof(short) * channels) ,NULL); if(number_read < 0) return -1; return count; }
static void input_sound(unsigned int sample_rate, unsigned int overlap, const char *ifname) { short buffer[8192]; float fbuf[16384]; unsigned int fbuf_cnt = 0; int i; int error; short *sp; // Init stuff from pa.org pa_simple *s; pa_sample_spec ss; ss.format = PA_SAMPLE_S16NE; ss.channels = 1; ss.rate = sample_rate; /* Create the recording stream */ if (!(s = pa_simple_new(NULL, "multimonNG", PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) { fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error)); exit(4); } for (;;) { i = pa_simple_read(s, sp = buffer, sizeof(buffer), &error); if (i < 0 && errno != EAGAIN) { perror("read"); fprintf(stderr, "error 1\n"); exit(4); } i=sizeof(buffer); if (!i) break; if (i > 0) { for (; i >= sizeof(buffer[0]); i -= sizeof(buffer[0]), sp++) fbuf[fbuf_cnt++] = (*sp) * (1.0/32768.0); if (i) fprintf(stderr, "warning: noninteger number of samples read\n"); if (fbuf_cnt > overlap) { process_buffer(fbuf, fbuf_cnt-overlap); memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0])); fbuf_cnt = overlap; } } } pa_simple_free(s); }
bool vis::PulseAudioSource::read(pcm_stereo_sample *buffer, const uint32_t buffer_size) { size_t buffer_size_bytes = static_cast<size_t>(sizeof(pcm_stereo_sample) * buffer_size); #ifdef _ENABLE_PULSE if (m_pulseaudio_simple == nullptr) { open_pulseaudio_source(static_cast<uint32_t>(buffer_size_bytes)); } if (m_pulseaudio_simple != nullptr) { // zero out buffer memset(buffer, 0, buffer_size_bytes); int32_t error_code; /* Record some data ... */ auto return_code = pa_simple_read(m_pulseaudio_simple, buffer, buffer_size_bytes, &error_code); if (return_code < 0) { VIS_LOG(vis::LogLevel::WARN, "Could not finish reading pulse audio " "stream buffer, bytes read: %d buffer " "size: ", return_code, buffer_size_bytes); // zero out buffer memset(buffer, 0, buffer_size_bytes); pa_simple_free(m_pulseaudio_simple); m_pulseaudio_simple = nullptr; return false; } // Success fully read entire buffer return true; } #endif // zero out buffer memset(buffer, 0, buffer_size_bytes); return false; }
void init(void) { int error; /* The sample type to use */ static const pa_sample_spec ss = { .format = PA_SAMPLE_S16NE, // signed 16bits , Native endian .rate = 44100, .channels = 1 }; /* Create the recording stream */ if (!(s = pa_simple_new(NULL, "USB VUmeter", PA_STREAM_RECORD, DEVICE, "record", &ss, NULL, NULL, &error))) { fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error)); } printf("%d\n",sizeof(short)); } float value (void) { int error; uint8_t buf[BUFSIZE]; int16_t *pbuf = (int16_t*)buf; // 16bit signed float percent; static double max_level=0, min_level=10000; double nrj=0; /* Record some data ... */ if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) { fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error)); } while (pbuf < (int16_t*)buf+sizeof(buf)) { nrj += (*pbuf) * (*pbuf); pbuf++; // printf("%02X ",buf[i]); } nrj = sqrt(nrj)/(sizeof(buf)); if(nrj > max_level) max_level = nrj; if(nrj < min_level) min_level = nrj; percent = (float) 100 * (nrj-min_level) / (max_level-min_level); // printf ("min:%f, nrj:%f, max:%f, %%:%f\n",min_level, nrj, max_level, nrj / max_level); return percent; }
static gavl_source_status_t read_func_pulse(void * p, gavl_audio_frame_t ** frame) { bg_pa_t * priv; int error = 0; gavl_audio_frame_t * f = *frame; priv = p; if(pa_simple_read(priv->pa, f->samples.u_8, priv->block_align * priv->format.samples_per_frame, &error) < 0) { return GAVL_SOURCE_EOF; } f->valid_samples = priv->format.samples_per_frame; return GAVL_SOURCE_OK; }
int32 ad_read(ad_rec_t * r, int16 * buf, int32 max) { int error; if (!r->recording) return AD_EOF; if (max > 2048) { max = 2048; } if (pa_simple_read(r->pa, (void*)buf, max * 2, &error) < 0) { fprintf(stderr, "Failed to read speech: %s\n", pa_strerror(error)); } return max; }
static ssize_t pulse_read (sw_handle * handle, float * buf, size_t count) { struct pa_simple * pa ; int error; size_t byte_count; if ((pa = (struct pa_simple *)handle->custom_data) == NULL) return 0; byte_count = count * sizeof (float); if (pa_simple_read(pa, buf, byte_count, &error) < 0) { fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error)); return 0; } return 1; }
int main(int argc, char*argv[]) { /* The sample type to use */ static const pa_sample_spec ss = { .format = PA_SAMPLE_S16LE, .rate = 44100, .channels = 2 }; pa_simple *inStream = NULL; pa_simple *outStream = NULL; int ret = 1; int error; /* Create the recording stream */ if (!(inStream = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) { fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error)); goto finish; } /* Create the playback stream */ if (!(outStream = pa_simple_new(NULL, argv[0], PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error))) { fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error)); goto finish; } for (;;) { uint8_t buf[BUFSIZE]; /* Record some data ... */ if (pa_simple_read(inStream, buf, sizeof(buf), &error) < 0) { fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error)); goto finish; } if (pa_simple_write(outStream, buf, sizeof(buf), &error) < 0) { fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error)); goto finish; } } ret = 0; finish: if (inStream) pa_simple_free(inStream); if (outStream) pa_simple_free(outStream); return ret; }
struct pa_simple *pulseaudio_begin(void) { int error; struct pa_simple *s; static const pa_sample_spec ss = { .format = PA_SAMPLE_FLOAT32LE, .rate = RATE, .channels = 1 }; static const pa_buffer_attr sb = { .maxlength = N * 2, .fragsize = N * 2 }; if(!(s = pa_simple_new(NULL, "paSpec", PA_STREAM_RECORD, NULL, "input stream", &ss, NULL, &sb, &error))) { printf("Error: pulseaudio: pa_simple_new() failed: %s\n", pa_strerror(error)); clean_screen(); exit(1); } return s; } void pulseaudio_end(struct pa_simple *s) { if(s != NULL) { pa_simple_free(s); } } void pulseaudio_read(struct pa_simple *s, float *buf, int sampnum) { int error; if(pa_simple_read(s, buf, sampnum * sizeof(float), &error) < 0) { printf("Error: pa_simple_read() failed: %s\n", pa_strerror(error)); pulseaudio_end(s); exit(1); } } void prnt(char hah, unsigned int cnt, unsigned int s, unsigned int sh) { while(cnt--) { printf("\e[%i;%iH%c", sh - cnt, s, hah); } }
int adin_read(SP16 * buf, int sampnum) { int cnt, bufsize; bufsize = sampnum * sizeof(SP16); if (bufsize > BUFSIZE) bufsize = BUFSIZE; SP16 inbuf[bufsize]; if (pa_simple_read(r, inbuf, bufsize, &errorpa) < 0) { printf("Error: adin_pulseaudio: pa_simple_read() failed: %s\n", pa_strerror(errorpa)); return (-2); } libpd_process_short(4, inbuf, buf); cnt = bufsize / sizeof(SP16); return(cnt); }
int main(int argc, char *argv[]) { pa_simple *pa = NULL; pa_sample_spec paspec = { PA_SAMPLE_S16NE, 32000, 1 }; void *state = NULL; SpeexBits bits; int quality = 3; int complexity = 1; int framesize = 0; int16_t *framein = NULL; char *frameout = NULL; int len; do { if(!(pa = pa_simple_new(NULL, "", PA_STREAM_RECORD, NULL, "", &paspec, NULL, NULL, NULL))) break; speex_bits_init(&bits); if(!(state = speex_encoder_init(&speex_uwb_mode))) break; if(speex_encoder_ctl(state, SPEEX_SET_QUALITY, &quality)) break; if(speex_encoder_ctl(state, SPEEX_SET_COMPLEXITY, &complexity)) break; if(speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &framesize) || !framesize) break; if(!(framein = calloc(framesize, sizeof(int16_t)))) break; if(!(frameout = calloc(framesize, sizeof(int16_t)))) break; while(1) { if(pa_simple_read(pa, framein, framesize * sizeof(int16_t), NULL)) break; speex_bits_reset(&bits); speex_encode_int(state, framein, &bits); if(!(len = speex_bits_write(&bits, frameout, framesize * sizeof(int16_t)))) break; fwrite(&len, sizeof(int), 1, stdout); fwrite(frameout, 1, len, stdout); } } while(0); if(framein) free(framein); if(frameout) free(frameout); if(state) speex_encoder_destroy(state); speex_bits_destroy(&bits); if(pa) pa_simple_free(pa); return 0; }
int main() { pa_sample_spec ss; ss.format = PA_SAMPLE_S16LE; ss.channels = 1; ss.rate = 96000; pa_buffer_attr ba; ba.maxlength = (uint32_t)-1; ba.tlength = 0; ba.prebuf = (uint32_t)-1; ba.minreq = (uint32_t)-1; ba.fragsize = (uint32_t)-1; pa_simple* s_rec = pa_simple_new(NULL, "echo", PA_STREAM_RECORD, NULL, "Record", &ss, NULL, &ba, NULL); pa_simple* s_play = pa_simple_new(NULL, "echo", PA_STREAM_PLAYBACK, NULL, "Echo", &ss, NULL, &ba, NULL); if (!s_rec) { fprintf(stderr, "Pulse rec failed.\n"); return 1; } if (!s_play) { fprintf(stderr, "Pulse play failed.\n"); return 1; } char buffer[sizeof(short) * 128]; for (;;) { pa_simple_read(s_rec, buffer, sizeof(buffer), NULL); pa_simple_write(s_play, buffer, sizeof(buffer), NULL); } return 0; }
void audio_trigger(context_t *context) { int input_fd = -1; static const pa_sample_spec ss = { .format = PA_SAMPLE_S16LE, .rate = 44100, .channels = 1 }; int error; daemon_log(LOG_INFO, "Trigger %s", context->shush_filename); if (context->points_threshold < 0) { daemon_log(LOG_INFO, "Threshold below 0, not triggering sound"); } daemon_log(LOG_INFO, "Opening %s for output", context->output_device ?: "default sink"); pa_simple *pa_output = pa_simple_new( NULL, "shusherd", PA_STREAM_PLAYBACK, context->output_device, "playback", &ss, NULL, NULL, &error); if (!pa_output) { daemon_log(LOG_ERR, "pa_simple_new failed: %s", pa_strerror(error)); goto finish; } input_fd = open(context->shush_filename, O_RDONLY); if (input_fd < 0) { daemon_log(LOG_ERR, "Error reading %s: %s", context->shush_filename, strerror(errno)); goto finish; } for (;;) { uint8_t buf[BUFSIZE]; ssize_t r; r = read(input_fd, buf, sizeof(buf)); if (r < 0) { daemon_log(LOG_ERR, "read() failed: %s", strerror(errno)); goto finish; } if (r == 0) goto finish; if (pa_simple_write(pa_output, buf, (size_t) r, &error) < 0) { daemon_log(LOG_ERR, "pa_simple_write() failed: %s", pa_strerror(errno)); goto finish; } } if (pa_simple_drain(pa_output, &error) < 0) { daemon_log(LOG_ERR, "pa_simple_drain() failed: %s", pa_strerror(errno)); goto finish; } finish: if (input_fd > 0) close(input_fd); if (pa_output) pa_simple_free(pa_output); } void *audio_loop(void *context_p) { context_t *context = (context_t *)context_p; time_t t = time(NULL); double loudness; double points = 0.0; int error; //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); daemon_log(LOG_INFO, "Starting listening..."); const short buf[BUFSIZE/2]; int bytes = 0; int trigger = 0; int latest_trigger_time = 0; while (context->enable_processing) { if ((bytes = pa_simple_read(context->pa_input, (void *)buf, sizeof(buf), &error)) < 0) { daemon_log(LOG_ERR, "pa_simple_read failed: %s", pa_strerror(error)); assert(0); } if ((time(NULL) - latest_trigger_time) < context->cooldown) { continue; } ebur128_add_frames_short(context->ebur128_state, buf, sizeof(buf)/2); if ((time(NULL) - t) > SAMPLE_TIME) { t = time(NULL); ebur128_loudness_shortterm(context->ebur128_state, &loudness); points += 100 - fabs(loudness); daemon_log(LOG_INFO, "Points: %f (%d) (%f)", points, context->points_threshold, loudness); if (points > context->points_threshold) { trigger = 1; } else { points *= context->decay; } } if (trigger) { latest_trigger_time = time(NULL); audio_trigger(context); points = 0; trigger = 0; daemon_log(LOG_INFO, "Waiting %d seconds before listening again", context->cooldown); } } daemon_log(LOG_INFO, "Stopped listening..."); return 0; }
int main(int argc, char **argv) { modulation mod = AM; int genwav = 0; int test = 0; int chat = 0; static struct option long_options[] = { {"modulation", required_argument, 0, 'm'}, {"genwav", no_argument, 0, 'g'}, {"test", no_argument, 0, 't'}, {"chat", no_argument, 0, 'c'}, {0, 0, 0, 0} }; int c; int option_index = 0; do { c = getopt_long (argc, argv, "m:gt", long_options, &option_index); switch (c) { case 0: break; case 'm': if (strcmp(optarg, "AM") == 0) { mod = AM; break; } if (strcmp(optarg, "FM") == 0) { mod = FM; break; } fprintf(stderr, "Error: Invalid modulation\n"); return 1; case 't': test = 1; break; case 'g': genwav = 1; break; case 'c': chat = 1; break; case -1: break; default: return 1; break; } } while (c != -1); if (!(test || chat || genwav)) { fprintf(stderr, "Error: You must suply an action\n"); return 1; } int *vbuf; frame *msg; int i; if (genwav || test) { vbuf = get_fdata(PING_STR, strlen(PING_STR), mod); if (chk_wav_data(vbuf, &msg, mod)) printf("Info: PCM data is ok.\n"); else { fprintf(stderr, "Error: PCM data can not be read\n"); for (i = 0; i < FRAME_SIZE; i++) fprintf(stderr, "%hhx", ((char *) msg)[i]); fprintf(stderr, "\n"); } } if (genwav) { FILE *am = fopen("am.wav", "w"); if (am == NULL) { printf("could not open files\n"); exit(1); } write_wav(am, FRAME_BUFFER, vbuf); printf("Info: WAV ready\n"); } if (!chat) return 0; char *mg = (char *) malloc(65536); int j; pa_simple *ch = get_ch(); pa_simple *pl = get_pl(); int err = 0; int *buf = (int *) malloc(sizeof(int) * SAMPLE_BUFFER); sbf = (int *) calloc(sizeof(int), FRAME_BUFFER); int *pbf; fd_set set; int rv; struct timeval tv; printf("Info: Starting soundwave chat.\n"); while (1) { if (pa_simple_read(ch, buf, sizeof(int) * SAMPLE_BUFFER, &err)) fprintf(stderr, "Error: %s\n", pa_strerror(err)); //filter_frq(buf, SAMPLE_BUFFER); mmpush(sbf, FRAME_BUFFER * sizeof(int), buf, SAMPLE_BUFFER * sizeof(int)); msg = get_msg(sbf, mod); if (chk_frm(msg)) { printf("M: %.*s", 61, msg->data); flushfb(); } free(msg); FD_ZERO(&set); FD_SET(STDIN_FILENO, &set); tv.tv_sec = 0; tv.tv_usec = 0; rv = select(STDIN_FILENO + 1, &set, NULL, NULL, &tv); if ((rv != 0) && (rv != -1)) { rv = read(STDIN_FILENO, mg, 65536); for (i = 0; i < rv; i += 61) { j = ((i + 61) <= rv) ? 61 : (rv - i); pbf = get_fdata(mg + i, j, mod); if (pa_simple_write(pl, pbf, FRAME_BUFFER * sizeof(int), &err)) printf("error: %s\n", pa_strerror(err)); free(pbf); } } fflush(stdin); fflush(stdout); fflush(stderr); } printf("\n"); pa_simple_free(ch); pa_simple_free(pl); return 0; }
int main(int argc, char *argv[]) { if (argc < 2) { exit(1); } /* * This didn't work * see how-to-use-echo-cancellation-module-in-pulseaudio * [http://stackoverflow.com/questions/13363241/ * how-to-use-echo-cancellation-module-in-pulseaudio] * setenv("PULSE_PROP", "filter.want=echo-cancel", 1); */ char data[BUFSIZE]; ssize_t length = 0; memset(data, 0, BUFSIZE); static const pa_sample_spec pass = { .format = PA_SAMPLE_S16LE, .rate = 22050, .channels = 1 }; pa_simple *pas = NULL; int error = 0; if ((pas = pa_simple_new(NULL, "yyclient", PA_STREAM_RECORD, NULL, "record", &pass, NULL, NULL, &error)) == NULL) { fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error)); if (pas) { pa_simple_free(pas); } exit(error); } int socket_fd; if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("server socket error"); exit(1); } struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; if(inet_pton(AF_INET, argv[1], &server_addr.sin_addr) <= 0){ perror("inet_pton errno"); close(socket_fd); exit(1); } server_addr.sin_port = htons(PORT); int connect_fd; if ((connect_fd = connect(socket_fd, (struct sockaddr*) &server_addr, sizeof(server_addr))) == -1) { perror("connect error"); close(socket_fd); exit(1); } do { if (pa_simple_read(pas, data, BUFSIZE, &error) < 0) { fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error)); if (pas) { pa_simple_free(pas); } close(connect_fd); close(socket_fd); exit(error); } } while ((length = send(socket_fd, data, BUFSIZE, 0)) == BUFSIZE); if (length == -1) { perror("send error"); close(connect_fd); close(socket_fd); exit(errno); } close(connect_fd); close(socket_fd); exit(0); }
int pulseaudio_read(pa_simple *s, short *buffer, int count, unsigned char channels_number){ int number_read = pa_simple_read(s, buffer, (size_t)(count * sizeof(short) * channels_number), NULL); return (number_read < 0) ? -1 : count; }
int main(int argc ,char **argv) { if(argc != 2) { av_log(":Usage: %s <index> \n",argv[0]); return -1; } m_index = atoi(argv[1]); av_log("AudioRecoder start ... \n"); av_log("AudioRecoder version %s\n",version_str); av_log("AudioRecoder index %d\n",m_index); int m_samplesSize = 4608; int16_t *m_AudioBuff = (int16_t*)calloc(m_samplesSize,sizeof(int16_t)); if(m_AudioBuff == NULL) { av_log("AudioRecord : calloc m_AudioBuff failed\n"); return -2; } int fd_fifo; char pipename[32] = {0}; sprintf(pipename, "/tmp/pulse-00%d", m_index); if((mkfifo(pipename, O_CREAT|O_RDWR|0777)) && (errno != EEXIST)) { av_log("AudioRecord : mkfifo pipe failed: errno=%d\n",errno); return -3; } #if 1 if((fd_fifo = open(pipename, O_RDWR)) < 0) { av_log("AudioRecord : open pipe failed: errno=%d\n",errno); return -4; } #endif #if DUMP int fd_dump; char dump_filename[64]; sprintf(dump_filename, "/tmp/dump00%d.pcm", m_index); if((fd_dump = open(dump_filename, O_RDWR|O_CREAT|O_TRUNC)) < 0) { av_log("AudioRecord : open dump_filename failed: errno=%d\n",errno); return -5; } #endif vdm_init(&vdm_main,m_index); pa_simple* m_pReadStream; pa_sample_spec m_paSample; /*m_paSample = {PA_SAMPLE_S16LE, 48000, 2};*/ m_paSample.format = PA_SAMPLE_S16LE; m_paSample.rate = 48000; m_paSample.channels = 2; int pa_error; char monitorname[32]; int pa_index = m_index % 8; if (pa_index == 0) pa_index = 8; sprintf(monitorname,"%d.monitor",pa_index); /* Create the recording stream */ m_pReadStream = pa_simple_new(NULL,NULL, PA_STREAM_RECORD, monitorname, "record", &m_paSample, NULL, NULL, &pa_error); if (!m_pReadStream) { av_log("AudioRecord : pa_simple_new() failed: %s\n", pa_strerror(pa_error)); return -6; } av_log("AudioRecoder start pa_simple_read... \n"); char audmixedbuf[4608]; char audbuf[4608]; int audlen=sizeof audbuf; uint64_t ts; while(1) { av_log("AudioRecord : pa_simpel_read(4608) \n"); // memset(m_AudioBuff,0,m_samplesSize*sizeof(int16_t)); if (pa_simple_read(m_pReadStream, (uint8_t*)m_AudioBuff,m_samplesSize, &pa_error) < 0) { av_log("AudioRecord : pa_simple_read() failed: %s\n", pa_strerror(pa_error)); return -7; } av_log("AudioRecord : pa_simpel_read(4608)-0-0 \n"); #if 1 if((write(fd_fifo,(uint8_t*)m_AudioBuff,m_samplesSize)) < 0) { av_log("AudioRecord : write() failed\n"); return -8; } #else vdm_check_audiofragment(&vdm_main); av_log("AudioRecord : pa_simpel_read(4608)-1-1 \n"); videosurf*vs=NULL; audiofrag*af=NULL; VDM_FOREACH_BEGIN(&vdm_main,vs,af) audlen=4608; if(_i==0){ // shmaudio_get(af,audmixedbuf,&audlen,&ts); continue; }else{ // shmaudio_get(af,audbuf,&audlen,&ts); //mix here // pcm_mix_16_ch2((int16_t*)audmixedbuf,(int16_t*)audbuf,audlen); } VDM_FOREACH_END memcpy(m_AudioBuff,audmixedbuf,4608); av_log("AudioRecord : pa_simpel_read(4608)--== \n"); write(fd_fifo,(uint8_t*)m_AudioBuff,m_samplesSize); #endif #if DUMP if((write(fd_dump,(uint8_t*)m_AudioBuff,m_samplesSize)) < 0) { av_log("AudioRecord : write() fd_dump failed\n"); return -9; } #endif } free(m_AudioBuff); close(fd_fifo); #if DUMP close(fd_dump); #endif pa_simple_free(m_pReadStream); av_log("AudioRecoder end ... \n"); fclose(fp_log); vdm_fini(&vdm_main); return 0; }
int main (int argc, char *argv[]) { /* Accept the users's choice of hosts or use the default. Then do the same for the TCP/IP port at which the server is listening as well as the number of iterations to perform. */ const char *server_host = argc > 1 ? argv[1] : SERVER_HOST; u_short server_port = argc > 2 ? ACE_OS::atoi (argv[2]) : SERVER_PORT; int max_iterations = argc > 3 ? ACE_OS::atoi (argv[3]) : MAX_ITERATIONS; /* Build ourselves a Stream socket. This is a connected socket that provides reliable end-to-end communications. We will use the server object to send data to the server we connect to. */ /* And we need a connector object to establish that connection. The ACE_SOCK_Connector object provides all of the tools we need to establish a connection once we know the server's network address... */ ACE_SOCK_Connector connector; /* Which we create with an ACE_INET_Addr object. This object is given the TCP/IP port and hostname of the server we want to connect to. */ ACE_INET_Addr addr (server_port, server_host); /* So, we feed the Addr object and the Stream object to the connector's connect() member function. Given this information, it will establish the network connection to the server and attach that connection to the server object. */ if (connector.connect (server, addr) == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); /* Just for grins, we'll send the server several messages. */ pa_sample_spec capture_profile; capture_profile.channels = 1; capture_profile.rate = 44100; capture_profile.format = PA_SAMPLE_S16LE; int error; pa_simple *paCaptureHandle = pa_simple_new(NULL,"soundCard", PA_STREAM_RECORD, NULL, "record", &capture_profile, NULL, NULL, &error); omni_thread* read = new omni_thread(read_thread, (void *)&max_iterations ); read->start(); for (int i = 0; i < max_iterations; i++) { short buffer[2048]; /* Create our message with the message number */ pa_simple_read(paCaptureHandle, buffer, 2048, &error); // sprintf((char*)buffer,"Message = %d\n",i); /* Send the message to the server. We use the server object's send_n() function to send all of the data at once. There is also a send() function but it may not send all of the data. That is due to network buffer availability and such. If the send() doesn't send all of the data, it is up to you to program things such that it will keep trying until all of the data is sent or simply give up. The send_n() function already does the "keep trying" option for us, so we use it. Like the send() method used in the servers we've seen, there are two additional parameters you can use on the send() and send_n() method calls. The timeout parameter limits the amount of time the system will attempt to send the data to the peer. The flags parameter is passed directly to the OS send() system call. See send(2) for the valid flags values. */ if (server.send_n (buffer,2048) == -1) //ACE_ERROR_RETURN ((LM_ERROR, // "%p\n", // "send"), // -1); //else /* Pause for a second. */ // ACE_OS::sleep (1); memset(buffer,2048,0); } pa_simple_free(paCaptureHandle); /* Close the connection to the server. The servers we've created so far all are based on the ACE_Reactor. When we close(), the server's reactor will see activity for the registered event handler and invoke handle_input(). That, in turn, will try to read from the socket but get back zero bytes. At that point, the server will know that we've closed from our side. */ while(read->state()!=omni_thread::STATE_TERMINATED); if (server.close () == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); return 0; }
static void *DEFAULT_CC read_raw_audio_data(void *arg) { pa_sample_spec samp_spec; pa_simple *simple = NULL; uint32_t bytes_read; char *cptr; int i; int error; struct trans *strans; char path[256]; struct stream *outs; strans = trans_create(TRANS_MODE_UNIX, 8192, 8192); if (strans == 0) { LOG(0, ("read_raw_audio_data: trans_create failed\n")); return 0; } strans->trans_data_in = sttrans_data_in; g_snprintf(path, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num); if (trans_connect(strans, "", path, 100) != 0) { LOG(0, ("read_raw_audio_data: trans_connect failed\n")); trans_delete(strans); return 0; } /* setup audio format */ samp_spec.format = PA_SAMPLE_S16LE; samp_spec.rate = 44100; samp_spec.channels = 2; /* if we are root, then for first 8 seconds connection to pulseaudo server fails; if we are non-root, then connection succeeds on first attempt; for now we have changed code to be non-root, but this may change in the future - so pretend we are root and try connecting to pulseaudio server for upto one minute */ for (i = 0; i < 60; i++) { simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL, "record", &samp_spec, NULL, NULL, &error); if (simple) { /* connected to pulseaudio server */ LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n")); break; } LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n")); LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); g_sleep(1000); } if (i == 60) { /* failed to connect to audio server */ trans_delete(strans); return NULL; } /* insert header just once */ outs = trans_get_out_s(strans, 8192); out_uint32_le(outs, 0); out_uint32_le(outs, AUDIO_BUF_SIZE + 8); cptr = outs->p; out_uint8s(outs, AUDIO_BUF_SIZE); s_mark_end(outs); while (1) { /* read a block of raw audio data... */ g_memset(cptr, 0, 4); bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error); if (bytes_read < 0) { LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n")); LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); break; } /* bug workaround: even when there is no audio data, pulseaudio is returning without errors but the data itself is zero; we use this zero data to determine that there is no audio data present */ if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0) { g_sleep(10); continue; } if (trans_force_write_s(strans, outs) != 0) { LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n")); break; } } pa_simple_free(simple); trans_delete(strans); return NULL; }
/* capture */ static void *qpa_thread_in (void *arg) { PAVoiceIn *pa = arg; HWVoiceIn *hw = &pa->hw; int threshold; threshold = conf.divisor ? hw->samples / conf.divisor : 0; if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) { return NULL; } for (;;) { int incr, to_grab, wpos; for (;;) { if (pa->done) { goto exit; } if (pa->dead > threshold) { break; } if (audio_pt_wait (&pa->pt, AUDIO_FUNC)) { goto exit; } } incr = to_grab = pa->dead; wpos = hw->wpos; if (audio_pt_unlock (&pa->pt, AUDIO_FUNC)) { return NULL; } while (to_grab) { int error; int chunk = audio_MIN (to_grab, hw->samples - wpos); void *buf = advance (pa->pcm_buf, wpos); if (pa_simple_read (pa->s, buf, chunk << hw->info.shift, &error) < 0) { qpa_logerr (error, "pa_simple_read failed\n"); return NULL; } hw->conv (hw->conv_buf + wpos, buf, chunk, &nominal_volume); wpos = (wpos + chunk) % hw->samples; to_grab -= chunk; } if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) { return NULL; } pa->wpos = wpos; pa->dead -= incr; pa->incr += incr; } exit: audio_pt_unlock (&pa->pt, AUDIO_FUNC); return NULL; }
static void * audio_capture_thr(void *args) { int error; PSAUDIORECTHRPARAMS params = (PSAUDIORECTHRPARAMS)args; pa_simple *pa_context = NULL; uint8_t active = 1; uint32_t buffer_size; SSAMPLEHEADER sample_header = {0}; HBUF sample; TIMING_MEASURE_AREA; buffer_size = HEADER_SIZE + params->sample_spec->channels * params->buffer_size * pa_sample_size(params->sample_spec); sample_header.number = 0; sample_header.buf_type = BUF_TYPE_INTERLEAVED; sample_header.sample_size = pa_sample_size(params->sample_spec); sample_header.samples = params->buffer_size; sample_header.channels = params->sample_spec->channels; sample_header.samplerate = params->sample_spec->rate; if ( !(pa_context = pa_simple_new(NULL, params->argv[0], PA_STREAM_RECORD, NULL, "record", params->sample_spec, NULL, NULL, &error)) ) { fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error)); goto audio_thr_finish; } printf("[source] audio thr\n"); while (active) { TIMING_START(); sample = buf_alloc(NULL); buf_resize(sample, buffer_size); sample->full_size = sample->size = sample->alloced_size; sample_zero_buffer(sample); memcpy(sample->buf, &sample_header, sizeof(SSAMPLEHEADER)); if (pa_simple_read(pa_context, sample->buf + HEADER_SIZE, sample->alloced_size - HEADER_SIZE, &error) < 0) { fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error)); goto audio_thr_finish; } pa_gettimeofday(&(sample_header.timestamp)); sample_header.number += 1; /* printf("[audio] read %p\n", sample); */ if ( (error = write(params->pipefd, &sample, sizeof(sample))) != sizeof(sample)) { if (error == -1) { handle_error("[audio] write()"); } buf_free(sample); perror("[audio] "); printf("[audio] uverrun. free buffer\n"); } active = params->active; TIMING_END(" audio"); } audio_thr_finish: pa_simple_free(pa_context); return NULL; }
int main(int argc, char*argv[]) { /* The Sample format to use */ static const pa_sample_spec ss = { .format = PA_SAMPLE_S16LE, .rate = 44100, .channels = 2 }; pa_simple* dev_out = 0; pa_simple* dev_in = 0; int ret = 1; int error; /* Create a new playback stream */ if (!(dev_out = pa_simple_new(NULL, "Noise Remover", PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error))) { fprintf(stderr, __FILE__": pa_simple_new() failed: %dev_out\n", pa_strerror(error)); goto finish; } if (!(dev_in = pa_simple_new(NULL, "Noise Remover", PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) { fprintf(stderr, __FILE__": pa_simple_new() failed: %dev_out\n", pa_strerror(error)); goto finish; } { int i; float f; SpeexPreprocessState* pp = speex_preprocess_state_init(BUFSIZE, ss.rate); i = 1; speex_preprocess_ctl(pp, SPEEX_PREPROCESS_SET_DENOISE, &i); i = 1; speex_preprocess_ctl(pp, SPEEX_PREPROCESS_SET_AGC, &i); f = 8000; speex_preprocess_ctl(pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f); i = 1; speex_preprocess_ctl(pp, SPEEX_PREPROCESS_SET_DEREVERB, &i); f = 0.04; speex_preprocess_ctl(pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f); f = 0.03; speex_preprocess_ctl(pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); double lowest_rms = 99999999999999; int silence_count = 0; for (;;) { int16_t buf[BUFSIZE]; /* Read some data ... */ if (pa_simple_read(dev_in, buf, sizeof(buf), &error) < 0) { fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error)); goto finish; } /* ... Use speex to de-noise ... */ double total = 0; for(int n = 0; n < sizeof(buf); n++) total += buf[n] * buf[n]; double rms = std::sqrt(total / sizeof(buf)); if(rms < lowest_rms) lowest_rms = rms; if((rms - lowest_rms) < 50) // this value will probably need adjusting for you silence_count = 0; else if(silence_count < 10) silence_count++; if(silence_count == 10) speex_preprocess_run(pp, buf); else continue; // don't write it out... /* ... and play it */ if (pa_simple_write(dev_out, buf, sizeof(buf), &error) < 0) { fprintf(stderr, __FILE__": pa_simple_write() failed: %dev_out\n", pa_strerror(error)); goto finish; } } /* Make sure that every single sample was played */ if (pa_simple_drain(dev_out, &error) < 0) { fprintf(stderr, __FILE__": pa_simple_drain() failed: %dev_out\n", pa_strerror(error)); goto finish; } } ret = 0; finish: if (dev_out) pa_simple_free(dev_out); if (dev_in) pa_simple_free(dev_in); return ret; }
// Reads in a message and places it in out limited to the len given // returns the size of the message size_t Dialup::read(unsigned char *out, size_t len) { // TODO: maybe clean it up a bit more, // it my be losing some bits when it refills the buffer int high = 0; int low = 0; unsigned char hash = 0; size_t dataind = 0; buffer[dataind] = 0; // bypass everthing that isn't the signal while (!buffer[buffind]) buffind++; while (dataind < len) { // grab new data if were done with this block if (buffind > buffsize) { // printf("!"); // save the last value for the case of a floating value int oldval = buffer[buffsize-2]; buffind = 0; // get the next block of data int err = pa_simple_read(audiosrv, buffer, buffsize, 0); if (err) throw pa_exception(err); // flip the data upside down // if its in a middle range assume the previous value for (int i=0; i<buffsize; i++) { if (buffer[i] < 100) { buffer[i] = 0; } else if (buffer[i] > 150) { buffer[i] = 1; } else { buffer[i] = i>0 ? buffer[i-1] : oldval; } } } // count up highs and lows if (buffer[buffind]) high++; else low++; if (low > 8) { // End of message signal if (out[dataind] != hash) return -1; else return dataind; } if (low+high > 4 && low && buffer[buffind]) { if (high > 8) { // End of word signal // printf(" |%d|%d[%c]\n", high, low, out[dataind]); hash ^= out[dataind]; out[++dataind] = 0; } else { // determine the bit // printf("%d", high>low); out[dataind] <<= 1; out[dataind] |= (high > low); } high = 0; low = 0; } //skip two as the audio data is interleaved buffind += 2; } return -2; }