| @@ -88,26 +88,27 @@ struct cubeb_stream { | | | @@ -88,26 +88,27 @@ struct cubeb_stream { |
88 | int record_fd; | | 88 | int record_fd; |
89 | float volume; | | 89 | float volume; |
90 | struct audio_info p_info; /* info for the play fd */ | | 90 | struct audio_info p_info; /* info for the play fd */ |
91 | struct audio_info r_info; /* info for the record fd */ | | 91 | struct audio_info r_info; /* info for the record fd */ |
92 | cubeb_data_callback data_cb; | | 92 | cubeb_data_callback data_cb; |
93 | cubeb_state_callback state_cb; | | 93 | cubeb_state_callback state_cb; |
94 | int16_t * play_buf; | | 94 | int16_t * play_buf; |
95 | int16_t * record_buf; | | 95 | int16_t * record_buf; |
96 | float * f_play_buf; | | 96 | float * f_play_buf; |
97 | float * f_record_buf; | | 97 | float * f_record_buf; |
98 | char input_name[32]; | | 98 | char input_name[32]; |
99 | char output_name[32]; | | 99 | char output_name[32]; |
100 | uint64_t frames_written; | | 100 | uint64_t frames_written; |
| | | 101 | uint64_t blocks_written; |
101 | }; | | 102 | }; |
102 | | | 103 | |
103 | int | | 104 | int |
104 | sun_init(cubeb ** context, char const * context_name) | | 105 | sun_init(cubeb ** context, char const * context_name) |
105 | { | | 106 | { |
106 | cubeb * c; | | 107 | cubeb * c; |
107 | | | 108 | |
108 | (void)context_name; | | 109 | (void)context_name; |
109 | if ((c = calloc(1, sizeof(cubeb))) == NULL) { | | 110 | if ((c = calloc(1, sizeof(cubeb))) == NULL) { |
110 | return CUBEB_ERROR; | | 111 | return CUBEB_ERROR; |
111 | } | | 112 | } |
112 | c->ops = &sun_ops; | | 113 | c->ops = &sun_ops; |
113 | *context = c; | | 114 | *context = c; |
| @@ -654,30 +655,42 @@ static int | | | @@ -654,30 +655,42 @@ static int |
654 | sun_stream_start(cubeb_stream * s) | | 655 | sun_stream_start(cubeb_stream * s) |
655 | { | | 656 | { |
656 | s->running = 1; | | 657 | s->running = 1; |
657 | if (pthread_create(&s->thread, NULL, sun_io_routine, s) != 0) { | | 658 | if (pthread_create(&s->thread, NULL, sun_io_routine, s) != 0) { |
658 | LOG("Couldn't create thread"); | | 659 | LOG("Couldn't create thread"); |
659 | return CUBEB_ERROR; | | 660 | return CUBEB_ERROR; |
660 | } | | 661 | } |
661 | return CUBEB_OK; | | 662 | return CUBEB_OK; |
662 | } | | 663 | } |
663 | | | 664 | |
664 | static int | | 665 | static int |
665 | sun_stream_get_position(cubeb_stream * s, uint64_t * position) | | 666 | sun_stream_get_position(cubeb_stream * s, uint64_t * position) |
666 | { | | 667 | { |
| | | 668 | #ifdef AUDIO_GETOOFFS |
| | | 669 | struct audio_offset offset; |
| | | 670 | |
| | | 671 | if (ioctl(s->play_fd, AUDIO_GETOOFFS, &offset) == -1) { |
| | | 672 | return CUBEB_ERROR; |
| | | 673 | } |
| | | 674 | s->blocks_written += offset.deltablks; |
| | | 675 | *position = BYTES_TO_FRAMES(s->blocks_written * s->p_info.blocksize, |
| | | 676 | s->p_info.play.channels); |
| | | 677 | return CUBEB_OK; |
| | | 678 | #else |
667 | pthread_mutex_lock(&s->mutex); | | 679 | pthread_mutex_lock(&s->mutex); |
668 | *position = s->frames_written; | | 680 | *position = s->frames_written; |
669 | pthread_mutex_unlock(&s->mutex); | | 681 | pthread_mutex_unlock(&s->mutex); |
670 | return CUBEB_OK; | | 682 | return CUBEB_OK; |
| | | 683 | #endif |
671 | } | | 684 | } |
672 | | | 685 | |
673 | static int | | 686 | static int |
674 | sun_stream_get_latency(cubeb_stream * stream, uint32_t * latency) | | 687 | sun_stream_get_latency(cubeb_stream * stream, uint32_t * latency) |
675 | { | | 688 | { |
676 | #ifdef AUDIO_GETBUFINFO | | 689 | #ifdef AUDIO_GETBUFINFO |
677 | struct audio_info info; | | 690 | struct audio_info info; |
678 | | | 691 | |
679 | if (ioctl(stream->play_fd, AUDIO_GETBUFINFO, &info) == -1) { | | 692 | if (ioctl(stream->play_fd, AUDIO_GETBUFINFO, &info) == -1) { |
680 | return CUBEB_ERROR; | | 693 | return CUBEB_ERROR; |
681 | } | | 694 | } |
682 | | | 695 | |
683 | *latency = BYTES_TO_FRAMES(info.play.seek + info.blocksize, | | 696 | *latency = BYTES_TO_FRAMES(info.play.seek + info.blocksize, |