You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
3.4KB

  1. /*
  2. * Linux audio play and grab interface
  3. * Copyright (c) 2000, 2001 Fabrice Bellard
  4. *
  5. * This file is part of Libav.
  6. *
  7. * Libav is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * Libav is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with Libav; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "config.h"
  22. #include <string.h>
  23. #if HAVE_SOUNDCARD_H
  24. #include <soundcard.h>
  25. #else
  26. #include <sys/soundcard.h>
  27. #endif
  28. #include <unistd.h>
  29. #include <fcntl.h>
  30. #include <sys/ioctl.h>
  31. #include "libavutil/log.h"
  32. #include "libavcodec/avcodec.h"
  33. #include "libavformat/avformat.h"
  34. #include "oss_audio.h"
  35. int ff_oss_audio_open(AVFormatContext *s1, int is_output,
  36. const char *audio_device)
  37. {
  38. OSSAudioData *s = s1->priv_data;
  39. int audio_fd;
  40. int tmp, err;
  41. char *flip = getenv("AUDIO_FLIP_LEFT");
  42. if (is_output)
  43. audio_fd = avpriv_open(audio_device, O_WRONLY);
  44. else
  45. audio_fd = avpriv_open(audio_device, O_RDONLY);
  46. if (audio_fd < 0) {
  47. av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, strerror(errno));
  48. return AVERROR(EIO);
  49. }
  50. if (flip && *flip == '1') {
  51. s->flip_left = 1;
  52. }
  53. /* non blocking mode */
  54. if (!is_output)
  55. fcntl(audio_fd, F_SETFL, O_NONBLOCK);
  56. s->frame_size = OSS_AUDIO_BLOCK_SIZE;
  57. /* select format : favour native format */
  58. err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp);
  59. #if HAVE_BIGENDIAN
  60. if (tmp & AFMT_S16_BE) {
  61. tmp = AFMT_S16_BE;
  62. } else if (tmp & AFMT_S16_LE) {
  63. tmp = AFMT_S16_LE;
  64. } else {
  65. tmp = 0;
  66. }
  67. #else
  68. if (tmp & AFMT_S16_LE) {
  69. tmp = AFMT_S16_LE;
  70. } else if (tmp & AFMT_S16_BE) {
  71. tmp = AFMT_S16_BE;
  72. } else {
  73. tmp = 0;
  74. }
  75. #endif
  76. switch(tmp) {
  77. case AFMT_S16_LE:
  78. s->codec_id = AV_CODEC_ID_PCM_S16LE;
  79. break;
  80. case AFMT_S16_BE:
  81. s->codec_id = AV_CODEC_ID_PCM_S16BE;
  82. break;
  83. default:
  84. av_log(s1, AV_LOG_ERROR, "Soundcard does not support 16 bit sample format\n");
  85. close(audio_fd);
  86. return AVERROR(EIO);
  87. }
  88. err=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &tmp);
  89. if (err < 0) {
  90. av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SETFMT: %s\n", strerror(errno));
  91. goto fail;
  92. }
  93. tmp = (s->channels == 2);
  94. err = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
  95. if (err < 0) {
  96. av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_STEREO: %s\n", strerror(errno));
  97. goto fail;
  98. }
  99. tmp = s->sample_rate;
  100. err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp);
  101. if (err < 0) {
  102. av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SPEED: %s\n", strerror(errno));
  103. goto fail;
  104. }
  105. s->sample_rate = tmp; /* store real sample rate */
  106. s->fd = audio_fd;
  107. return 0;
  108. fail:
  109. close(audio_fd);
  110. return AVERROR(EIO);
  111. }
  112. int ff_oss_audio_close(OSSAudioData *s)
  113. {
  114. close(s->fd);
  115. return 0;
  116. }