/* * PCM-Capture nach TCP / 16bit signed auf Ice1712 Pro mit ALSA/Linux/x86 * Aufruf [Programm] [Portnummer] * * (Compilieren fuer Mono oder Stereo und auf eine feste Samplingrate zw. * 8000 und 48000Hz, hat bisher keine eigene Erkennung fuer WAV-Header!) * Benoetigte Libraries: asound pthread * * Frei kopierbarer haesslicher "proof of concept" Code ohne jegliche * Garantien, nicht mal die, die oben versprochene Funktion zu erfuellen. * * Beteiligt: Eric Auer, Attilio Erriquez, Dan Hollis, Christian Dressler * * Achtung: Der ALSA Treiber fuer diese Karte erlaubt nur, ALLE Kanaele * gleichzeitig zu oeffnen, daher funktioniert dafuer auch keine OSS-Emu. * Fuer Ausgabe sind das exakt 10, fuer Eingabe exakt 12 Monokanaele. * * 30.05.2000 - 01.06.2000 */ #include "rec-sock-alsa.h" /* ***************************************************************** */ void help(void) { printf("Usage: Give me a port and I will write,\n" "signed %dbit " "mono" " PCM %dHz data to it.\n", snd_inBITS,snd_HZ); _exit(1); return; }; /* ***************************************************************** */ signed int mybuf[RBUF*nCHN]; // nCHN wg nCHN voices int want_data; // for locking /* ***************************************************************** */ int send_buffer(int sockfd, int channel) // verbindet beide Welten! // Aktion: fetch channel from buffer (locking), send it, recv ack (ign. ack) { int cnt,cnt2,left; fmtSOCK mywrbuf[RBUF+1]; char combuf[200]; LOCK; want_data++; UNLOCK; while (in_buffer<=0) { /* usleep(1); */ }; LOCK; if ((left=in_buffer)<=0) return 1; // Pech gehabt? left /= sizeof(mybuf[0]) * nCHN; if (left>=RBUF) return 2; // dont overflow yourself for (cnt=0,cnt2=channel; cnt> snd_SHL; cnt2+=nCHN; }; if (want_data>0) want_data--; UNLOCK; fprintf(stderr,"send_buffer: %d Samples\n",left); if (left<=0) return 3; // should never happen if (send(sockfd,mywrbuf,left * sizeof(mywrbuf[0]),0) == -1) { perror("send"); return 4; }; if (recv(sockfd,combuf,sizeof(combuf),0) == -1) { perror("recv"); return 5; }; /* Ack. from client is ignored here, there only has to be some message */ return 0; }; /* ***************************************************************** */ int read_sound(snd_pcm_t * handle) { int left, cnt; if ((cnt = snd_pcm_capture_go(handle))) { fprintf(stderr,"Error with snd_pcm_capture_go: %s\n", snd_strerror(cnt)); return 1; }; want_data=0; usleep(1000); while (run_server>0) { LOCK; in_buffer = 0; left = in_buffer = snd_pcm_read(handle,mybuf, sizeof(mybuf)); UNLOCK; left = (left>0) ? left / (nCHN * sizeof(mybuf[0])) : left; if (left<=0) { fprintf(stderr,"Error with snd_pcm_read: %s\n", snd_strerror(left)); left = snd_pcm_capture_go(handle); fprintf(stderr,"Tried to restart capture: %s\n", snd_strerror(left)); left = 0; fprintf(stderr,"Trying to continue\n"); }; if ((left<0) && (left!= -EAGAIN)) { fprintf(stderr,"Error with snd_pcm_read: %s\n", snd_strerror(left)); LOCK; run_server = -1; in_buffer = 0; UNLOCK; return 1; }; if (left>0) { // wait a bit if someone wants to copy the buffer // but only if there is something in it. usleep(1000); while (want_data) usleep(1000); }; #ifdef DEBUG if (left>0) { fprintf(stderr,"%d samples fetched\n",left); }; #endif }; LOCK; run_server = -1; in_buffer = 0; UNLOCK; return 0; }; /* ***************************************************************** */ int main(int argc, char ** argv) { snd_pcm_t * soundhandle=NULL; int sockfd; long int port; run_server = 1; in_buffer = 0; if ((argc!=2) || (!argv)) help(); if (!argv[1]) help(); port = strtol(argv[1],NULL,10); if ((port < 1024) || (port > 65519)) help(); fprintf(stderr,"Opening sound for capture\n"); if (open_sound(&soundhandle)) return 1; fprintf(stderr,"Starting to listen to port %d\n",(int)port); if ((sockfd = open_socket((int)port)) < 0) return 1; if (read_sound(soundhandle)) { fprintf(stderr, "Error reading from PCM\n"); }; // kehrt nur bei Fehler zurueck oder bei "CLOSE" Kommando fprintf(stderr,"Closing server sockets\n"); if (close_socket(sockfd)) return 1; fprintf(stderr,"Closing sound\n"); if (close_sound(soundhandle)) return 1; return 0; };