1. You don't need the parentheses.
2. If you use process substitution [1] instead of a pipe, you will stay in the same process and can modify variables of the enclosing scope:
i=0
while read -r v; do
...
i=$(( i + 1))
done < <(do_something)
The drawback is that this way `do_something` has to come after `done`, but that's bash for you ¯\_(ツ)_/¯[1] https://www.gnu.org/software/bash/manual/html_node/Process-S...