contract AudioToken is ERC20Detailed, Ownable {
    
    uint256 public constant INITIAL_SUPPLY = 1500000000e18;

    /**
    * @dev fixed supply of tokens.
    */
    constructor() public ERC20Detailed("AUDIO Token", "AUDIO", 18) {
        _mint(owner(), INITIAL_SUPPLY);
    }
    
    /**
    * @dev transfers _value tokens to a contract at address _to and calls the function 
    * tokenFallback(address, uint256, bytes) on that contract.
    */
    function transferAndCall(address _to, 
                             uint    _value, 
                             bytes   _data) public returns (bool) {
        require(_to != address(this));

        transfer(_to, _value);
    
        require(TransferAndCallFallBack(_to).tokenFallback(
            msg.sender, 
            _value,
            _data
        ));
        
        return true;
    }
    
    /**
    * @dev transfers _value tokens from address _from to a contract 
    * at address _to and calls the function tokenFallback(address, uint256, bytes) 
    * on that contract.
    */
    function transferFromAndCall(address _from,
                                 address _to, 
                                 uint    _value, 
                                 bytes   _data) public returns (bool) {
        require(_to != address(this));

        transferFrom(_from, _to, _value);
    
        require(TransferAndCallFallBack(_to).tokenFallback(
            _from, 
            _value, 
            _data
        ));
        
        return true;
    }
    
    /**
    * @dev approves _value tokens to be transfered to a contract _spender
    * and calls the function receiveApproval(address, uint256, bytes) 
    * on that contract. Requires current approval to be 0 to avoid double spending.
    */
    function approveAndCall(address _spender, 
                            uint    _value, 
                            bytes   _data) public returns (bool) {
        require(_spender != address(this));
        require(_value == 0 || allowance(msg.sender, _spender) == 0);
        
        approve(_spender, _value);
        
        require(ApproveAndCallFallBack(_spender).receiveApproval(
            msg.sender, 
            _value,
            _data
        ));

        return true;
    }
    
    /**
    * @dev recover any mistakenly sent ERC-20 tokens (also works for ERC-721 tokens).
    */
    function recoverTokens(address _token, uint256 _value) onlyOwner public returns (bool) {
        IERC20 erc20 = IERC20(_token);
        return erc20.transfer(owner(), _value);
    }
    
    /**
    * @dev recover any mistakenly sent ETH.
    */
    function recoverEther() onlyOwner public {
        owner().transfer(address(this).balance);
    }
}
function recoverTokens(address _token, uint256 _value) onlyOwner public returns (bool) {
    IERC20 erc20 = IERC20(_token);
    return erc20.transfer(owner(), _value);
}

/**
 * @dev recover any mistakenly sent ERC-20 tokens (also works for ERC-721 tokens).
 */