-
- /* **********
- * now we mix
- * we take the buffer content and mix the mixer_buffer to what we got
- */
-mix_to_buffer:
- /* release all writepointer which will underrun, since writing of
- * remote port data is too slow
- */
- relation = p_mixer_rel;
- readp = p_mixer_readp;
- relationpointer = &(p_mixer_rel);
- while(relation) /* if no relation, this is skipped */
- {
- /* NOTE: if writep and readp are equal, the distance ist max
- * == PORT_BUFFER
- */
- if (((relation->mixer_writep-readp-1+PORT_BUFFER)%PORT_BUFFER)+1 <= length) /* underrun */
- {
- /* remove port relation in order to resync.
- * this is also caused by ports which do not transmit
- * anymore.
- */
-#ifdef MIXER_DEBUG
- PERROR("PORT(%s) Buffer underrun, source port is sending too slow or stopped sending, removing relation. (readp=%d, writep=%d, PORT_BUFFER=%d)\n", p_name, readp, relation->mixer_writep, PORT_BUFFER);
-#endif
-
- *relationpointer = relation->next;
- memset(relation, 0, sizeof(struct mixer_relation));
- free(relation);
- pmemuse--;
- relation = *relationpointer;
- continue;
- }
- relationpointer = &(relation->next);
- relation = relation->next;
- }
-
- /* if we do recording, we write the record data and the buffer data to the record fp and increment record_count */
- if (p_record)
- switch (p_record_type)
- {
- case CODEC_MONO:
- /* convert from mixer to uncompressed 16 bit mono audio */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- len = length;
- mix_buffer = p_record_buffer;
- rec_buffer = record_buffer;
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length<<1), 1, p_record);
- p_record_length = (length<<1) + p_record_length;
- }
- break;
-
- case CODEC_LAW:
- len = length;
- mix_buffer = p_record_buffer;
- rec_buffer = record_buffer;
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length<<1), 1, p_record);
- p_record_length = (length<<1) + p_record_length;
- }
- break;
-
- }
- break;
-
- case CODEC_STEREO:
- /* convert from mixer to uncompressed 16 bit stereo audio */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- len = length;
- mix_buffer = p_record_buffer;
- mix_buffer2 = p_stereo_buffer;
- rec_buffer = record_buffer;
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
-
- *(rec_buffer++) = mix_buffer2[readp];
- mix_buffer2[readp++] = 0;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- *(rec_buffer++) = mix_buffer2[readp];
- mix_buffer2[readp++] = 0;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length<<2), 1, p_record);
- p_record_length = (length<<2) + p_record_length;
- }
- break;
-
- case CODEC_LAW:
- len = length;
- mix_buffer = p_record_buffer;
- mix_buffer2 = p_stereo_buffer;
- rec_buffer = record_buffer;
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
-
- *(rec_buffer++) = mix_buffer2[readp];
- mix_buffer2[readp++] = 0;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- *(rec_buffer++) = mix_buffer2[readp];
- mix_buffer2[readp++] = 0;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length<<2), 1, p_record);
- p_record_length = (length<<2) + p_record_length;
- }
- break;
- }
- break;
-
- case CODEC_8BIT:
- /* convert from mixer to uncompressed 8 bit mono audio */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- len = length;
- mix_buffer = p_record_buffer;
- rec8_buffer = (unsigned char *)record_buffer;
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = (sample>>8)+0x80;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = (sample>>8)+0x80;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length), 1, p_record);
- p_record_length = (length) + p_record_length;
- }
- break;
-
- case CODEC_LAW:
- len = length;
- mix_buffer = p_record_buffer;
- rec8_buffer = (unsigned char *)record_buffer;
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = (sample>>8)+0x80;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = (sample>>8)+0x80;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length), 1, p_record);
- p_record_length = (length) + p_record_length;
- }
- break;
-
- }
- break;
-
- case CODEC_LAW:
- case CODEC_OFF: /* if no codec is specified, the recorded data will be stored as LAW */
- /* convert from mixer to law */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- len = length;
- mix_buffer = p_record_buffer;
- rec8_buffer = (unsigned char *)record_buffer;
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = audio_s16_to_law[sample & 0xffff];
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length), 1, p_record);
- p_record_length = (length) + p_record_length;
- }
- break;
-
- case CODEC_LAW:
- len = length;
- mix_buffer = p_record_buffer;
- rec8_buffer = (unsigned char *)record_buffer;
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = audio_s16_to_law[sample & 0xffff];
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length), 1, p_record);
- p_record_length = (length) + p_record_length;
- }
- break;
- }
- break;
- }
-
- /* if we have no transmitting relation, we do not need read mixer */
- if (!p_mixer_rel)
- { /* nothing mixed to(no rel), so we are just done */
- if (compressed)
- {
- /* compress to law */
- len = length;
- buf_in8 = (unsigned char *)temp_buffer;
- buf_in16 = (signed short *)temp_buffer;
- buf_out16 = (signed short *)buffer;
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- while(len--)
- *(buffer++) = audio_s16_to_law[*(buf_in16++) & 0xffff];
- break;
-
- case CODEC_LAW:
- memcpy(buffer, temp_buffer, length);
- break;
-
- default:
- PERROR("Software error: current tone for unmixed & uncompressed, has no codec\n");
- exit(-1);
- }
- } else
- {
- /* uncompress law files */
- len = length;
- buf_in8 = (unsigned char *)temp_buffer;
- buf_in16 = (signed short *)temp_buffer;
- buf_out16 = (signed short *)buffer;
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- while(len--)
- (*(buf_out16++)) = *(buf_in16++);
- break;
-
- case CODEC_LAW:
- while(len--)
- (*(buf_out16++)) = audio_law_to_s32[*(buf_in8++)];
- break;
-
- default:
- PERROR("Software error: current tone for unmixed & uncompressed, has no codec\n");
- exit(-1);
- }
- }
- return(length);
- }
-
-// PDEBUG(DEBUG_PORT, "PORT(%s) mixing %d bytes. (readp=%d, PORT_BUFFER=%d)\n", p_name, length, readp, PORT_BUFFER);
- /* now we got our stuff and we'll mix it baby */
-
- len = length;
- mix_buffer = p_mixer_buffer;
- if (compressed)
- {
- /* convert from mixer to compressed law data */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- break;
-
- case CODEC_LAW:
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- break;
-
- default:
- PERROR("Software error: current tone for compressed data has no codec\n");
- exit(-1);
- }
- } else
- {
- /* convert from mixer to uncompressed 16 bit audio */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- buf_in16 = (signed short *)temp_buffer;
- buf_out16 = (signed short *)buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buf_out16++) = sample;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buf_out16++) = sample;
- }
- break;
-
- case CODEC_LAW:
- buf_in8 = (unsigned char *)temp_buffer;
- buf_out16 = (signed short *)buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buf_out16++) = sample;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buf_out16++) = sample;
- }
- break;
-
- default:
- PERROR("Software error: current tone for uncompressed data has no codec\n");
- exit(-1);
- }
- }
-
- p_mixer_readp = readp; /* new read pointer */
-
- return(length);