![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
chan_alsa.c File Reference
Definition in file chan_alsa.c.
#include "asterisk.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <alsa/asoundlib.h>
#include "asterisk/frame.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/options.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/endian.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/musiconhold.h"
#include "busy.h"
#include "ringtone.h"
#include "ring10.h"
#include "answer.h"
Include dependency graph for chan_alsa.c:

Go to the source code of this file.
Data Structures | |
| struct | chan_alsa_pvt |
| struct | sound |
Defines | |
| #define | ALSA_INDEV "hw:0,0" |
| #define | ALSA_OUTDEV "hw:0,0" |
| #define | ALSA_PCM_NEW_HW_PARAMS_API |
| #define | ALSA_PCM_NEW_SW_PARAMS_API |
| #define | BUFFER_FMT ((buffersize * 10) << 16) | (0x0006); |
| #define | DEBUG 0 |
| #define | DESIRED_RATE 8000 |
| #define | FRAME_SIZE 160 |
| #define | MAX_BUFFER_SIZE 100 |
| #define | MIN(a, b) ((a) < (b) ? (a) : (b)) |
| #define | MIN_SWITCH_TIME 600 |
| #define | PERIOD_FRAMES 80 |
Functions | |
| static int | alsa_answer (struct ast_channel *c) |
| static int | alsa_call (struct ast_channel *c, char *dest, int timeout) |
| static snd_pcm_t * | alsa_card_init (char *dev, snd_pcm_stream_t stream) |
| static int | alsa_digit (struct ast_channel *c, char digit, unsigned int duration) |
| static int | alsa_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
| static int | alsa_hangup (struct ast_channel *c) |
| static int | alsa_indicate (struct ast_channel *chan, int cond, const void *data, size_t datalen) |
| static struct ast_channel * | alsa_new (struct chan_alsa_pvt *p, int state) |
| static struct ast_frame * | alsa_read (struct ast_channel *chan) |
| static struct ast_channel * | alsa_request (const char *type, int format, void *data, int *cause) |
| static int | alsa_text (struct ast_channel *c, const char *text) |
| static int | alsa_write (struct ast_channel *chan, struct ast_frame *f) |
| static void | answer_sound (void) |
| AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"ALSA Console Channel Driver") | |
| AST_MUTEX_DEFINE_STATIC (alsalock) | |
| static char * | autoanswer_complete (const char *line, const char *word, int pos, int state) |
| static int | console_answer (int fd, int argc, char *argv[]) |
| static int | console_autoanswer (int fd, int argc, char *argv[]) |
| static int | console_dial (int fd, int argc, char *argv[]) |
| static int | console_hangup (int fd, int argc, char *argv[]) |
| static int | console_sendtext (int fd, int argc, char *argv[]) |
| static void | grab_owner (void) |
| static int | load_module (void) |
| static int | send_sound (void) |
| static void * | sound_thread (void *unused) |
| static int | soundcard_init (void) |
| static int | unload_module (void) |
Variables | |
| static struct chan_alsa_pvt | alsa |
| static const struct ast_channel_tech | alsa_tech |
| static const char | answer_usage [] |
| static int | autoanswer = 1 |
| static const char | autoanswer_usage [] |
| static struct ast_cli_entry | cli_alsa [] |
| static const char | config [] = "alsa.conf" |
| static char | context [AST_MAX_CONTEXT] = "default" |
| static int | cursound = -1 |
| static struct ast_jb_conf | default_jbconf |
| static const char | dial_usage [] |
| static char | exten [AST_MAX_EXTENSION] = "s" |
| static snd_pcm_format_t | format = SND_PCM_FORMAT_S16_LE |
| static struct ast_jb_conf | global_jbconf |
| static const char | hangup_usage [] |
| static int | hookstate = 0 |
| static char | indevname [50] = ALSA_INDEV |
| static char | language [MAX_LANGUAGE] = "" |
| static char | mohinterpret [MAX_MUSICCLASS] |
| static int | nosound = 0 |
| static int | offset = 0 |
| static char | outdevname [50] = ALSA_OUTDEV |
| static int | readdev = -1 |
| static int | sampsent = 0 |
| static const char | sendtext_usage [] |
| static short | silence [FRAME_SIZE] = { 0, } |
| static int | silencelen = 0 |
| static int | silencesuppression = 0 |
| static int | silencethreshold = 1000 |
| static int | sndcmd [2] |
| static struct sound | sounds [] |
| pthread_t | sthread |
| static const char | tdesc [] = "ALSA Console Channel Driver" |
| static int | writedev = -1 |
|
|
Definition at line 86 of file chan_alsa.c. |
|
|
Definition at line 87 of file chan_alsa.c. |
|
|
Definition at line 47 of file chan_alsa.c. |
|
|
Definition at line 48 of file chan_alsa.c. |
|
|
Definition at line 97 of file chan_alsa.c. |
|
|
Definition at line 84 of file chan_alsa.c. |
|
|
Definition at line 88 of file chan_alsa.c. Referenced by alsa_card_init(). |
|
|
Definition at line 91 of file chan_alsa.c. Referenced by alsa_read(), oss_read(), send_sound(), sound_thread(), and soundcard_writeframe(). |
|
|
Definition at line 172 of file chan_alsa.c. |
|
|
Referenced by autoanswer_complete(), and send_sound(). |
|
|
Definition at line 100 of file chan_alsa.c. |
|
|
Definition at line 92 of file chan_alsa.c. Referenced by alsa_card_init(). |
|
|
Definition at line 562 of file chan_alsa.c. References alsa, answer_sound(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, ast_verbose(), cursound, and chan_alsa_pvt::icard. 00563 { 00564 ast_mutex_lock(&alsalock); 00565 ast_verbose(" << Console call has been answered >> \n"); 00566 answer_sound(); 00567 ast_setstate(c, AST_STATE_UP); 00568 cursound = -1; 00569 snd_pcm_prepare(alsa.icard); 00570 snd_pcm_start(alsa.icard); 00571 ast_mutex_unlock(&alsalock); 00572 return 0; 00573 }
|
|
||||||||||||||||
|
Definition at line 523 of file chan_alsa.c. References alsa, AST_CONTROL_ANSWER, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), ast_verbose(), autoanswer, grab_owner(), chan_alsa_pvt::icard, ast_channel::lock, chan_alsa_pvt::owner, sndcmd, and ast_frame::subclass. 00524 { 00525 int res = 3; 00526 struct ast_frame f = { AST_FRAME_CONTROL }; 00527 ast_mutex_lock(&alsalock); 00528 ast_verbose(" << Call placed to '%s' on console >> \n", dest); 00529 if (autoanswer) { 00530 ast_verbose(" << Auto-answered >> \n"); 00531 grab_owner(); 00532 if (alsa.owner) { 00533 f.subclass = AST_CONTROL_ANSWER; 00534 ast_queue_frame(alsa.owner, &f); 00535 ast_mutex_unlock(&alsa.owner->lock); 00536 } 00537 } else { 00538 ast_verbose(" << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n"); 00539 grab_owner(); 00540 if (alsa.owner) { 00541 f.subclass = AST_CONTROL_RINGING; 00542 ast_queue_frame(alsa.owner, &f); 00543 ast_mutex_unlock(&alsa.owner->lock); 00544 } 00545 write(sndcmd[1], &res, sizeof(res)); 00546 } 00547 snd_pcm_prepare(alsa.icard); 00548 snd_pcm_start(alsa.icard); 00549 ast_mutex_unlock(&alsalock); 00550 return 0; 00551 }
|
|
||||||||||||
|
Definition at line 344 of file chan_alsa.c. References ast_log(), DESIRED_RATE, pollfd::fd, LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, PERIOD_FRAMES, readdev, and writedev. Referenced by soundcard_init(). 00345 { 00346 int err; 00347 int direction; 00348 snd_pcm_t *handle = NULL; 00349 snd_pcm_hw_params_t *hwparams = NULL; 00350 snd_pcm_sw_params_t *swparams = NULL; 00351 struct pollfd pfd; 00352 snd_pcm_uframes_t period_size = PERIOD_FRAMES * 4; 00353 /* int period_bytes = 0; */ 00354 snd_pcm_uframes_t buffer_size = 0; 00355 00356 unsigned int rate = DESIRED_RATE; 00357 #if 0 00358 unsigned int per_min = 1; 00359 #endif 00360 /* unsigned int per_max = 8; */ 00361 snd_pcm_uframes_t start_threshold, stop_threshold; 00362 00363 err = snd_pcm_open(&handle, dev, stream, O_NONBLOCK); 00364 if (err < 0) { 00365 ast_log(LOG_ERROR, "snd_pcm_open failed: %s\n", snd_strerror(err)); 00366 return NULL; 00367 } else { 00368 if (option_debug) 00369 ast_log(LOG_DEBUG, "Opening device %s in %s mode\n", dev, (stream == SND_PCM_STREAM_CAPTURE) ? "read" : "write"); 00370 } 00371 00372 snd_pcm_hw_params_alloca(&hwparams); 00373 snd_pcm_hw_params_any(handle, hwparams); 00374 00375 err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); 00376 if (err < 0) 00377 ast_log(LOG_ERROR, "set_access failed: %s\n", snd_strerror(err)); 00378 00379 err = snd_pcm_hw_params_set_format(handle, hwparams, format); 00380 if (err < 0) 00381 ast_log(LOG_ERROR, "set_format failed: %s\n", snd_strerror(err)); 00382 00383 err = snd_pcm_hw_params_set_channels(handle, hwparams, 1); 00384 if (err < 0) 00385 ast_log(LOG_ERROR, "set_channels failed: %s\n", snd_strerror(err)); 00386 00387 direction = 0; 00388 err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, &direction); 00389 if (rate != DESIRED_RATE) 00390 ast_log(LOG_WARNING, "Rate not correct, requested %d, got %d\n", DESIRED_RATE, rate); 00391 00392 direction = 0; 00393 err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, &direction); 00394 if (err < 0) 00395 ast_log(LOG_ERROR, "period_size(%ld frames) is bad: %s\n", period_size, snd_strerror(err)); 00396 else { 00397 if (option_debug) 00398 ast_log(LOG_DEBUG, "Period size is %d\n", err); 00399 } 00400 00401 buffer_size = 4096 * 2; /* period_size * 16; */ 00402 err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size); 00403 if (err < 0) 00404 ast_log(LOG_WARNING, "Problem setting buffer size of %ld: %s\n", buffer_size, snd_strerror(err)); 00405 else { 00406 if (option_debug) 00407 ast_log(LOG_DEBUG, "Buffer size is set to %d frames\n", err); 00408 } 00409 00410 #if 0 00411 direction = 0; 00412 err = snd_pcm_hw_params_set_periods_min(handle, hwparams, &per_min, &direction); 00413 if (err < 0) 00414 ast_log(LOG_ERROR, "periods_min: %s\n", snd_strerror(err)); 00415 00416 err = snd_pcm_hw_params_set_periods_max(handle, hwparams, &per_max, 0); 00417 if (err < 0) 00418 ast_log(LOG_ERROR, "periods_max: %s\n", snd_strerror(err)); 00419 #endif 00420 00421 err = snd_pcm_hw_params(handle, hwparams); 00422 if (err < 0) 00423 ast_log(LOG_ERROR, "Couldn't set the new hw params: %s\n", snd_strerror(err)); 00424 00425 snd_pcm_sw_params_alloca(&swparams); 00426 snd_pcm_sw_params_current(handle, swparams); 00427 00428 #if 1 00429 if (stream == SND_PCM_STREAM_PLAYBACK) 00430 start_threshold = period_size; 00431 else 00432 start_threshold = 1; 00433 00434 err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold); 00435 if (err < 0) 00436 ast_log(LOG_ERROR, "start threshold: %s\n", snd_strerror(err)); 00437 #endif 00438 00439 #if 1 00440 if (stream == SND_PCM_STREAM_PLAYBACK) 00441 stop_threshold = buffer_size; 00442 else 00443 stop_threshold = buffer_size; 00444 00445 err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold); 00446 if (err < 0) 00447 ast_log(LOG_ERROR, "stop threshold: %s\n", snd_strerror(err)); 00448 #endif 00449 #if 0 00450 err = snd_pcm_sw_params_set_xfer_align(handle, swparams, PERIOD_FRAMES); 00451 if (err < 0) 00452 ast_log(LOG_ERROR, "Unable to set xfer alignment: %s\n", snd_strerror(err)); 00453 #endif 00454 00455 #if 0 00456 err = snd_pcm_sw_params_set_silence_threshold(handle, swparams, silencethreshold); 00457 if (err < 0) 00458 ast_log(LOG_ERROR, "Unable to set silence threshold: %s\n", snd_strerror(err)); 00459 #endif 00460 err = snd_pcm_sw_params(handle, swparams); 00461 if (err < 0) 00462 ast_log(LOG_ERROR, "sw_params: %s\n", snd_strerror(err)); 00463 00464 err = snd_pcm_poll_descriptors_count(handle); 00465 if (err <= 0) 00466 ast_log(LOG_ERROR, "Unable to get a poll descriptors count, error is %s\n", snd_strerror(err)); 00467 if (err != 1) { 00468 if (option_debug) 00469 ast_log(LOG_DEBUG, "Can't handle more than one device\n"); 00470 } 00471 00472 snd_pcm_poll_descriptors(handle, &pfd, err); 00473 if (option_debug) 00474 ast_log(LOG_DEBUG, "Acquired fd %d from the poll descriptor\n", pfd.fd); 00475 00476 if (stream == SND_PCM_STREAM_CAPTURE) 00477 readdev = pfd.fd; 00478 else 00479 writedev = pfd.fd; 00480 00481 return handle; 00482 }
|
|
||||||||||||||||
|
Definition at line 497 of file chan_alsa.c. References ast_mutex_lock(), ast_mutex_unlock(), and ast_verbose(). 00498 { 00499 ast_mutex_lock(&alsalock); 00500 ast_verbose(" << Console Received digit %c of duration %u ms >> \n", 00501 digit, duration); 00502 ast_mutex_unlock(&alsalock); 00503 return 0; 00504 }
|
|
||||||||||||
|
Definition at line 738 of file chan_alsa.c. References ast_mutex_lock(), ast_mutex_unlock(), chan_alsa_pvt::owner, and ast_channel::tech_pvt. 00739 { 00740 struct chan_alsa_pvt *p = newchan->tech_pvt; 00741 ast_mutex_lock(&alsalock); 00742 p->owner = newchan; 00743 ast_mutex_unlock(&alsalock); 00744 return 0; 00745 }
|
|
|
Definition at line 575 of file chan_alsa.c. References alsa, ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), autoanswer, cursound, chan_alsa_pvt::icard, chan_alsa_pvt::owner, sndcmd, and ast_channel::tech_pvt. 00576 { 00577 int res; 00578 ast_mutex_lock(&alsalock); 00579 cursound = -1; 00580 c->tech_pvt = NULL; 00581 alsa.owner = NULL; 00582 ast_verbose(" << Hangup on console >> \n"); 00583 ast_module_unref(ast_module_info->self); 00584 if (hookstate) { 00585 hookstate = 0; 00586 if (!autoanswer) { 00587 /* Congestion noise */ 00588 res = 2; 00589 write(sndcmd[1], &res, sizeof(res)); 00590 } 00591 } 00592 snd_pcm_drop(alsa.icard); 00593 ast_mutex_unlock(&alsalock); 00594 return 0; 00595 }
|
|
||||||||||||||||||||
|
Definition at line 747 of file chan_alsa.c. References AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), LOG_WARNING, and sndcmd. 00748 { 00749 int res = 0; 00750 00751 ast_mutex_lock(&alsalock); 00752 00753 switch (cond) { 00754 case AST_CONTROL_BUSY: 00755 res = 1; 00756 break; 00757 case AST_CONTROL_CONGESTION: 00758 res = 2; 00759 break; 00760 case AST_CONTROL_RINGING: 00761 break; 00762 case -1: 00763 res = -1; 00764 break; 00765 case AST_CONTROL_VIDUPDATE: 00766 res = -1; 00767 break; 00768 case AST_CONTROL_HOLD: 00769 ast_verbose(" << Console Has Been Placed on Hold >> \n"); 00770 ast_moh_start(chan, data, mohinterpret); 00771 break; 00772 case AST_CONTROL_UNHOLD: 00773 ast_verbose(" << Console Has Been Retrieved from Hold >> \n"); 00774 ast_moh_stop(chan); 00775 break; 00776 default: 00777 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, chan->name); 00778 res = -1; 00779 } 00780 00781 if (res > -1) 00782 write(sndcmd[1], &res, sizeof(res)); 00783 00784 ast_mutex_unlock(&alsalock); 00785 00786 return res; 00787 }
|
|
||||||||||||
|
|
Definition at line 663 of file chan_alsa.c. References ast_channel::_state, alsa, AST_FORMAT_SLINEAR, AST_FRAME_NULL, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_UP, ast_frame::data, ast_frame::datalen, ast_frame::delivery, FRAME_SIZE, ast_frame::frametype, chan_alsa_pvt::icard, LOG_ERROR, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass. 00664 { 00665 static struct ast_frame f; 00666 static short __buf[FRAME_SIZE + AST_FRIENDLY_OFFSET / 2]; 00667 short *buf; 00668 static int readpos = 0; 00669 static int left = FRAME_SIZE; 00670 snd_pcm_state_t state; 00671 int r = 0; 00672 int off = 0; 00673 00674 ast_mutex_lock(&alsalock); 00675 /* Acknowledge any pending cmd */ 00676 f.frametype = AST_FRAME_NULL; 00677 f.subclass = 0; 00678 f.samples = 0; 00679 f.datalen = 0; 00680 f.data = NULL; 00681 f.offset = 0; 00682 f.src = "Console"; 00683 f.mallocd = 0; 00684 f.delivery.tv_sec = 0; 00685 f.delivery.tv_usec = 0; 00686 00687 state = snd_pcm_state(alsa.icard); 00688 if ((state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING)) { 00689 snd_pcm_prepare(alsa.icard); 00690 } 00691 00692 buf = __buf + AST_FRIENDLY_OFFSET / 2; 00693 00694 r = snd_pcm_readi(alsa.icard, buf + readpos, left); 00695 if (r == -EPIPE) { 00696 #if DEBUG 00697 ast_log(LOG_ERROR, "XRUN read\n"); 00698 #endif 00699 snd_pcm_prepare(alsa.icard); 00700 } else if (r == -ESTRPIPE) { 00701 ast_log(LOG_ERROR, "-ESTRPIPE\n"); 00702 snd_pcm_prepare(alsa.icard); 00703 } else if (r < 0) { 00704 ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r)); 00705 } else if (r >= 0) { 00706 off -= r; 00707 } 00708 /* Update positions */ 00709 readpos += r; 00710 left -= r; 00711 00712 if (readpos >= FRAME_SIZE) { 00713 /* A real frame */ 00714 readpos = 0; 00715 left = FRAME_SIZE; 00716 if (chan->_state != AST_STATE_UP) { 00717 /* Don't transmit unless it's up */ 00718 ast_mutex_unlock(&alsalock); 00719 return &f; 00720 } 00721 f.frametype = AST_FRAME_VOICE; 00722 f.subclass = AST_FORMAT_SLINEAR; 00723 f.samples = FRAME_SIZE; 00724 f.datalen = FRAME_SIZE * 2; 00725 f.data = buf; 00726 f.offset = AST_FRIENDLY_OFFSET; 00727 f.src = "Console"; 00728 f.mallocd = 0; 00729 #ifdef ALSA_MONITOR 00730 alsa_monitor_read((char *) buf, FRAME_SIZE * 2); 00731 #endif 00732 00733 } 00734 ast_mutex_unlock(&alsalock); 00735 return &f; 00736 }
|
|
||||||||||||||||||||
|
Definition at line 822 of file chan_alsa.c. References alsa, alsa_new(), AST_CAUSE_BUSY, AST_FORMAT_SLINEAR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, LOG_NOTICE, LOG_WARNING, and chan_alsa_pvt::owner. 00823 { 00824 int oldformat = format; 00825 struct ast_channel *tmp = NULL; 00826 00827 format &= AST_FORMAT_SLINEAR; 00828 if (!format) { 00829 ast_log(LOG_NOTICE, "Asked to get a channel of format '%d'\n", oldformat); 00830 return NULL; 00831 } 00832 00833 ast_mutex_lock(&alsalock); 00834 00835 if (alsa.owner) { 00836 ast_log(LOG_NOTICE, "Already have a call on the ALSA channel\n"); 00837 *cause = AST_CAUSE_BUSY; 00838 } else if (!(tmp = alsa_new(&alsa, AST_STATE_DOWN))) 00839 ast_log(LOG_WARNING, "Unable to create new ALSA channel\n"); 00840 00841 ast_mutex_unlock(&alsalock); 00842 00843 return tmp; 00844 }
|
|
||||||||||||
|
Definition at line 506 of file chan_alsa.c. References ast_mutex_lock(), ast_mutex_unlock(), and ast_verbose(). 00507 { 00508 ast_mutex_lock(&alsalock); 00509 ast_verbose(" << Console Received text %s >> \n", text); 00510 ast_mutex_unlock(&alsalock); 00511 return 0; 00512 }
|
|
||||||||||||
|
Definition at line 597 of file chan_alsa.c. References alsa, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), cursound, ast_frame::data, ast_frame::datalen, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, nosound, chan_alsa_pvt::ocard, and option_debug. 00598 { 00599 static char sizbuf[8000]; 00600 static int sizpos = 0; 00601 int len = sizpos; 00602 int pos; 00603 int res = 0; 00604 /* size_t frames = 0; */ 00605 snd_pcm_state_t state; 00606 00607 /* Immediately return if no sound is enabled */ 00608 if (nosound) 00609 return 0; 00610 00611 ast_mutex_lock(&alsalock); 00612 /* Stop any currently playing sound */ 00613 if (cursound != -1) { 00614 snd_pcm_drop(alsa.ocard); 00615 snd_pcm_prepare(alsa.ocard); 00616 cursound = -1; 00617 } 00618 00619 00620 /* We have to digest the frame in 160-byte portions */ 00621 if (f->datalen > sizeof(sizbuf) - sizpos) { 00622 ast_log(LOG_WARNING, "Frame too large\n"); 00623 res = -1; 00624 } else { 00625 memcpy(sizbuf + sizpos, f->data, f->datalen); 00626 len += f->datalen; 00627 pos = 0; 00628 #ifdef ALSA_MONITOR 00629 alsa_monitor_write(sizbuf, len); 00630 #endif 00631 state = snd_pcm_state(alsa.ocard); 00632 if (state == SND_PCM_STATE_XRUN) 00633 snd_pcm_prepare(alsa.ocard); 00634 res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2); 00635 if (res == -EPIPE) { 00636 #if DEBUG 00637 if (option_debug) 00638 ast_log(LOG_DEBUG, "XRUN write\n"); 00639 #endif 00640 snd_pcm_prepare(alsa.ocard); 00641 res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2); 00642 if (res != len / 2) { 00643 ast_log(LOG_ERROR, "Write error: %s\n", snd_strerror(res)); 00644 res = -1; 00645 } else if (res < 0) { 00646 ast_log(LOG_ERROR, "Write error %s\n", snd_strerror(res)); 00647 res = -1; 00648 } 00649 } else { 00650 if (res == -ESTRPIPE) 00651 ast_log(LOG_ERROR, "You've got some big problems\n"); 00652 else if (res < 0) 00653 ast_log(LOG_NOTICE, "Error %d on write\n", res); 00654 } 00655 } 00656 ast_mutex_unlock(&alsalock); 00657 if (res > 0) 00658 res = 0; 00659 return res; 00660 }
|
|
|
Definition at line 553 of file chan_alsa.c. References nosound, and sndcmd. Referenced by alsa_answer(), and console_answer(). 00554 { 00555 int res; 00556 nosound = 1; 00557 res = 4; 00558 write(sndcmd[1], &res, sizeof(res)); 00559 00560 }
|
|
||||||||||||
|
|
|
|
|
|
||||||||||||||||||||
|
Definition at line 866 of file chan_alsa.c. References ast_strdup, ast_strlen_zero(), and MIN. 00867 { 00868 #ifndef MIN 00869 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 00870 #endif 00871 switch (state) { 00872 case 0: 00873 if (!ast_strlen_zero(word) && !strncasecmp(word, "on", MIN(strlen(word), 2))) 00874 return ast_strdup("on"); 00875 case 1: 00876 if (!ast_strlen_zero(word) && !strncasecmp(word, "off", MIN(strlen(word), 3))) 00877 return |