Changeset 319


Ignore:
Timestamp:
Mar 15, 2006 8:56:04 PM (19 years ago)
Author:
bennylp
Message:

Tidying up sound device, register PortAudio? error codes, and initial support for stereo sound device (untested)

Location:
pjproject/trunk/pjmedia
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia/errno.h

    r222 r319  
    3131 
    3232 
     33/* 
     34 * Mapping from PortAudio error codes to pjmedia error space. 
     35 */ 
     36#define PJMEDIA_PORTAUDIO_ERRNO_START (PJMEDIA_ERRNO_START+PJ_ERRNO_SPACE_SIZE-1000) 
     37 
     38/* 
     39 * Convert PortAudio error code to PJMEDIA error code. 
     40 */ 
     41#define PJMEDIA_ERRNO_FROM_PORTAUDIO(err)   (err+PJMEDIA_PORTAUDIO_ERRNO_START) 
     42 
     43 
    3344/************************************************************ 
    3445 * GENERIC/GENERAL PJMEDIA ERRORS 
  • pjproject/trunk/pjmedia/include/pjmedia/sound.h

    r188 r319  
    4949    unsigned    default_samples_per_sec;/**< Default sampling rate.         */ 
    5050} pj_snd_dev_info; 
    51  
    52 /** 
    53  * Sound device parameter, to be specified when calling #pj_snd_open_recorder 
    54  * or #pj_snd_open_player. 
    55  */ 
    56 typedef struct pj_snd_stream_info 
    57 { 
    58     unsigned samples_per_sec;           /**< Sampling rate.             */ 
    59     unsigned bits_per_sample;           /**< No of bits per sample.     */ 
    60     unsigned samples_per_frame;         /**< No of samples per frame.   */ 
    61     unsigned bytes_per_frame;           /**< No of bytes per frame.     */ 
    62     unsigned frames_per_packet;         /**< No of frames per packet.   */ 
    63 } pj_snd_stream_info; 
    6451 
    6552/**  
     
    135122 * @return              Audio stream, or NULL if failed. 
    136123 */ 
    137 PJ_DECL(pj_snd_stream*) pj_snd_open_recorder(int index, 
    138                                              const pj_snd_stream_info *param, 
    139                                              pj_snd_rec_cb rec_cb, 
    140                                              void *user_data); 
     124PJ_DECL(pj_status_t) pj_snd_open_recorder( int index, 
     125                                           unsigned clock_rate, 
     126                                           unsigned channel_count, 
     127                                           unsigned samples_per_frame, 
     128                                           unsigned bits_per_sample, 
     129                                           pj_snd_rec_cb rec_cb, 
     130                                           void *user_data, 
     131                                           pj_snd_stream **p_snd_strm); 
    141132 
    142133/** 
     
    151142 * @return              Audio stream, or NULL if failed. 
    152143 */ 
    153 PJ_DECL(pj_snd_stream*) pj_snd_open_player(int index, 
    154                                            const pj_snd_stream_info *param, 
    155                                            pj_snd_play_cb play_cb, 
    156                                            void *user_data); 
     144PJ_DECL(pj_status_t) pj_snd_open_player( int index, 
     145                                         unsigned clock_rate, 
     146                                         unsigned channel_count, 
     147                                         unsigned samples_per_frame, 
     148                                         unsigned bits_per_sample, 
     149                                         pj_snd_play_cb play_cb, 
     150                                         void *user_data, 
     151                                         pj_snd_stream **p_snd_strm ); 
    157152 
    158153/** 
  • pjproject/trunk/pjmedia/src/pjmedia/conference.c

    r318 r319  
    140140    unsigned              samples_per_frame;    /**< Samples per frame.     */ 
    141141    unsigned              bits_per_sample;      /**< Bits per sample.       */ 
    142     pj_snd_stream_info    snd_info;     /**< Sound device parameter.        */ 
    143142}; 
    144143 
     
    287286 
    288287 
    289     /* Init default sound device parameters. */ 
    290     pj_memset(&conf->snd_info, 0, sizeof(conf->snd_info)); 
    291     conf->snd_info.samples_per_sec = conf->clock_rate; 
    292     conf->snd_info.bits_per_sample = conf->bits_per_sample; 
    293     conf->snd_info.samples_per_frame = conf->samples_per_frame; 
    294     conf->snd_info.bytes_per_frame = conf->samples_per_frame *  
    295                                conf->bits_per_sample / 8; 
    296     conf->snd_info.frames_per_packet = 1; 
    297      
    298288 
    299289    /* Create port */ 
     
    389379static pj_status_t create_sound( pjmedia_conf *conf ) 
    390380{ 
     381    pj_status_t status; 
     382 
    391383    /* Open recorder only if mic is not disabled. */ 
    392384    if ((conf->options & PJMEDIA_CONF_NO_MIC) == 0) { 
    393         conf->snd_rec = pj_snd_open_recorder(-1 ,&conf->snd_info,  
    394                                              &rec_cb, conf); 
    395         if (conf->snd_rec == NULL) { 
    396             return -1; 
     385        status = pj_snd_open_recorder(-1, conf->clock_rate, 1,  
     386                                      conf->samples_per_frame, 
     387                                      conf->bits_per_sample, 
     388                                      &rec_cb, conf, &conf->snd_rec); 
     389        if (status != PJ_SUCCESS) { 
     390            conf->snd_rec = NULL; 
     391            return status; 
    397392        } 
    398393    } 
    399394 
    400395    /* Open player */ 
    401     conf->snd_player = pj_snd_open_player(-1, &conf->snd_info, &play_cb, conf); 
    402     if (conf->snd_player == NULL) { 
     396    status = pj_snd_open_player(-1, conf->clock_rate, 1, 
     397                                conf->samples_per_frame, 
     398                                conf->bits_per_sample,  
     399                                &play_cb, conf, &conf->snd_player); 
     400    if (status != PJ_SUCCESS) { 
    403401        if (conf->snd_rec) { 
    404402            pj_snd_stream_close(conf->snd_rec); 
     403            conf->snd_rec = NULL; 
    405404        } 
    406         return -1; 
     405        conf->snd_player = NULL; 
     406        return status; 
    407407    } 
    408408 
  • pjproject/trunk/pjmedia/src/pjmedia/errno.c

    r315 r319  
    1919#include <pjmedia/errno.h> 
    2020#include <pj/string.h> 
     21#include <portaudio.h> 
    2122 
    2223 
     
    130131    pj_str_t errstr; 
    131132 
    132     if (statcode >= PJMEDIA_ERRNO_START &&  
    133         statcode < PJMEDIA_ERRNO_START + PJ_ERRNO_SPACE_SIZE) 
     133    /* See if the error comes from PortAudio. */ 
     134    if (statcode >= PJMEDIA_ERRNO_FROM_PORTAUDIO(paNotInitialized) && 
     135        statcode <  PJMEDIA_ERRNO_FROM_PORTAUDIO(paNotInitialized + 10000)) 
     136    { 
     137 
     138        int pa_err = statcode - PJMEDIA_ERRNO_FROM_PORTAUDIO(0); 
     139        pj_str_t msg; 
     140         
     141        msg.ptr = (char*)Pa_GetErrorText(pa_err); 
     142        msg.slen = pj_ansi_strlen(msg.ptr); 
     143 
     144        errstr.ptr = buf; 
     145        pj_strncpy_with_null(&errstr, &msg, bufsize); 
     146        return errstr; 
     147 
     148    } else if (statcode >= PJMEDIA_ERRNO_START &&  
     149               statcode < PJMEDIA_ERRNO_START + PJ_ERRNO_SPACE_SIZE) 
    134150    { 
    135151        /* Find the error in the table. 
  • pjproject/trunk/pjmedia/src/pjmedia/pasound.c

    r245 r319  
    1818 */ 
    1919#include <pjmedia/sound.h> 
     20#include <pjmedia/errno.h> 
     21#include <pj/log.h> 
     22#include <pj/os.h> 
    2023#include <pj/string.h> 
    21 #include <pj/os.h> 
    22 #include <pj/log.h> 
    2324#include <portaudio.h> 
    2425 
     
    3839    int              bytes_per_sample; 
    3940    pj_uint32_t      samples_per_sec; 
     41    int              channel_count; 
    4042    pj_uint32_t      timestamp; 
    4143    pj_uint32_t      underflow; 
     
    189191 * Open stream. 
    190192 */ 
    191 PJ_DEF(pj_snd_stream*) pj_snd_open_recorder( int index, 
    192                                              const pj_snd_stream_info *param, 
    193                                              pj_snd_rec_cb rec_cb, 
    194                                              void *user_data) 
     193PJ_DEF(pj_status_t) pj_snd_open_recorder( int index, 
     194                                          unsigned clock_rate, 
     195                                          unsigned channel_count, 
     196                                          unsigned samples_per_frame, 
     197                                          unsigned bits_per_sample, 
     198                                          pj_snd_rec_cb rec_cb, 
     199                                          void *user_data, 
     200                                          pj_snd_stream **p_snd_strm) 
    195201{ 
    196202    pj_pool_t *pool; 
     
    209215        } 
    210216        if (index == count) { 
    211             PJ_LOG(2,(THIS_FILE, "Error: unable to find recorder device")); 
    212             return NULL; 
     217            /* No such device. */ 
     218            return PJ_ENOTFOUND; 
    213219        } 
    214220    } else { 
    215221        paDevInfo = Pa_GetDeviceInfo(index); 
    216         if (!paDevInfo) 
    217             return NULL; 
    218     } 
    219  
    220     if (param->bits_per_sample == 8) 
     222        if (!paDevInfo) { 
     223            /* Assumed it is "No such device" error. */ 
     224            return PJ_ENOTFOUND; 
     225        } 
     226    } 
     227 
     228    if (bits_per_sample == 8) 
    221229        sampleFormat = paUInt8; 
    222     else if (param->bits_per_sample == 16) 
     230    else if (bits_per_sample == 16) 
    223231        sampleFormat = paInt16; 
    224     else if (param->bits_per_sample == 32) 
     232    else if (bits_per_sample == 32) 
    225233        sampleFormat = paInt32; 
    226234    else 
    227         return NULL; 
     235        return PJ_ENOTSUP; 
    228236     
    229237    pool = pj_pool_create( snd_mgr.factory, "sndstream", 1024, 1024, NULL); 
    230238    if (!pool) 
    231         return NULL; 
    232  
    233     stream = pj_pool_calloc(pool, 1, sizeof(*stream)); 
     239        return PJ_ENOMEM; 
     240 
     241    stream = pj_pool_zalloc(pool, sizeof(*stream)); 
    234242    stream->pool = pool; 
    235     stream->name = pj_str("recorder"); 
     243    stream->name = pj_str("snd-rec"); 
    236244    stream->user_data = user_data; 
    237245    stream->dev_index = index; 
    238     stream->samples_per_sec = param->samples_per_frame; 
    239     stream->bytes_per_sample = param->bits_per_sample / 8; 
     246    stream->samples_per_sec = samples_per_frame; 
     247    stream->bytes_per_sample = bits_per_sample / 8; 
     248    stream->channel_count = channel_count; 
    240249    stream->rec_cb = rec_cb; 
    241250 
    242251    pj_memset(&inputParam, 0, sizeof(inputParam)); 
    243252    inputParam.device = index; 
    244     inputParam.channelCount = 1; 
     253    inputParam.channelCount = channel_count; 
    245254    inputParam.hostApiSpecificStreamInfo = NULL; 
    246255    inputParam.sampleFormat = sampleFormat; 
     
    248257 
    249258    err = Pa_OpenStream( &stream->stream, &inputParam, NULL, 
    250                          param->samples_per_sec,  
    251                          param->samples_per_frame * param->frames_per_packet,  
    252                          0, 
    253                          &PaRecorderCallback, stream ); 
     259                         clock_rate, samples_per_frame,  
     260                         0, &PaRecorderCallback, stream ); 
    254261    if (err != paNoError) { 
    255262        pj_pool_release(pool); 
    256         PJ_LOG(2,(THIS_FILE, "Error opening player: %s", Pa_GetErrorText(err))); 
    257         return NULL; 
     263        return PJMEDIA_ERRNO_FROM_PORTAUDIO(err); 
    258264    } 
    259265 
    260266    PJ_LOG(5,(THIS_FILE, "%s opening device %s for recording, sample rate=%d, " 
     267                         "channel count=%d, " 
    261268                         "%d bits per sample, %d samples per buffer", 
    262269                         (err==0 ? "Success" : "Error"), 
    263                          paDevInfo->name, param->samples_per_sec,  
    264                          param->bits_per_sample, 
    265                          param->samples_per_frame * param->frames_per_packet)); 
    266  
    267     return stream; 
    268 } 
    269  
    270  
    271 PJ_DEF(pj_snd_stream*) pj_snd_open_player(int index, 
    272                                            const pj_snd_stream_info *param, 
    273                                            pj_snd_play_cb play_cb, 
    274                                            void *user_data) 
     270                         paDevInfo->name, clock_rate, channel_count, 
     271                         bits_per_sample, samples_per_frame)); 
     272 
     273    *p_snd_strm = stream; 
     274    return PJ_SUCCESS; 
     275} 
     276 
     277 
     278PJ_DEF(pj_status_t) pj_snd_open_player( int index, 
     279                                        unsigned clock_rate, 
     280                                        unsigned channel_count, 
     281                                        unsigned samples_per_frame, 
     282                                        unsigned bits_per_sample, 
     283                                        pj_snd_play_cb play_cb, 
     284                                        void *user_data, 
     285                                        pj_snd_stream **p_snd_strm) 
    275286{ 
    276287    pj_pool_t *pool; 
     
    289300        } 
    290301        if (index == count) { 
    291             PJ_LOG(2,(THIS_FILE, "Error: unable to find player device")); 
    292             return NULL; 
     302            /* No such device. */ 
     303            return PJ_ENOTFOUND; 
    293304        } 
    294305    } else { 
    295306        paDevInfo = Pa_GetDeviceInfo(index); 
    296         if (!paDevInfo) 
    297             return NULL; 
    298     } 
    299  
    300     if (param->bits_per_sample == 8) 
     307        if (!paDevInfo) { 
     308            /* Assumed it is "No such device" error. */ 
     309            return PJ_ENOTFOUND; 
     310        } 
     311    } 
     312 
     313    if (bits_per_sample == 8) 
    301314        sampleFormat = paUInt8; 
    302     else if (param->bits_per_sample == 16) 
     315    else if (bits_per_sample == 16) 
    303316        sampleFormat = paInt16; 
    304     else if (param->bits_per_sample == 32) 
     317    else if (bits_per_sample == 32) 
    305318        sampleFormat = paInt32; 
    306319    else 
    307         return NULL; 
     320        return PJ_ENOTSUP; 
    308321     
    309322    pool = pj_pool_create( snd_mgr.factory, "sndstream", 1024, 1024, NULL); 
    310323    if (!pool) 
    311         return NULL; 
     324        return PJ_ENOMEM; 
    312325 
    313326    stream = pj_pool_calloc(pool, 1, sizeof(*stream)); 
     
    315328    stream->name = pj_str("player"); 
    316329    stream->user_data = user_data; 
    317     stream->samples_per_sec = param->samples_per_frame; 
    318     stream->bytes_per_sample = param->bits_per_sample / 8; 
     330    stream->samples_per_sec = samples_per_frame; 
     331    stream->bytes_per_sample = bits_per_sample / 8; 
     332    stream->channel_count = channel_count; 
    319333    stream->dev_index = index; 
    320334    stream->play_cb = play_cb; 
     
    322336    pj_memset(&outputParam, 0, sizeof(outputParam)); 
    323337    outputParam.device = index; 
    324     outputParam.channelCount = 1; 
     338    outputParam.channelCount = channel_count; 
    325339    outputParam.hostApiSpecificStreamInfo = NULL; 
    326340    outputParam.sampleFormat = sampleFormat; 
     
    328342 
    329343    err = Pa_OpenStream( &stream->stream, NULL, &outputParam, 
    330                          param->samples_per_sec,  
    331                          param->samples_per_frame * param->frames_per_packet,  
    332                          0, 
    333                          &PaPlayerCallback, stream ); 
     344                         clock_rate,  samples_per_frame,  
     345                         0, &PaPlayerCallback, stream ); 
    334346    if (err != paNoError) { 
    335347        pj_pool_release(pool); 
    336         PJ_LOG(2,(THIS_FILE, "Error opening player: %s", Pa_GetErrorText(err))); 
    337         return NULL; 
     348        return PJMEDIA_ERRNO_FROM_PORTAUDIO(err); 
    338349    } 
    339350 
    340351    PJ_LOG(5,(THIS_FILE, "%s opening device %s for playing, sample rate=%d, " 
     352                         "channel count=%d, " 
    341353                         "%d bits per sample, %d samples per buffer", 
    342354                         (err==0 ? "Success" : "Error"), 
    343                          paDevInfo->name, param->samples_per_sec,  
    344                          param->bits_per_sample, 
    345                          param->samples_per_frame * param->frames_per_packet)); 
    346  
    347     return stream; 
     355                         paDevInfo->name, clock_rate, channel_count, 
     356                         bits_per_sample, samples_per_frame)); 
     357 
     358    *p_snd_strm = stream; 
     359 
     360    return PJ_SUCCESS; 
    348361} 
    349362 
  • pjproject/trunk/pjmedia/src/pjmedia/portaudio/portaudio.h

    r65 r319  
    6565    paNoError = 0, 
    6666 
    67     paNotInitialized = -10000, 
     67    paNotInitialized = 1,   /* blp: changed from -10000 */ 
    6868    paUnanticipatedHostError, 
    6969    paInvalidChannelCount, 
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r311 r319  
    5454    unsigned                pt;             /**< Payload type.              */ 
    5555    pj_bool_t               paused;         /**< Paused?.                   */ 
    56     pj_snd_stream_info      snd_info;       /**< Sound stream param.        */ 
    57     //pj_snd_stream        *snd_stream;     /**< Sound stream.              */ 
    5856    unsigned                in_pkt_size;    /**< Size of input buffer.      */ 
    5957    void                   *in_pkt;         /**< Input buffer.              */ 
     
    279277 
    280278    /* Number of samples in the frame */ 
    281     ts_len = frame->size / (channel->snd_info.bits_per_sample / 8); 
     279    ts_len = frame->size / 2; 
    282280 
    283281    /* Init frame_out buffer. */ 
     
    565563 
    566564/* 
    567  * Create sound stream parameter from codec attributes. 
    568  */ 
    569 static void init_snd_param( pj_snd_stream_info *snd_param, 
    570                             const pjmedia_codec_param *codec_param) 
    571 { 
    572     pj_memset(snd_param, 0, sizeof(*snd_param)); 
    573  
    574     snd_param->bits_per_sample   = codec_param->pcm_bits_per_sample; 
    575     snd_param->bytes_per_frame   = 2; 
    576     snd_param->frames_per_packet = codec_param->sample_rate *  
    577                                    codec_param->ptime /  
    578                                    1000; 
    579     snd_param->samples_per_frame = 1; 
    580     snd_param->samples_per_sec   = codec_param->sample_rate; 
    581 } 
    582  
    583  
    584 /* 
    585565 * Create media channel. 
    586566 */ 
     
    643623    if (status != PJ_SUCCESS) 
    644624        return status; 
    645  
    646     /* Create and initialize sound device */ 
    647  
    648     init_snd_param(&channel->snd_info, codec_param); 
    649  
    650     /* 
    651     if (dir == PJMEDIA_DIR_ENCODING) 
    652         channel->snd_stream = pj_snd_open_recorder(-1, &channel->snd_info,  
    653                                                    &rec_callback, channel); 
    654     else 
    655         channel->snd_stream = pj_snd_open_player(-1, &channel->snd_info,  
    656                                                  &play_callback, channel); 
    657  
    658     if (!channel->snd_stream) 
    659         return -1; 
    660     */ 
    661625 
    662626    /* Done. */ 
Note: See TracChangeset for help on using the changeset viewer.