diff --git a/OSBindings/Mac/Clock SignalTests/PCMPatchedTrackTests.mm b/OSBindings/Mac/Clock SignalTests/PCMPatchedTrackTests.mm index bafdf4ec8..41120fedf 100644 --- a/OSBindings/Mac/Clock SignalTests/PCMPatchedTrackTests.mm +++ b/OSBindings/Mac/Clock SignalTests/PCMPatchedTrackTests.mm @@ -134,7 +134,7 @@ XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1"); } -- (void)testMultiReplace +- (std::shared_ptr)fourSegmentPatchedTrack { std::shared_ptr patchableTrack = self.patchableTogglingTrack; Storage::Disk::PCMPatchedTrack *patchable = static_cast(patchableTrack.get()); @@ -149,6 +149,13 @@ patchable->add_segment(Storage::Time(c, 4), segment); } + return patchableTrack; +} + +- (void)testMultiSegmentTrack +{ + std::shared_ptr patchableTrack = self.fourSegmentPatchedTrack; + Storage::Time total_length; std::vector events; while(1) @@ -162,4 +169,30 @@ XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1"); } +- (void)testMultiReplace +{ + std::shared_ptr patchableTrack = self.fourSegmentPatchedTrack; + Storage::Disk::PCMPatchedTrack *patchable = static_cast(patchableTrack.get()); + + Storage::Disk::PCMSegment segment; + segment.data = {0x00}; + segment.number_of_bits = 8; + segment.length_of_a_bit.length = 1; + segment.length_of_a_bit.clock_rate = 16; + patchable->add_segment(Storage::Time(1, 8), segment); + + Storage::Time total_length; + std::vector events; + while(1) + { + events.push_back(patchableTrack->get_next_event()); + total_length += events.back().length; + if(events.back().type == Storage::Disk::Track::Event::IndexHole) break; + } + + XCTAssert(events.size() == 17, @"Should still be 17 total events"); + XCTAssert(events[4].length == Storage::Time(17, 32), @"Should have added a 17/32 gap after the fourth event"); + XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1"); +} + @end diff --git a/Storage/Disk/PCMPatchedTrack.cpp b/Storage/Disk/PCMPatchedTrack.cpp index b67ccf414..c25b00f3b 100644 --- a/Storage/Disk/PCMPatchedTrack.cpp +++ b/Storage/Disk/PCMPatchedTrack.cpp @@ -103,7 +103,8 @@ void PCMPatchedTrack::insert_period(const Period &period) } else { - bool should_insert; + bool should_insert = false; + std::vector::difference_type insertion_offset = 0; if(start_period->start_time == period.start_time) { @@ -117,20 +118,25 @@ void PCMPatchedTrack::insert_period(const Period &period) // start_period starts before period. So trim and plan to insert afterwards. start_period->trim_end_to_time(period.start_time); should_insert = true; + insertion_offset = start_period + 1 - periods_.begin(); } - if(end_period->end_time > period.end_time) + if(end_period->end_time == period.end_time) { - // end_period exactly after period does. So exclude it from the list to delete - end_period--; + // end_period ends exactly when period does. So include it from the list to delete + end_period++; + } + else + { + end_period->push_start_to_time(period.end_time); } // remove everything that is exiting in between - periods_.erase(start_period + 1, end_period - 1); + periods_.erase(start_period + 1, end_period); // insert the new period if required if(should_insert) - periods_.insert(start_period + 1, period); + periods_.insert(periods_.begin()+insertion_offset, period); } }