Newer
Older
tac2grc / src / grc.py
@lukas lukas on 14 Aug 2022 3 KB initial commit
GRC_TEMPLATE = '''
options:
  parameters:
    title: 'TASRC to GRC converter output'
  states:
    coordinate: [-100, -100]

blocks:
%s

connections:
%s

metadata:
  file_format: 1
'''

BLOCK_TEMPLATE = '''
- name: %s
  id: epy_block
  parameters:
    _source_code: "from gnuradio import gr\\nimport numpy as np\\nclass BLOCK(gr.sync_block):\\n def __init__(self):\\n  gr.sync_block.__init__(self,name='%s:%s%s',in_sig=%s,out_sig=%s)\\n def work(self, input_items, output_items):\\n  return len(output_items[0])"
  states:
    coordinate: [%s, %s]
'''

LINK_TEMPLATE = "- [%s, '%s', %s, '%s']\n"

def getLongestDependencyRow(blocks, blockDependencies):
    currentMax = 0
    for block in blocks:
        current = getLongestDependencyRow(blockDependencies[block], blockDependencies) + 1
        if current > currentMax:
            currentMax = current
    return currentMax

def getPosition(block, blockDependencies, reverseBlockDependencies, depths):
    position = getLongestDependencyRow(blockDependencies[block], blockDependencies)
    depths += [0] * (position+1 - len(depths)) 
    y = depths[position]
    depths[position] += 50 # base offset
    depths[position] += max(
            (3+block.blockType.inputs.getRealCount()+block.blockType.outputs.getRealCount()) * 15,
            max(block.blockType.inputs.getRealCount(), block.blockType.outputs.getRealCount()) * 30)        
    return position * 300, y

def getBlockDependencies(blocks, links):
    blockDependencies = {}
    for block in blocks:
        blockDependencies[block] = []
        for link in links:
            if link.toBlock == block:
                blockDependencies[block].append(link.fromBlock)
    reverseBlockDependencies = {}
    for block in blockDependencies:
        for dependency in blockDependencies[block]:
            if not dependency in reverseBlockDependencies:
                reverseBlockDependencies[dependency] = []
            reverseBlockDependencies[dependency].append(block)
    return blockDependencies, reverseBlockDependencies

def getBlocksContent(blocks, links):
    blockDependencies, reverseBlockDependencies = getBlockDependencies(blocks, links)
    depths = []
    blocksContent = ""
    for block in blocks:
        description = block.blockType.getIODescription(block)
        inputs = "[%s]" % ", ".join(["np.int8"] * block.blockType.inputs.getRealCount())
        outputs = "[%s]" % ", ".join(["np.int8"] * block.blockType.outputs.getRealCount())
        position = getPosition(block, blockDependencies, reverseBlockDependencies, depths)
        blocksContent += BLOCK_TEMPLATE % (
                block.name, 
                block.name, 
                block.blockType.name, 
                description, 
                inputs, 
                outputs, 
                position[0], 
                position[1])
    return blocksContent

def getLinksContent(links):
    linksContent = ""
    for link in links:
        fromPort = link.fromBlock.blockType.outputs.getRealPort(link.fromPort)
        toPort = link.toBlock.blockType.inputs.getRealPort(link.toPort)
        linksContent += LINK_TEMPLATE % (link.fromBlock.name, fromPort, link.toBlock.name, toPort)
    return linksContent

def write(filename, blocks, links):
    with open(filename, "w+") as file:
        print("writing to file %s" % filename)
        file.truncate(0)
        file.write(GRC_TEMPLATE % (getBlocksContent(blocks, links), getLinksContent(links)))