From 25cfa9041ea0e67fcaa4d4a1609c727c8ec1ce2d Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 2 Apr 2017 22:19:18 +0200 Subject: [PATCH] AM Modulator: parametrize vsync shape depending on TV standard --- plugins/channeltx/modatv/atvmod.cpp | 61 +++++++++------ plugins/channeltx/modatv/atvmod.h | 113 ++++++++++++++++++---------- 2 files changed, 112 insertions(+), 62 deletions(-) diff --git a/plugins/channeltx/modatv/atvmod.cpp b/plugins/channeltx/modatv/atvmod.cpp index bac7e3200..1258f7300 100644 --- a/plugins/channeltx/modatv/atvmod.cpp +++ b/plugins/channeltx/modatv/atvmod.cpp @@ -271,44 +271,38 @@ Complex& ATVMod::modulateVestigialSSB(Real& sample) void ATVMod::pullVideo(Real& sample) { - int iLine = m_lineCount % m_nbLines2; - - if (m_lineCount < m_nbLines2) // even image or non interlaced + if (m_lineCount < m_nbLines2 + 1) // even image or non interlaced { - if (iLine < m_nbSyncLinesHead) + int iLine = m_lineCount; + + if (iLine < m_nbSyncLinesHeadE + m_nbBlankLines) { pullVSyncLine(sample); } - else if (iLine < m_nbSyncLinesHead + m_nbBlankLines) + else if (iLine > m_nbLines2 - m_nbSyncLinesBottom) { - pullVSyncLine(sample); // pull black line - } - else if (iLine < m_nbLines2 - 3) - { - pullImageLine(sample); + pullVSyncLine(sample); } else { - pullVSyncLine(sample); + pullImageLine(sample); } } else // odd image { - if (iLine < m_nbSyncLinesHead - 1) + int iLine = m_lineCount - m_nbLines2 - 1; + + if (iLine < m_nbSyncLinesHeadO + m_nbBlankLines) { pullVSyncLine(sample); } - else if (iLine < m_nbSyncLinesHead + m_nbBlankLines - 1) + else if (iLine > m_nbLines2 - 1 - m_nbSyncLinesBottom) { - pullVSyncLine(sample); // pull black line - } - else if (iLine < m_nbLines2 - 4) - { - pullImageLine(sample); + pullVSyncLine(sample); } else { - pullVSyncLine(sample); + pullImageLine(sample); } } @@ -819,7 +813,7 @@ void ATVMod::applyStandard() m_vBarIncrement = m_spanLevel / (float) m_nbBars; m_nbLines = m_config.m_nbLines; - m_nbLines2 = (m_nbLines / 2) + 1; + m_nbLines2 = m_nbLines / 2; m_fps = m_config.m_fps * 1.0f; // qDebug() << "ATVMod::applyStandard: " @@ -837,16 +831,30 @@ void ATVMod::applyStandard() m_nbImageLines = m_nbLines - 15; // lines less the total number of sync lines m_nbImageLines2 = m_nbImageLines / 2; m_interleaved = true; - m_nbSyncLinesHead = 5; // number of sync lines on the top of a frame + m_nbSyncLinesHeadE = 5; // number of sync lines on the top of a frame even + m_nbSyncLinesHeadO = 4; // number of sync lines on the top of a frame odd + m_nbSyncLinesBottom = 3; + m_nbLongSyncLines = 2; + m_nbHalfLongSync = 1; + m_nbWholeEqLines = 2; + m_singleLongSync = false; m_nbBlankLines = 7; // yields 376 lines (195 - 7) * 2 + m_blankLineLvel = m_blackLevel; break; case ATVStdPAL525: // Follows PAL-M standard // what is left in a 64/1.008 us line for the image m_nbImageLines = m_nbLines - 15; m_nbImageLines2 = m_nbImageLines / 2; m_interleaved = true; - m_nbSyncLinesHead = 5; + m_nbSyncLinesHeadE = 5; + m_nbSyncLinesHeadO = 4; // number of sync lines on the top of a frame odd + m_nbSyncLinesBottom = 3; + m_nbLongSyncLines = 2; + m_nbHalfLongSync = 1; + m_nbWholeEqLines = 2; + m_singleLongSync = false; m_nbBlankLines = 15; // yields 480 lines (255 - 15) * 2 + m_blankLineLvel = m_blackLevel; break; case ATVStdPAL625: // Follows PAL-B/G/H standard default: @@ -854,8 +862,15 @@ void ATVMod::applyStandard() m_nbImageLines = m_nbLines - 15; m_nbImageLines2 = m_nbImageLines / 2; m_interleaved = true; - m_nbSyncLinesHead = 5; + m_nbSyncLinesHeadE = 5; + m_nbSyncLinesHeadO = 4; // number of sync lines on the top of a frame odd + m_nbSyncLinesBottom = 3; + m_nbLongSyncLines = 2; + m_nbHalfLongSync = 1; + m_nbWholeEqLines = 2; + m_singleLongSync = false; m_nbBlankLines = 17; // yields 576 lines (305 - 17) * 2 + m_blankLineLvel = m_blackLevel; } if (m_imageOK) diff --git a/plugins/channeltx/modatv/atvmod.h b/plugins/channeltx/modatv/atvmod.h index 84f0faebf..32be0b50a 100644 --- a/plugins/channeltx/modatv/atvmod.h +++ b/plugins/channeltx/modatv/atvmod.h @@ -631,8 +631,15 @@ private: uint32_t m_nbImageLines; //!< number of image lines excluding synchronization lines uint32_t m_nbImageLines2; //!< same number as above (non interlaced) or half the number above (interlaced) uint32_t m_nbHorizPoints; //!< number of line points per horizontal line - uint32_t m_nbSyncLinesHead; //!< number of header sync lines + uint32_t m_nbSyncLinesHeadE; //!< number of header sync lines on even frame + uint32_t m_nbSyncLinesHeadO; //!< number of header sync lines on odd frame + uint32_t m_nbSyncLinesBottom;//!< number of sync lines at bottom + uint32_t m_nbLongSyncLines; //!< number of whole long sync lines for vertical synchronization + uint32_t m_nbHalfLongSync; //!< number of half long sync / equalization lines + uint32_t m_nbWholeEqLines; //!< number of whole equalizing lines + bool m_singleLongSync; //!< single or double long sync per long sync line uint32_t m_nbBlankLines; //!< number of lines in a frame (full or half) that are blanked (black) at the top of the image + float m_blankLineLvel; //!< video level of blank lines float m_hBarIncrement; //!< video level increment at each horizontal bar increment float m_vBarIncrement; //!< video level increment at each vertical bar increment bool m_interleaved; //!< true if image is interlaced (2 half frames per frame) @@ -725,9 +732,9 @@ private: else if (m_horizontalCount < m_pointsPerSync + m_pointsPerBP + m_pointsPerImgLine) { int pointIndex = m_horizontalCount - (m_pointsPerSync + m_pointsPerBP); - int iLine = m_lineCount % m_nbLines2; - int oddity = m_lineCount < m_nbLines2 ? 0 : 1; - int iLineImage = iLine - m_nbSyncLinesHead - m_nbBlankLines; + int oddity = m_lineCount < m_nbLines2 + 1 ? 0 : 1; + int iLine = oddity == 0 ? m_lineCount : m_lineCount - m_nbLines2 - 1; + int iLineImage = iLine - m_nbBlankLines - (oddity == 0 ? m_nbSyncLinesHeadE : m_nbSyncLinesHeadO); switch(m_running.m_atvModInput) { @@ -822,11 +829,11 @@ private: inline void pullVSyncLine(Real& sample) { - int fieldLine = m_lineCount % m_nbLines2; - - if (m_lineCount < m_nbLines2) // even + if (m_lineCount < m_nbLines2 + 1) // even { - if (fieldLine < 2) // 0,1: Whole line "long" pulses + int fieldLine = m_lineCount; + + if (fieldLine < m_nbLongSyncLines) // 0,1: Whole line "long" pulses { int halfIndex = m_horizontalCount % (m_nbHorizPoints/2); @@ -839,7 +846,7 @@ private: sample = m_blackLevel; } } - else if (fieldLine == 2) // long pulse then equalizing pulse + else if (fieldLine < m_nbLongSyncLines + m_nbHalfLongSync) // long pulse then equalizing pulse { if (m_horizontalCount < (m_nbHorizPoints/2) - m_pointsPerSync) { @@ -858,7 +865,7 @@ private: sample = m_blackLevel; // black } } - else if ((fieldLine < 5) || (fieldLine > m_nbLines2 - 3)) // Whole line equalizing pulses + else if (fieldLine < m_nbLongSyncLines + m_nbHalfLongSync + m_nbWholeEqLines) // Whole line equalizing pulses { int halfIndex = m_horizontalCount % (m_nbHorizPoints/2); @@ -871,21 +878,7 @@ private: sample = m_blackLevel; } } - else // black images - { - if (m_horizontalCount < m_pointsPerSync) - { - sample = 0.0f; - } - else - { - sample = m_blackLevel; - } - } - } - else // odd - { - if (fieldLine < 1) // equalizing pulse then long pulse + else if (fieldLine > m_nbLines2 - m_nbHalfLongSync) // equalizing pulse then long pulse { if (m_horizontalCount < m_pointsPerFSync) { @@ -904,20 +897,7 @@ private: sample = m_blackLevel; // black } } - else if (fieldLine < 3) // Whole line "long" pulses - { - int halfIndex = m_horizontalCount % (m_nbHorizPoints/2); - - if (halfIndex < (m_nbHorizPoints/2) - m_pointsPerSync) // ultra-black - { - sample = 0.0f; - } - else // black - { - sample = m_blackLevel; - } - } - else if ((fieldLine < 5) || (fieldLine > m_nbLines2 - 5)) // Whole line equalizing pulses + else if (fieldLine > m_nbLines2 - m_nbHalfLongSync - m_nbWholeEqLines) // Whole line equalizing pulses { int halfIndex = m_horizontalCount % (m_nbHorizPoints/2); @@ -937,10 +917,65 @@ private: sample = 0.0f; } else + { + sample = m_blankLineLvel; + } + } + } + else // odd + { + int fieldLine = m_lineCount - m_nbLines2 - 1; + + if (fieldLine < m_nbLongSyncLines) // 0,1: Whole line "long" pulses + { + int halfIndex = m_horizontalCount % (m_nbHorizPoints/2); + + if (halfIndex < (m_nbHorizPoints/2) - m_pointsPerSync) // ultra-black + { + sample = 0.0f; + } + else // black { sample = m_blackLevel; } } + else if (fieldLine < m_nbLongSyncLines + m_nbWholeEqLines) // Whole line equalizing pulses + { + int halfIndex = m_horizontalCount % (m_nbHorizPoints/2); + + if (halfIndex < m_pointsPerFSync) // ultra-black + { + sample = 0.0f; + } + else // black + { + sample = m_blackLevel; + } + } + else if (fieldLine > m_nbLines2 - 1 - m_nbWholeEqLines - m_nbHalfLongSync) // Whole line equalizing pulses + { + int halfIndex = m_horizontalCount % (m_nbHorizPoints/2); + + if (halfIndex < m_pointsPerFSync) // ultra-black + { + sample = 0.0f; + } + else // black + { + sample = m_blackLevel; + } + } + else // black images + { + if (m_horizontalCount < m_pointsPerSync) + { + sample = 0.0f; + } + else + { + sample = m_blankLineLvel; + } + } } } };