Changeset 2491:d3ef52e3cd3d in roaraudio for roard/streams.c
- Timestamp:
- 08/24/09 01:59:05 (15 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
roard/streams.c
r2459 r2491 716 716 } 717 717 718 int streams_fill_mixbuffer (int id, struct roar_audio_info * info) {719 // TODO: decide: is this the most complex, hacked, un-understadable,720 // un-writeable and even worse: un-readable721 // function in the whole project?722 size_t todo = ROAR_OUTPUT_CALC_OUTBUFSIZE(info);723 size_t needed = todo;724 size_t todo_in;725 size_t len, outlen;726 size_t mul = 1, div = 1;727 void * rest = NULL;728 void * in = NULL;729 struct roar_buffer * buf;730 struct roar_audio_info * stream_info;731 struct roar_stream_server * stream = g_streams[id];732 int is_the_same = 0;733 734 if ( g_streams[id] == NULL )735 return -1;736 737 if ( streams_get_outputbuffer(id, &rest, todo) == -1 ) {738 return -1;739 }740 741 if ( rest == NULL ) {742 return -1;743 }744 745 // set up stream_info746 747 stream_info = &(ROAR_STREAM(stream)->info);748 749 // calc todo_in750 todo_in = ROAR_OUTPUT_CALC_OUTBUFSIZE(stream_info);751 752 if ( todo_in == 0 ) {753 ROAR_WARN("streams_fill_mixbuffer(id=%i, info=%p{...}): todo_in == 0, this should not happen!", id, info);754 return -1;755 }756 757 // calc mul and div:758 mul = todo / todo_in;759 div = todo_in / todo;760 761 if ( mul == 0 ) {762 mul = 1;763 } else {764 div = 1;765 }766 767 ROAR_DBG("streams_fill_mixbuffer(*): mul=%i, div=%i", mul, div);768 769 ROAR_DBG("streams_fill_mixbuffer(*): rest=%p, todo=%i->%i (in->out)", rest, todo_in, todo);770 // are both (input and output) of same format?771 772 773 ROAR_DBG("streams_fill_mixbuffer(*): stream_info:");774 roar_debug_audio_info_print(stream_info);775 ROAR_DBG("streams_fill_mixbuffer(*): info:");776 roar_debug_audio_info_print(info);777 778 is_the_same = stream_info->rate == info->rate && stream_info->bits == info->bits &&779 stream_info->channels == info->channels && stream_info->codec == info->codec;780 781 ROAR_DBG("streams_fill_mixbuffer(*): is_the_same=%i", is_the_same);782 783 /* How it works:784 *785 * set a counter to the number of samples we need.786 * loop until we have all samples done or no samples are787 * left in our input buffer.788 * If there a no samples left in the input buffer: fill the rest789 * of the output buffer with zeros.790 *791 * The loop:792 * get a buffer from the input.793 * if it's bigger than needed, set an offset.794 * The rest of the data:795 * 0) convert endianness (codec) from remote to local...796 * 1) change bits in of the samples797 * 2) change sample rate798 * 3) change the nummber of channels799 * 4) insert into output buffer800 */801 802 /*803 // get our first buffer:804 805 if ( stream_shift_buffer(id, &buf) == -1 ) {806 return -1;807 }808 809 // first test for some basic simple cases...810 811 if ( buf == NULL ) { // we habe nothing in input queue812 // we may memset() our output buffer OR813 // just return with -1 so we are going to814 // be ignored.815 return -1;816 }817 */818 819 while (todo) { // main loop820 ROAR_DBG("streams_fill_mixbuffer(*): looping...");821 // exit loop if nothing is left, even if we need more data..822 if ( stream_shift_buffer(id, &buf) == -1 )823 break;824 if ( buf == NULL )825 break;826 827 // read the data for this loop...828 roar_buffer_get_data(buf, &in);829 roar_buffer_get_len(buf, &len);830 831 ROAR_DBG("streams_fill_mixbuffer(*): len = %i", len);832 833 if ( len > todo_in ) {834 roar_buffer_set_offset(buf, todo_in);835 len = todo_in;836 } else {837 roar_buffer_set_len(buf, 0); // queue for deletation838 }839 840 // we now have 'len' bytes in 'in'841 842 // calc how much outlen this has...843 outlen = (len * mul) / div;844 845 ROAR_DBG("streams_fill_mixbuffer(*): outlen = %i, buf = %p, len = %i", outlen, in, len);846 847 if ( is_the_same ) {848 /*849 * 0) convert endianness (codec) from remote to local...850 * 1) change bits in of the samples851 * 2) change sample rate852 * 3) change the nummber of channels853 \\==> skiping,...854 */855 // * 4) insert into output buffer856 ROAR_DBG("streams_fill_mixbuffer(*): memcpy: in->rest: %p -> %p", in, rest);857 if ( memcpy(rest, in, len) != rest ) {858 ROAR_ERR("streams_fill_mixbuffer(*): memcpy returned invalid pointer.");859 }860 861 } else {862 863 /*864 // * 0) convert endianness (codec) from remote to local...865 if ( stream_info->codec != info->codec ) {866 // we neet to convert...867 return -1;868 }869 870 // * 1) change bits in of the samples871 if ( stream_info->bits != info->bits ) {872 return -1;873 }874 875 // * 2) change sample rate876 if ( stream_info->rate != info->rate ) {877 return -1;878 }879 880 // * 3) change the nummber of channels881 if ( stream_info->channels != info->channels ) {882 return -1;883 }884 885 // * 4) insert into output buffer886 */887 // hey! we have roar_conv() :)888 889 if ( roar_conv(rest, in, 8*len / stream_info->bits, stream_info, info) == -1 )890 return -1;891 }892 893 if ( !streams_get_flag(id, ROAR_FLAG_HWMIXER) ) {894 if ( change_vol(rest, info->bits, rest, 8*outlen / info->bits, info->channels, &(stream->mixer)) == -1 )895 return -1;896 }897 898 // we habe outlen bytes more...899 todo -= outlen;900 rest += outlen;901 todo_in -= len;902 903 roar_buffer_get_len(buf, &len);904 ROAR_DBG("streams_fill_mixbuffer(*): New length of buffer %p is %i", buf, len);905 if ( len == 0 ) {906 roar_buffer_delete(buf, NULL);907 } else {908 stream_unshift_buffer(id, buf);909 }910 }911 912 //len = 0;913 //roar_buffer_get_len(buf, &len);914 915 /*916 if ( len > 0 ) // we still have some data in this buffer, re-inserting it to the input buffers...917 stream_unshift_buffer(id, buf);918 else919 buffer_delete(buf, NULL);920 */921 922 ROAR_STREAM(g_streams[id])->pos =923 ROAR_MATH_OVERFLOW_ADD(ROAR_STREAM(g_streams[id])->pos,924 ROAR_OUTPUT_CALC_OUTBUFSAMP(info, needed-todo));925 //ROAR_WARN("stream=%i, pos=%u", id, ((struct roar_stream*)g_streams[id])->pos);926 927 if ( todo > 0 ) { // zeroize the rest of the buffer928 memset(rest, 0, todo);929 930 if ( todo != ROAR_OUTPUT_CALC_OUTBUFSIZE(info) ) {931 if ( g_streams[id]->is_new ) {932 stream->pre_underruns++;933 } else {934 ROAR_WARN("streams_fill_mixbuffer(*): Underrun in stream: %u bytes missing, filling with zeros", (unsigned int)todo);935 stream->post_underruns++;936 }937 938 stream->is_new = 0;939 }940 } else {941 stream->is_new = 0;942 }943 944 return 0;945 }946 947 718 int streams_fill_mixbuffer2 (int id, struct roar_audio_info * info) { 948 719 size_t outlen = ROAR_OUTPUT_CALC_OUTBUFSIZE(info);
Note: See TracChangeset
for help on using the changeset viewer.