о, чего словил:
Делал объектный вариант Жениного скрипта для работы с сэмплами:
причем, простой копипаст с "переводом" на питон работает отлично. Что я тут могу не оттуда запускать?
P.S. ацессор удалял при каждой итерации, а добавлял в конструкторе...
Код:
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Runtime Error!
Program: C:\Program Files\REAPER (x64)\reaper.exe
R6025
- pure virtual function call
---------------------------
ОК
---------------------------
Делал объектный вариант Жениного скрипта для работы с сэмплами:
Код:
def find_loop(item, search_samples, precision):
item = Item(item, block_size=search_samples)
samples = item.samples.get_all()
class Item:
def __init__(self, item, use_ts=True, block_size=1024):
self.item = item
self.take = RPR_GetActiveTake(self.item)
self.playrate = RPR_GetMediaItemTakeInfo_Value(self.take, "D_PLAYRATE")
self.PCM_source = RPR_GetMediaItemTake_Source(self.take)
self.samplerate = RPR_GetMediaSourceSampleRate(self.PCM_source)
self._start = RPR_GetMediaItemInfo_Value(self.item, "D_POSITION")
self._len = RPR_GetMediaItemInfo_Value(self.item, "D_LENGTH")
self._get_range(use_ts)
self.samples = ItemSamples(self, block_size)
def _get_range(self, use_ts):
sel_start = sel_end = None
if use_ts:
loop_tr = RPR_GetSet_LoopTimeRange(0, 0, 0, 0, 0)
sel_start, sel_end = loop_tr[2], loop_tr[3]
if not sel_start or sel_end == sel_start:
sel_start = self._start
sel_end = self._start + self._len
sel_start = max(sel_start, self._start)
sel_end = min(sel_end, self._start + self._len)
if sel_end - sel_start < 0:
RPR_ShowMessageBox(
"Time selection out of item range!", "Note", 0)
self.open()
self.start = (sel_start - self._start) * self.playrate
self.len = (sel_end - sel_start) * self.playrate
self.end = self._start + self._len
self.len_spls = int(self._len * self.samplerate)
self.close()
def open(self):
if self.playrate != 1:
RPR_SetMediaItemTakeInfo_Value(self.take, "D_PLAYRATE", 1)
RPR_SetMediaItemInfo_Value(
self.item, "D_LENGTH", self._len * self.playrate)
def close(self):
if self.playrate != 1:
RPR_SetMediaItemTakeInfo_Value(
self.take, "D_PLAYRATE", self.playrate)
RPR_SetMediaItemInfo_Value(self.item, "D_LENGTH", self._len)
RPR_UpdateTimeline()
class ItemSamples:
def __init__(self, item, block_size=1024):
self.channels_amount = RPR_GetMediaSourceNumChannels(item.PCM_source)
self.audio = RPR_CreateTakeAudioAccessor(item.take)
self._block_size = block_size
self._n_blocks = int(item.len_spls / block_size)
self._extra_spls = item.len_spls - block_size * self._n_blocks
self._buf_preset = list([0] * block_size * self.channels_amount)
self.item = item
def get_start_time(self, sample_offset):
self.item.open()
if sample_offset < 0:
retval = self.item.end - (
(sample_offset * self.channels_amount) / self.item.samplerate)
self.item.close()
return retval
retval = self.item.start + (
(sample_offset * self.channels_amount) / self.item.samplerate)
self.item.close()
return retval
def get_block(self, block=False, sample=False):
if block is False and sample is False:
raise Exception('block or sample offset has to be specified.\
block = %s, sample = %s' % (block, sample))
if block is not False:
block_size = self._block_size
start = self.get_start_time(block * block_size)
start_in_spls = block * block_size
if block == self._n_blocks:
block_size = self._extra_spls
if sample is not False:
if block:
raise Exception(
'only block, or sample can be assigned at time')
if self.item.end - sample < block_size:
block_size = self.item.end - sample
start = self.get_start_time(sample)
start_in_spls = sample
self.item.open()
samplebuffer = self._buf_preset
RPR_GetAudioAccessorSamples(self.audio, self.item.samplerate,
self.channels_amount, start,
block_size, samplebuffer)
samples = list()
for sample in range(block_size):
channels = list()
for channel in range(self.channels_amount):
pos = sample * self.channels_amount + channel
channels.append(samplebuffer[pos])
idx = start_in_spls + sample
samples.append(Sample(idx, channels))
RPR_DestroyAudioAccessor(self.audio)
self.item.close()
return samples
def get_all(self):
samples = list()
for block in range(self._n_blocks):
samples.append(self.get_block(block=block))
return samples
class Sample:
def __init__(self, idx, channels):
self.idx = idx
self.channels_amount = len(channels)
self.channels = tuple(channels)
причем, простой копипаст с "переводом" на питон работает отлично. Что я тут могу не оттуда запускать?
P.S. ацессор удалял при каждой итерации, а добавлял в конструкторе...
Последнее редактирование: