+//
+bool
+AS_02::h__AS02Writer::HasOpenClip() const
+{
+ return m_ClipStart != 0;
+}
+
+//
+Result_t
+AS_02::h__AS02Writer::StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC)
+{
+ if ( Ctx != 0 )
+ {
+ DefaultLogSink().Error("Encryption not yet supported for PCM clip-wrap.\n");
+ return RESULT_STATE;
+ }
+
+ if ( m_ClipStart != 0 )
+ {
+ DefaultLogSink().Error("Cannot open clip, clip already open.\n");
+ return RESULT_STATE;
+ }
+
+ m_ClipStart = m_File.Tell();
+ byte_t clip_buffer[24] = {0};
+ memcpy(clip_buffer, EssenceUL, 16);
+ bool check = Kumu::write_BER(clip_buffer+16, 0, 8);
+ assert(check);
+ return m_File.Write(clip_buffer, 24);
+}
+
+//
+Result_t
+AS_02::h__AS02Writer::WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf)
+{
+ if ( m_ClipStart == 0 )
+ {
+ DefaultLogSink().Error("Cannot write clip block, no clip open.\n");
+ return RESULT_STATE;
+ }
+
+ return m_File.Write(FrameBuf.RoData(), FrameBuf.Size());
+}
+
+//
+Result_t
+AS_02::h__AS02Writer::FinalizeClip(ui32_t bytes_per_frame)
+{
+ if ( m_ClipStart == 0 )
+ {
+ DefaultLogSink().Error("Cannot close clip, clip not open.\n");
+ return RESULT_STATE;
+ }
+
+ ui64_t current_position = m_File.Tell();
+ Result_t result = m_File.Seek(m_ClipStart+16);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ byte_t clip_buffer[8] = {0};
+ bool check = Kumu::write_BER(clip_buffer, m_FramesWritten * bytes_per_frame, 8);
+ assert(check);
+ result = m_File.Write(clip_buffer, 8);
+ }
+
+ m_File.Seek(current_position);
+ m_ClipStart = 0;
+ return result;
+}
+
+// standard method of writing the header and footer of a completed AS-02 file