Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 57e8b3b in mainline


Ignore:
Timestamp:
2012-07-15T15:25:43Z (10 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial
Children:
5cd5079
Parents:
2cc5c835
Message:

Add frame count to event report.

This enables applications to detect underruns.

Location:
uspace
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/dplay/dplay.c

    r2cc5c835 r57e8b3b  
    5151
    5252#define DEFAULT_DEVICE "/hw/pci0/00:01.0/sb16/pcm"
    53 #define SUBBUFFERS 2
     53#define BUFFER_PARTS 2
    5454
    5555typedef struct {
     
    8585        async_answer_0(iid, EOK);
    8686        playback_t *pb = arg;
    87         const size_t buffer_part = pb->buffer.size / SUBBUFFERS;
     87        const size_t buffer_part = pb->buffer.size / BUFFER_PARTS;
    8888        while (1) {
    8989                ipc_call_t call;
    9090                ipc_callid_t callid = async_get_call(&call);
    9191                switch(IPC_GET_IMETHOD(call)) {
    92                 case PCM_EVENT_PLAYBACK_DONE:
    93                         printf("+");
     92                case PCM_EVENT_FRAMES_PLAYED:
     93                        printf("%u frames\n", IPC_GET_ARG1(call));
    9494                        async_answer_0(callid, EOK);
    9595                        break;
    9696                case PCM_EVENT_PLAYBACK_TERMINATED:
    97                         printf("\nPlayback terminated\n");
     97                        printf("Playback terminated\n");
    9898                        fibril_mutex_lock(&pb->mutex);
    9999                        pb->playing = false;
     
    136136        printf("Buffer data ready.\n");
    137137        fibril_mutex_lock(&pb->mutex);
     138        const unsigned frames = pb->buffer.size /
     139            (BUFFER_PARTS * channels * pcm_sample_format_size(format));
    138140        int ret = audio_pcm_start_playback(pb->device,
    139             SUBBUFFERS, channels, sampling_rate, format);
     141            frames, channels, sampling_rate, format);
    140142        if (ret != EOK) {
    141143                fibril_mutex_unlock(&pb->mutex);
  • uspace/app/drec/drec.c

    r2cc5c835 r57e8b3b  
    5252
    5353#define DEFAULT_DEVICE "/hw/pci0/00:01.0/sb16/pcm"
    54 #define SUBBUFFERS 2
     54#define BUFFER_PARTS 2
    5555
    5656const unsigned sampling_rate = 44100, channels = 2, sample_size = 16;
     
    8484        async_answer_0(iid, EOK);
    8585        record_t *rec = arg;
    86         const size_t buffer_part = rec->buffer.size / SUBBUFFERS;
     86        const size_t buffer_part = rec->buffer.size / BUFFER_PARTS;
    8787        while (1) {
    8888                ipc_call_t call;
    8989                ipc_callid_t callid = async_get_call(&call);
    9090                switch(IPC_GET_IMETHOD(call)) {
    91                 case PCM_EVENT_RECORDING_DONE:
    92                         printf("+");
     91                case PCM_EVENT_FRAMES_RECORDED:
     92                        printf("%u frames\n", IPC_GET_ARG1(call));
    9393                        async_answer_0(callid, EOK);
    9494                        break;
    9595                case PCM_EVENT_RECORDING_TERMINATED:
    96                         printf("\nRecording terminated\n");
     96                        printf("Recording terminated\n");
    9797                        return;
    9898                default:
     
    122122        printf("Recording: %dHz, %s, %d channel(s).\n",
    123123            sampling_rate, pcm_sample_format_str(format), channels);
     124        const unsigned frames = rec->buffer.size /
     125            (BUFFER_PARTS * channels * pcm_sample_format_size(format));
    124126        int ret = audio_pcm_start_record(rec->device,
    125             SUBBUFFERS, channels, sampling_rate, format);
     127            frames, channels, sampling_rate, format);
    126128        if (ret != EOK) {
    127129                printf("Failed to start recording: %s.\n", str_error(ret));
  • uspace/drv/audio/sb16/dsp.c

    r2cc5c835 r57e8b3b  
    188188{
    189189        assert(dsp);
     190        dsp->active.frame_count +=
     191            dsp->active.samples / ((dsp->active.mode & DSP_MODE_STEREO) ? 2 : 1);
     192
    190193        if (dsp->event_exchange) {
    191194                switch (dsp->status) {
    192195                case DSP_PLAYBACK:
    193                         async_msg_0(dsp->event_exchange,
    194                             PCM_EVENT_PLAYBACK_DONE);
     196                        async_msg_1(dsp->event_exchange,
     197                            PCM_EVENT_FRAMES_PLAYED, dsp->active.frame_count);
    195198                        break;
    196199                case DSP_RECORDING:
    197                         async_msg_0(dsp->event_exchange,
    198                             PCM_EVENT_RECORDING_DONE);
     200                        async_msg_1(dsp->event_exchange,
     201                            PCM_EVENT_FRAMES_RECORDED, dsp->active.frame_count);
    199202                        break;
    200203                default:
     
    267270}
    268271
    269 int sb_dsp_start_playback(sb_dsp_t *dsp, unsigned parts,
     272int sb_dsp_start_playback(sb_dsp_t *dsp, unsigned frames,
    270273    unsigned channels, unsigned sampling_rate, pcm_sample_format_t format)
    271274{
     
    275278                return EINVAL;
    276279
    277         /* Play block size must be even number (we use DMA 16)*/
    278         if (dsp->buffer.size % (parts * 2))
    279                 return EINVAL;
    280 
    281         const unsigned play_block_size = dsp->buffer.size / parts;
    282 
    283280        /* Check supported parameters */
    284         ddf_log_debug("Requested playback (%u parts): %uHz, %s, %u channel(s).",
    285             parts, sampling_rate, pcm_sample_format_str(format), channels);
     281        ddf_log_debug("Requested playback: %u frames, %uHz, %s, %u channel(s).",
     282            frames, sampling_rate, pcm_sample_format_str(format), channels);
    286283        if (channels != 1 && channels != 2)
    287284                return ENOTSUP;
     
    311308#endif
    312309
    313         dsp->active.mode = 0 |
    314             (sign ? DSP_MODE_SIGNED : 0) | (channels == 2 ? DSP_MODE_STEREO : 0);
     310        dsp->active.mode = 0
     311            | (sign ? DSP_MODE_SIGNED : 0)
     312            | (channels == 2 ? DSP_MODE_STEREO : 0);
     313        dsp->active.samples = frames * channels;
     314        dsp->active.frame_count = 0;
     315
    315316        sb_dsp_write(dsp, dsp->active.mode);
    316 
    317         dsp->active.samples = sample_count(format, play_block_size);
    318317        sb_dsp_write(dsp, (dsp->active.samples - 1) & 0xff);
    319318        sb_dsp_write(dsp, (dsp->active.samples - 1) >> 8);
     
    339338}
    340339
    341 int sb_dsp_start_record(sb_dsp_t *dsp, unsigned parts,
     340int sb_dsp_start_record(sb_dsp_t *dsp, unsigned frames,
    342341    unsigned channels, unsigned sampling_rate, pcm_sample_format_t format)
    343342{
     
    347346                return EINVAL;
    348347
    349         /* Play block size must be even number (we use DMA 16)*/
    350         if (dsp->buffer.size % (parts * 2))
    351                 return EINVAL;
    352 
    353         const unsigned play_block_size = dsp->buffer.size / parts;
    354 
    355348        /* Check supported parameters */
    356         ddf_log_debug("Requested record (%u parts): %uHz, %s, %u channel(s).",
    357             parts, sampling_rate, pcm_sample_format_str(format), channels);
     349        ddf_log_debug("Requested record: %u frames, %uHz, %s, %u channel(s).",
     350            frames, sampling_rate, pcm_sample_format_str(format), channels);
    358351        if (channels != 1 && channels != 2)
    359352                return ENOTSUP;
     
    384377
    385378        dsp->active.mode = 0 |
    386             (sign ? DSP_MODE_SIGNED : 0) | (channels == 2 ? DSP_MODE_STEREO : 0);
     379            (sign ? DSP_MODE_SIGNED : 0) |
     380            (channels == 2 ? DSP_MODE_STEREO : 0);
     381        dsp->active.samples = frames * channels;
     382        dsp->active.frame_count = 0;
     383
    387384        sb_dsp_write(dsp, dsp->active.mode);
    388 
    389         dsp->active.samples = sample_count(format, play_block_size);
    390385        sb_dsp_write(dsp, (dsp->active.samples - 1) & 0xff);
    391386        sb_dsp_write(dsp, (dsp->active.samples - 1) >> 8);
  • uspace/drv/audio/sb16/dsp.h

    r2cc5c835 r57e8b3b  
    5757                uint8_t mode;
    5858                uint16_t samples;
     59                unsigned frame_count;
    5960        } active;
    6061        enum {
     
    7576int sb_dsp_set_event_session(sb_dsp_t *dsp, async_sess_t *session);
    7677int sb_dsp_release_buffer(sb_dsp_t *dsp);
    77 int sb_dsp_start_playback(sb_dsp_t *dsp, unsigned parts,
     78int sb_dsp_start_playback(sb_dsp_t *dsp, unsigned frames,
    7879    unsigned channels, unsigned sample_rate, pcm_sample_format_t format);
    7980int sb_dsp_stop_playback(sb_dsp_t *dsp);
    80 int sb_dsp_start_record(sb_dsp_t *dsp, unsigned parts,
     81int sb_dsp_start_record(sb_dsp_t *dsp, unsigned frames,
    8182    unsigned channels, unsigned sample_rate, pcm_sample_format_t format);
    8283int sb_dsp_stop_record(sb_dsp_t *dsp);
  • uspace/drv/audio/sb16/pcm_iface.c

    r2cc5c835 r57e8b3b  
    7070}
    7171
    72 static int sb_start_playback(ddf_fun_t *fun, unsigned parts,
     72static int sb_start_playback(ddf_fun_t *fun, unsigned frames,
    7373    unsigned channels, unsigned sample_rate, pcm_sample_format_t format)
    7474{
     
    7777        sb_dsp_t *dsp = fun->driver_data;
    7878        return sb_dsp_start_playback(
    79             dsp, parts, channels, sample_rate, format);
     79            dsp, frames, channels, sample_rate, format);
    8080}
    8181
     
    8888}
    8989
    90 static int sb_start_record(ddf_fun_t *fun, unsigned parts,
     90static int sb_start_record(ddf_fun_t *fun, unsigned frames,
    9191    unsigned channels, unsigned sample_rate, pcm_sample_format_t format)
    9292{
     
    9595        sb_dsp_t *dsp = fun->driver_data;
    9696        return sb_dsp_start_record(
    97             dsp, parts, channels, sample_rate, format);
     97            dsp, frames, channels, sample_rate, format);
    9898}
    9999
  • uspace/lib/drv/generic/remote_audio_pcm.c

    r2cc5c835 r57e8b3b  
    148148}
    149149
    150 int audio_pcm_start_playback(audio_pcm_sess_t *sess, unsigned parts,
     150int audio_pcm_start_playback(audio_pcm_sess_t *sess, unsigned frames,
    151151    unsigned channels, unsigned sample_rate, pcm_sample_format_t format)
    152152{
    153         if (parts > UINT8_MAX || channels > UINT8_MAX)
     153        if (channels > UINT16_MAX)
    154154                return EINVAL;
    155155        assert((format & UINT16_MAX) == format);
    156         const sysarg_t packed =
    157             (parts << 24) | (channels << 16) | (format & UINT16_MAX);
    158         async_exch_t *exch = async_exchange_begin(sess);
    159         const int ret = async_req_3_0(exch,
     156        const sysarg_t packed = (channels << 16) | (format & UINT16_MAX);
     157        async_exch_t *exch = async_exchange_begin(sess);
     158        const int ret = async_req_4_0(exch,
    160159            DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE),
    161160            IPC_M_AUDIO_PCM_START_PLAYBACK,
    162             sample_rate, packed);
     161            frames, sample_rate, packed);
    163162        async_exchange_end(exch);
    164163        return ret;
     
    175174}
    176175
    177 int audio_pcm_start_record(audio_pcm_sess_t *sess, unsigned parts,
     176int audio_pcm_start_record(audio_pcm_sess_t *sess, unsigned frames,
    178177    unsigned channels, unsigned sample_rate, pcm_sample_format_t format)
    179178{
    180         if (parts > UINT8_MAX || channels > UINT8_MAX)
     179        if (channels > UINT16_MAX)
    181180                return EINVAL;
    182181        assert((format & UINT16_MAX) == format);
    183         const sysarg_t packed =
    184             (parts << 24) | (channels << 16) | (format & UINT16_MAX);
    185         async_exch_t *exch = async_exchange_begin(sess);
    186         const int ret = async_req_3_0(exch,
     182        const sysarg_t packed = (channels << 16) | (format & UINT16_MAX);
     183        async_exch_t *exch = async_exchange_begin(sess);
     184        const int ret = async_req_4_0(exch,
    187185            DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE), IPC_M_AUDIO_PCM_START_RECORD,
    188             sample_rate, packed);
     186            frames, sample_rate, packed);
    189187        async_exchange_end(exch);
    190188        return ret;
     
    345343        const audio_pcm_iface_t *pcm_iface = iface;
    346344
    347         const unsigned rate = DEV_IPC_GET_ARG1(*call);
    348         const unsigned parts = (DEV_IPC_GET_ARG2(*call) >> 24) & UINT8_MAX;
    349         const unsigned channels = (DEV_IPC_GET_ARG2(*call) >> 16) & UINT8_MAX;
    350         const pcm_sample_format_t format = DEV_IPC_GET_ARG2(*call) & UINT16_MAX;
     345        const unsigned frames = DEV_IPC_GET_ARG1(*call);
     346        const unsigned rate = DEV_IPC_GET_ARG2(*call);
     347        const unsigned channels = (DEV_IPC_GET_ARG3(*call) >> 16) & UINT8_MAX;
     348        const pcm_sample_format_t format = DEV_IPC_GET_ARG3(*call) & UINT16_MAX;
    351349
    352350        const int ret = pcm_iface->start_playback
    353             ? pcm_iface->start_playback(fun, parts, channels, rate, format)
     351            ? pcm_iface->start_playback(fun, frames, channels, rate, format)
    354352            : ENOTSUP;
    355353        async_answer_0(callid, ret);
     
    371369        const audio_pcm_iface_t *pcm_iface = iface;
    372370
    373         const unsigned rate = DEV_IPC_GET_ARG1(*call);
    374         const unsigned parts = (DEV_IPC_GET_ARG2(*call) >> 24) & UINT8_MAX;
    375         const unsigned channels = (DEV_IPC_GET_ARG2(*call) >> 16) & UINT8_MAX;
    376         const pcm_sample_format_t format = DEV_IPC_GET_ARG2(*call) & UINT16_MAX;
     371        const unsigned frames = DEV_IPC_GET_ARG1(*call);
     372        const unsigned rate = DEV_IPC_GET_ARG2(*call);
     373        const unsigned channels = (DEV_IPC_GET_ARG3(*call) >> 16) & UINT16_MAX;
     374        const pcm_sample_format_t format = DEV_IPC_GET_ARG3(*call) & UINT16_MAX;
    377375
    378376        const int ret = pcm_iface->start_record
    379             ? pcm_iface->start_record(fun, parts, channels, rate, format)
     377            ? pcm_iface->start_record(fun, frames, channels, rate, format)
    380378            : ENOTSUP;
    381379        async_answer_0(callid, ret);
  • uspace/lib/drv/include/audio_pcm_iface.h

    r2cc5c835 r57e8b3b  
    4545
    4646enum {
    47         PCM_EVENT_PLAYBACK_DONE = IPC_FIRST_USER_METHOD,
    48         PCM_EVENT_RECORDING_DONE,
     47        PCM_EVENT_FRAMES_PLAYED = IPC_FIRST_USER_METHOD,
     48        PCM_EVENT_FRAMES_RECORDED,
    4949        PCM_EVENT_PLAYBACK_TERMINATED,
    5050        PCM_EVENT_RECORDING_TERMINATED
  • uspace/srv/audio/hound/audio_device.c

    r2cc5c835 r57e8b3b  
    4646#include "log.h"
    4747
    48 #define BUFFER_BLOCKS 2
     48#define BUFFER_PARTS 2
    4949
    5050static int device_sink_connection_callback(audio_sink_t *sink, bool new);
     
    107107                    dev->buffer.base, dev->buffer.size);
    108108
    109                 ret = audio_pcm_start_playback(dev->sess, BUFFER_BLOCKS,
     109                const unsigned frames = dev->buffer.size /
     110                    (BUFFER_PARTS * audio_format_frame_size(&dev->sink.format));
     111                ret = audio_pcm_start_playback(dev->sess, frames,
    110112                    dev->sink.format.channels, dev->sink.format.sampling_rate,
    111113                    dev->sink.format.sample_format);
     
    148150                        return ret;
    149151                }
    150                 ret = audio_pcm_start_record(dev->sess, BUFFER_BLOCKS,
     152                const unsigned frames = dev->buffer.size /
     153                    (BUFFER_PARTS * audio_format_frame_size(&dev->sink.format));
     154                ret = audio_pcm_start_record(dev->sess, frames,
    151155                    dev->sink.format.channels, dev->sink.format.sampling_rate,
    152156                    dev->sink.format.sample_format);
     
    187191                async_answer_0(callid, EOK);
    188192                switch(IPC_GET_IMETHOD(call)) {
    189                 case PCM_EVENT_PLAYBACK_DONE: {
     193                case PCM_EVENT_FRAMES_PLAYED: {
     194                        //TODO add underrun protection.
    190195                        if (dev->buffer.position) {
    191196                                dev->buffer.position +=
    192                                     (dev->buffer.size / BUFFER_BLOCKS);
     197                                    (dev->buffer.size / BUFFER_PARTS);
    193198                        }
    194199                        if ((!dev->buffer.position) ||
     
    199204                        }
    200205                        audio_sink_mix_inputs(&dev->sink, dev->buffer.position,
    201                             dev->buffer.size / BUFFER_BLOCKS);
     206                            dev->buffer.size / BUFFER_PARTS);
    202207                        break;
    203208                }
     
    206211                        return;
    207212                }
    208                 case PCM_EVENT_RECORDING_DONE: {
     213                case PCM_EVENT_FRAMES_RECORDED: {
    209214                        //TODO implement
    210215                        break;
  • uspace/srv/audio/hound/audio_format.h

    r2cc5c835 r57e8b3b  
    6161
    6262
    63 
     63static inline size_t audio_format_frame_size(const audio_format_t *a)
     64{
     65        return a->channels * pcm_sample_format_size(a->sample_format);
     66}
    6467
    6568bool audio_format_same(const audio_format_t *a, const audio_format_t* b);
Note: See TracChangeset for help on using the changeset viewer.