-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsound.c
105 lines (88 loc) · 2.73 KB
/
sound.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <portaudio.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <strings.h>
#include "ringbuffer.h"
#include <semaphore.h>
#define SAMPLE_RATE 8000
#define FRAME_SIZE 160
#define RINGBUFFER_SIZE 1024 // 64
// 64 frames @ 20ms/frame = 1.2 sec
// 64 frames @ 320B/frame = 20kB
extern sem_t * sem_microphone;
ringbuffer_t * speakers;
ringbuffer_t * microphone;
struct myAudio {
ringbuffer_t * speakers;
ringbuffer_t * microphone;
} audioIO;
PaStream *stream;
/* This routine will be called by the PortAudio engine when audio is needed.
** It may called at interrupt level on some machines so don't do anything
** that could mess up the system like calling malloc() or free().
*/
static int paCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
long long moy = 0;
int i;
int16_t frame[160];
int16_t * out = (int16_t *)outputBuffer;
int16_t * in = (int16_t *)inputBuffer;
int16_t * tmp;
// Cast data passed through stream to our structure.
struct myAudio * data = (struct myAudio *)userData;
ringbuffer_t * dataIn = data->microphone;
ringbuffer_t * dataOut = data->speakers;
/* Data in */
ringbuffer_write(dataIn, in);
sem_post(sem_microphone);
/* Data out */
if( (tmp=ringbuffer_read(dataOut, frame)) != NULL) {
for( i=0; i<framesPerBuffer; i++ ) {
*out++ = frame[i]; // left
*out++ = frame[i]; // right
}
} else {
bzero(out, sizeof(int16_t) * framesPerBuffer * 2);
}
return 0;
}
void audio_init() {
speakers = ringbuffer_new(FRAME_SIZE, RINGBUFFER_SIZE);
microphone = ringbuffer_new(FRAME_SIZE, RINGBUFFER_SIZE);
audioIO.speakers = speakers;
audioIO.microphone = microphone;
Pa_Initialize();
// Open an audio I/O stream.
Pa_OpenDefaultStream( &stream,
1, // one input channels
2, // no output
paInt16,
SAMPLE_RATE,
FRAME_SIZE,
//256, // frames per buffer, i.e. the number
// of sample frames that PortAudio will
// request from the callback. Many apps
// may want to use
// paFramesPerBufferUnspecified, which
// tells PortAudio to pick the best,
// possibly changing, buffer size.*/
paCallback, /* this is your callback function */
&audioIO ); /*This is a pointer that will be passed to
your callback*/
Pa_StartStream( stream );
}
void audio_close() {
Pa_StopStream(stream);
Pa_CloseStream(stream);
Pa_Terminate();
}
int audio_to_speakers(int16_t * data, int size) {
return ringbuffer_write(speakers, data);
}