open() 함수 사용시, Invalid argument 에러 발생

dlatjrwo의 이미지

사운드카드 디바이스를 통한 wav 파일 재생 프로그램 실행 중,
open() 함수을 통하여 장치를 접근하려고 할 때, Invalid argument 에러가 발생합니다.

이 소스코드를 컴파일 환경에서 gcc(Ubuntu 4.4.3-4ubuntu5.1)4.4.3을 통하여 컴파일했을 경우,
문제없이 장치를 사용하였습니다. 헌데, 컴파일 환경에서 arm-Linux-gcc(gcc version 4.3.1)을 통하여
컴파일하고,(컴파일은 문제없이 되었습니다.) 테스트 보드로 실행파일을 옮겨 실행하면 앞서 언급한,
Invalid argument 에러가 발생합니다.
/dev/폴더에서 dsp장치가 인식된 것은 확인하였습니다.
장치에 접근을 못하는 건지, 아니면, 관련 소스에 문제가 있는 것인지, 어떤 문제인지 도통 감이 잡히지 않네요.
도움을 부탁드립니다.

컴파일 환경
- Linux 2.6.32-45-generic #103-Ubuntu SMP i686 GNU/Linux

테스트 보드 실행 환경
- Linux 3.0.15 #4 SMP PREEMPT armv7l GNU/Linux

소스코드

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/ioctl.h>
#include <linux/soundcard.h>
#include <errno.h>
 
#define  SCERR_NO_PROC_DEVICE                      -1    // Thers's no /proc/device 
#define  SCERR_DRIVER_NO_FIND                      -2    // Cannot find driver in /proc/device
#define  SCERR_NO_SOUNDCARD                        -3    // There's no Sound Card
#define  SCERR_NO_MIXER                            -4    // There's no Mixer
#define  SCERR_OPEN_SOUNDCARD                      -5    // Fail to open Sound Card
#define  SCERR_OPEN_MIXER                          -6    // Fail to open Mixer
#define  SCERR_PRIVILEGE_SOUNDCARD                 -7    // No permission using Sound Card
#define  SCERR_PRIVILEGE_MIXER                     -8    // No permission using Mixer
 
#define  SCERR_NO_FILE                             -10   // There's no file
#define  SCERR_NOT_OPEN                            -11   // Cannot open the file
#define  SCERR_NOT_WAV_FILE                        -12   // Is not the WAV file
#define  SCERR_NO_wav_info                       -13   // There's no forman information of WAV
 
#define  BUFF_SIZE            1024
#define  DSP_DEVICE_NAME      "/dev/dsp"               // interface for excution of AU sound file in sound card 
//#define  DSP_DEVICE_NAME      "/dev/audio"               // interface for excution of AU sound file in sound card 
#define  MIXER_DEVICE_NAME    "/dev/mixer"
#define  TRUE                 1
 
typedef  struct
{
   unsigned char     chunk_id[4];
   unsigned long     size;
   unsigned short    tag;
   unsigned short    channels;
   unsigned long     rate;
   unsigned long     avr_samples;
   unsigned short    align;
   unsigned short    data_bit;
} wav_info_t;
 
static int            fd_soundcard     = -1;
static int            fd_mixer         = -1;       // descriptor for volume control
static unsigned long  data_offset      =  0;       // offset for wav play
 
//------------------------------------------------------------------------------
// Description: Program Close after print the Msg
// Factor: format     : print string format ex) "%s%d"
//        ...        : factor to need format
//------------------------------------------------------------------------------
void  printx( const char *_format, ...)
{
   char     *bar  = "-------------------------------";
   va_list   parg;
   int       count;
 
   printf( "%s:ERRORn", bar);
 
   va_start( parg,_format);
   count = vprintf(_format, parg);
   va_end( parg);
 
   printf( "n%sn", bar);
   exit( -1);
}
 
//------------------------------------------------------------------------------
// Description: get the buffer size for sound output
// Return: buffer size for sound output
//------------------------------------------------------------------------------
int   soundcard_get_buff_size( void)
{
   int   size  = 1024;
 
   if ( 0 <= fd_soundcard)
   {
      ioctl( fd_soundcard, SNDCTL_DSP_GETBLKSIZE, &size);
      if ( size < 1024 )
         size  = 1024;
   }
   return size;
}
 
//------------------------------------------------------------------------------
// Desciption: set output of sound card as stereo
// Factor: _enable - 1 : stereo
//                  0 : mono
//------------------------------------------------------------------------------
void  soundcard_set_stereo( int _enable)
{
   if ( 0 <= fd_soundcard)    ioctl( fd_soundcard, SNDCTL_DSP_STEREO, &_enable);
}
//------------------------------------------------------------------------------
// Description: set bit rate of output sound
// Factor : _rate  - bit rate value
//------------------------------------------------------------------------------
void  soundcard_set_bit_rate( int _rate)
{
   if ( 0 <= fd_soundcard)    ioctl( fd_soundcard, SNDCTL_DSP_SPEED, &_rate );
}
 
//------------------------------------------------------------------------------
// Description: set bit size of output sound
// Factor: _size   - bit size of sound data
//------------------------------------------------------------------------------
void  soundcard_set_data_bit_size( int _size)
{
   if ( 0 <= fd_soundcard)    ioctl( fd_soundcard, SNDCTL_DSP_SAMPLESIZE, &_size);
}
 
//------------------------------------------------------------------------------
// Description: set sound card volume
// Factor: _channel - the chennel number
//             Headphone volume : SOUND_MIXER_WRITE_VOLUME
//             PCM	 volume : SOUND_MIXER_WRITE_PCM
//             Speaker	 volume : SOUND_MIXER_WRITE_SPEAKER
//             Line	 volume : SOUND_MIXER_WRITE_LINE
//             Mic	 volume : SOUND_MIXER_WRITE_MIC
//             CD	 volume : SOUND_MIXER_WRITE_CD
//             PCM2	 volume : SOUND_MIXER_WRITE_ALTPCM    main) Speaker volume of ESP-MMI
//             IGain	 volume : SOUND_MIXER_WRITE_IGAIN
//             Line 1	 volume : SOUND_MIXER_WRITE_LINE1
//       _left : left or low value of volume
//       _right: right or high value of volume
//------------------------------------------------------------------------------
void soundcard_set_volume( int _channel, int _left, int _right )
{
   int volume;
 
   if ( 120 < _left  ) _left  = 120;
   if ( 120 < _right ) _right = 120;
 
   volume = 256 *_right +_left;
   ioctl( fd_mixer, _channel, &volume );
}
 
//--------------------------------------------------------------------
// Description: Open for play the wav file
// Detail: Possible only wav file 
// Factor: _filename   : Name of wav file
// Return: 0 < Success in file open
//       0 > Fail to file open & Error code
//--------------------------------------------------------------------
int   soundcard_open_file( char *_filename)
{
   int            fd_wavfile;
   int            read_size;
   unsigned char  buff[BUFF_SIZE+5];
 
   wav_info_t    *p_wav_info;
   wav_info_t     wav_info;
   unsigned char *ptr;
 
   if ( 0 != access(_filename, R_OK ) )                              // No file
      return SCERR_NO_FILE;
 
   fd_wavfile = open(_filename, O_RDONLY );
   if ( 0 > fd_wavfile)                                              // Fail to file open
      return SCERR_NOT_OPEN;
 
                                 // Header processing
 
   memset( buff, 0 , BUFF_SIZE);
   read_size = read( fd_wavfile, buff, BUFF_SIZE);
 
   if ( 0 == memmem( buff, BUFF_SIZE, "RIFF", 4 ))         // examine whether "RIFF" string is.
      return SCERR_NOT_WAV_FILE;
 
   if ( 0 == memmem( buff, BUFF_SIZE, "WAVE", 4 ))         // examine whether "WAVE" string is.
      return SCERR_NOT_WAV_FILE;
 
 
   p_wav_info = (wav_info_t *)memmem( buff, BUFF_SIZE, "fmt ", 4 ); // get the format information
   if ( NULL == p_wav_info)
      return SCERR_NO_wav_info;
 
   memcpy( &wav_info, p_wav_info, sizeof(wav_info_t) );
 
                                 //   printf( "CHANNEL   = %dn", (int) wav_info.channels );
                                 //   printf( "DATA BITS = %dn", (int) wav_info.data_bit);
                                 //   printf( "RATE      = %dn", (int) wav_info.rate);
 
   ptr = (unsigned char *)memmem( buff, BUFF_SIZE, "data", 4 );
   ptr += 8;
 
   data_offset = (unsigned long)( ptr - buff );
 
   lseek( fd_wavfile, data_offset , SEEK_SET );         // move to data offset file read offset
   soundcard_set_stereo       ( wav_info.channels >= 2 ? 1 : 0);   // enable sound춖tereo mode
   soundcard_set_data_bit_size( wav_info.data_bit             );   // set sound data size
   soundcard_set_bit_rate     ( wav_info.rate                 );   // set sound bit rate
 
   return fd_wavfile;
}
 
//--------------------------------------------------------------------
// Description: Close for quit to use sound card
//--------------------------------------------------------------------
void soundcard_close( void)
{
   close( fd_soundcard);
   close( fd_mixer    );
}
 
//--------------------------------------------------------------------
// Description: Open for using Sound Card
// Factor: _mode - PLAYER    : Private Play 
// Factor: _mode - RECORDER   : Private Recorder
// Factor: _mode - AUDIO     : Play and Record
// Return: Sound Card file descriptor
//--------------------------------------------------------------------
int   soundcard_open(int _mode)
{
   char  *dsp_devname   = DSP_DEVICE_NAME;
   char  *mixer_devname = MIXER_DEVICE_NAME;
 
   // Open Sound Card device
   if ( 0 != access( dsp_devname, W_OK ) )
      return SCERR_PRIVILEGE_SOUNDCARD;
 
   printf(" dsp_devname : %s \n", dsp_devname);
   printf(" _mode : %d\n", _mode);
 
   fd_soundcard = open( dsp_devname, _mode );
   if ( 0 > fd_soundcard ) {
      printf("\n***** Error : %d ********\n", fd_soundcard);
      perror("file open error:");
      return SCERR_OPEN_SOUNDCARD;
   }
 
   // Open MIXER
 
   if ( 0 != access( mixer_devname, W_OK ) )
      return SCERR_PRIVILEGE_MIXER;
 
   fd_mixer = open( mixer_devname, O_RDWR|O_NDELAY );
   if ( 0 > fd_soundcard)
      return SCERR_OPEN_MIXER;
 
   return fd_soundcard;
}
 
//--------------------------------------------------------------------
// Description: Save to "test.wav" recoarded during 10sec using sound card
//--------------------------------------------------------------------
int main( int argc, char **argv )
{
   int      fd_soundcard;
   int      fd_wav_file;
   char    *sound_buff;                                 // buffer for sound output
   int      sound_buff_size;
   int      read_size;
 
   if ( 2 > argc)
      printx( "usage: ./exe [wave file name]");
 
   fd_soundcard   = soundcard_open( O_WRONLY);
 
   printf("\n***** fd_soundcard 	: %d ********\n", fd_soundcard);
   printf("\n***** Error 		: %s ********\n", strerror(errno));
 
   switch( fd_soundcard)
   {
   case  SCERR_NO_PROC_DEVICE       :  printx( "Do not have /proc/device");
   case  SCERR_NO_SOUNDCARD         :  printx( "Do not have  Sound Card");
   case  SCERR_NO_MIXER             :  printx( "Do not have Mixer");
   case  SCERR_PRIVILEGE_SOUNDCARD  :  printx( "No permission using Sound Card");
   case  SCERR_PRIVILEGE_MIXER      :  printx( "No permission using Mixer device");
   case  SCERR_OPEN_SOUNDCARD       :  printx( "Cannot open Sound Card");
   case  SCERR_OPEN_MIXER           :  printx( "Cnanot open Mixer device");
   }
   soundcard_set_volume( SOUND_MIXER_WRITE_ALTPCM, 100, 100);
   soundcard_set_volume( SOUND_MIXER_WRITE_MIC   , 80, 80);
   soundcard_set_volume( SOUND_MIXER_WRITE_IGAIN , 60, 60);
 
   sound_buff_size   = soundcard_get_buff_size();
   sound_buff        = ( char *)malloc( sound_buff_size);
 
   fd_wav_file   = soundcard_open_file( argv[1]);               // open the wave file to output
   switch( fd_wav_file)
   {
   case  SCERR_NO_FILE        :  printx( "There's no WAV file");
   case  SCERR_NOT_OPEN       :  printx( "Cannot open WAV file");
   case  SCERR_NOT_WAV_FILE   :  printx( "It's not WAV file");
   case  SCERR_NO_wav_info    :  printx( "There's no WAV Information");
   }
 
   while( 1)
   {
      read_size = read( fd_wav_file, &sound_buff[0], soundcard_get_buff_size());
      if( 0 < read_size)
      {
         write( fd_soundcard, &sound_buff[0], read_size );
      }
      else
         break;
   }
   close( fd_wav_file);
   soundcard_close();
   return 0;
}
poplinux의 이미지

ioctl() 호출에 사용한 argument 가 커널단 안에서는 구현이 안되어 있는 상태인 것 같습니다.

타겟 보드의 커널 소스나 드라이버 소스를 확인하셔서 사용하신 cmd 를 지원하는지 확인해 보십시요.

========================
조직 : E.L.D(Embedded Linux Developer/Designer)
블로그 : poplinux@tistory.com
카페 : cafe.naver.com/poplinux

임베디드 리눅스 관련 프리렌서 지향

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.