1 /******************************************************************************
2 * recordMyDesktop *
3 *******************************************************************************
4 * *
5 * Copyright (C) 2006,2007,2008 John Varouhakis *
6 * *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
21 * *
22 * *
23 * *
24 * For further information contact me at johnvarouhakis@gmail.com *
25 ******************************************************************************/
26
27 #include "config.h"
28 #include "rmd_capture_sound.h"
29
30 #include "rmd_jack.h"
31 #include "rmd_opendev.h"
32 #include "rmd_types.h"
33
34 #include <pthread.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <sys/types.h>
38 #include <sys/uio.h>
39 #include <unistd.h>
40 #include <stdlib.h>
41
42
CaptureSound(ProgData * pdata)43 void *CaptureSound(ProgData *pdata){
44
45 #ifdef HAVE_LIBASOUND
46 int frames=pdata->periodsize;
47 #endif
48 //start capturing only after first frame is taken
49 usleep(pdata->frametime);
50
51 while(pdata->running){
52 int sret=0;
53 SndBuffer *newbuf,*tmp;
54 if (pdata->paused) {
55 #ifdef HAVE_LIBASOUND
56 if(!pdata->hard_pause){
57 snd_pcm_pause(pdata->sound_handle,1);
58 pthread_mutex_lock(&pdata->pause_mutex);
59 pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
60 pthread_mutex_unlock(&pdata->pause_mutex);
61 snd_pcm_pause(pdata->sound_handle,0);
62 }
63 else{//device doesn't support pause(is this the norm?mine doesn't)
64 snd_pcm_close(pdata->sound_handle);
65 pthread_mutex_lock(&pdata->pause_mutex);
66 pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
67 pthread_mutex_unlock(&pdata->pause_mutex);
68 pdata->sound_handle=
69 OpenDev(pdata->args.device,
70 &pdata->args.channels,
71 &pdata->args.frequency,
72 &pdata->args.buffsize,
73 NULL,
74 NULL,
75 NULL//let's hope that the device capabilities
76 //didn't magically change
77 );
78 if(pdata->sound_handle==NULL){
79 fprintf(stderr,"Couldn't reopen sound device.Exiting\n");
80 pdata->running = FALSE;
81 errno=3;
82 pthread_exit(&errno);
83 }
84 }
85 #else
86 close(pdata->sound_handle);
87 pthread_mutex_lock(&pdata->pause_mutex);
88 pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
89 pthread_mutex_unlock(&pdata->pause_mutex);
90 pdata->sound_handle=
91 OpenDev(pdata->args.device,
92 pdata->args.channels,
93 pdata->args.frequency);
94 if(pdata->sound_handle<0){
95 fprintf(stderr,"Couldn't reopen sound device.Exiting\n");
96 pdata->running = FALSE;
97 errno=3;
98 pthread_exit(&errno);
99 }
100 #endif
101 }
102
103 //create new buffer
104 newbuf=(SndBuffer *)malloc(sizeof(SndBuffer));
105 #ifdef HAVE_LIBASOUND
106 newbuf->data=(signed char *)malloc(frames*pdata->sound_framesize);
107 #else
108 newbuf->data=(signed char *)malloc(((pdata->args.buffsize<<1)*
109 pdata->args.channels));
110 #endif
111 newbuf->next=NULL;
112
113 //read data into new buffer
114 #ifdef HAVE_LIBASOUND
115 while(sret<frames){
116 int temp_sret=snd_pcm_readi(pdata->sound_handle,
117 newbuf->data+pdata->sound_framesize*sret,
118 frames-sret);
119 if(temp_sret==-EPIPE){
120 fprintf(stderr,"%s: Overrun occurred.\n",
121 snd_strerror(temp_sret));
122 snd_pcm_prepare(pdata->sound_handle);
123 }
124 else if (temp_sret<0){
125 fprintf(stderr,"An error occured while reading sound data:\n"
126 " %s\n",
127 snd_strerror(temp_sret));
128 snd_pcm_prepare(pdata->sound_handle);
129 }
130 else
131 sret+=temp_sret;
132 }
133 #else
134 sret=0;
135 //oss recording loop
136 do{
137 int temp_sret=read(pdata->sound_handle,
138 &newbuf->data[sret],
139 ((pdata->args.buffsize<<1)*
140 pdata->args.channels)-sret);
141 if(temp_sret<0){
142 fprintf(stderr,"An error occured while reading from soundcard"
143 "%s\n"
144 "Error description:\n"
145 "%s\n",pdata->args.device,strerror(errno));
146 }
147 else
148 sret+=temp_sret;
149 }while(sret<((pdata->args.buffsize<<1)*
150 pdata->args.channels));
151 #endif
152 //queue the new buffer
153 pthread_mutex_lock(&pdata->sound_buffer_mutex);
154 tmp=pdata->sound_buffer;
155 if(pdata->sound_buffer==NULL)
156 pdata->sound_buffer=newbuf;
157 else{
158 while(tmp->next!=NULL)
159 tmp=tmp->next;
160 tmp->next=newbuf;
161 }
162 pthread_mutex_unlock(&pdata->sound_buffer_mutex);
163
164
165 //signal that there are data to be proccessed
166 pthread_mutex_lock(&pdata->snd_buff_ready_mutex);
167 pthread_cond_signal(&pdata->sound_data_read);
168 pthread_mutex_unlock(&pdata->snd_buff_ready_mutex);
169 }
170 #ifdef HAVE_LIBASOUND
171 snd_pcm_close(pdata->sound_handle);
172 #else
173 close(pdata->sound_handle);
174 #endif
175 pthread_exit(&errno);
176 }
177
178
179
180