1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
/*
* iec60958.c: Define the S/P-DIF interface for redirecting
* 16bit none audio stream (NO decoding!).
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*
* Copyright (C) 2002,2003 Werner Fink, <werner@suse.de>
*
*/
#include "iec60958.h"
// see iec60958.h enum_stream_t
const char * const audioTypes[5] = {"", "PCM", "AC3", "DTS", "MP2"};
iec60958::iec60958(unsigned int rate,
const unsigned int bsize,
const uint_8 poff)
: burst_size(bsize), offset(poff), start(0), current(0), remember(0), payload(0), flags(0)
{
sample_rate = rate;
play.burst = (uint_32 *)0; // Provide pointer to 16bit PCM stereo samples
play.size = play.pay = 0;
last.burst = (uint_32 *)0; // Provide pointer to 16bit PCM stereo samples
last.size = last.pay = 0;
pts.reset();
isDVD = false;
track = 0;
}
void iec60958::Reset(flags_t arg)
{
flags = arg;
Clear();
isDVD = false; // Is this a DVD stream?
}
void iec60958::Clear(void)
{
buffer_reset(); // Clear buffer
ClassReset(); // E.g. counters, pointers
pts.reset(); // Timings
}
const frame_t & iec60958::Frame(enum_frame_t type)
{
uint_16 *sh = (uint_16 *)&remember[0];
memset(&remember[0], 0, burst_size);
switch (type) {
default:
case PCM_DATA:
sh[0] = char2short(0xf8, 0x72); // Pa
sh[1] = char2short(0x4e, 0x1f); // Pb
sh[2] = char2short(7<<5, 0x00); // null frame requires stream = 7
sh[3] = shorts(0x0000); // Null data_type
last.size = burst_size;
break;
case PCM_WAIT:
sh[0] = char2short(0xf8, 0x72); // Pa
sh[1] = char2short(0x4e, 0x1f); // Pb
sh[2] = char2short(0x00, 0x03); // Audio ES Channel empty, wait for DD Decoder or pause
sh[3] = char2short(0x00, 0x20); // Trailing frame size is 0x0020 aka 32 bits payload
last.size = SPDIF_BURST_SIZE; // _OR_ simply 32 aka 0x20 ms fill frame???
break;
case PCM_WAIT2:
sh[0] = char2short(0xf8, 0x72); // Pa
sh[1] = char2short(0x4e, 0x1f); // Pb
sh[2] = char2short(0x00, 0x03); // Audio ES Channel empty, wait for DD Decoder or pause
#if 0
sh[3] = shorts(8*(burst_size-8)); // Trailing frame size is burst_size - header_size
last.size = burst_size;
#else
sh[3] = shorts(8*(SPDIF_BURST_SIZE-8)); // Trailing frame size is burst_size - header_size
last.size = SPDIF_BURST_SIZE; // _OR_ simply 32 aka 0x20 ms fill frame???
#endif
break;
case PCM_STOP:
sh[0] = char2short(0xf8, 0x72); // Pa
sh[1] = char2short(0x4e, 0x1f); // Pb
sh[2] = char2short(0x01, 0x03); // User stop, skip or error
sh[3] = char2short(0x08, 0x00); // Trailing frame size is 2048 bits (silent)
last.size = burst_size;
break;
case PCM_START: // Combination of PCM_WAIT and PCM_DATA
// char | 0,1 | 2,3 | 4,5 | 6,7 | 8,9 |10,11|12,13|14,15
// short | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
// 0 0 0 0 , magic ,stream, len
sh[4] = char2short(0xf8, 0x72); // Pa
sh[5] = char2short(0x4e, 0x1f); // Pb
sh[6] = char2short(7<<5, 0x00); // null frame requires stream = 7
sh[7] = shorts(0x0000); // Null data_type
// char |16,17|18,19|20,21|22,23|24,25|26,27|28,29|30,31
// short | 8 | 9 | 10| 11| 12| 13| 14| 15
// 0 0 0 0 , magic ,stream, len
sh[12] = char2short(0xf8, 0x72); // Pa
sh[13] = char2short(0x4e, 0x1f); // Pb
sh[14] = char2short(0x00, 0x03); // Audio ES Channel empty, wait for DD Decoder or pause
sh[15] = char2short(0x00, 0x40); // Trailing frame size is 0x0040 aka 64 bits payload
// char |32,33|34,35|36,37|38,39
// short | 16| 17| 18| 19
// 0 0 0 0
last.size = burst_size;
break;
case PCM_SILENT: // Just silent
last.size = burst_size;
break;
}
last.burst = (uint_32 *)&remember[0];
return last;
}
|