Sure, here's a test case generator for the provided problem statement:

```python
import random
import string

def generate_random_string(length):
    return ''.join(random.choice(string.ascii_lowercase) for _ in range(length))

def tcgen():
    # Number of songs
    N = random.randint(1, 50)
    
    songs = []
    titles = set()
    
    for _ in range(N):
        # Ensure unique song titles
        while True:
            s_i = generate_random_string(random.randint(1, 100))
            if s_i not in titles:
                titles.add(s_i)
                break
        
        # Duration of the song
        t_i = random.randint(1, 1000)
        songs.append((s_i, t_i))
    
    # Choose a random song title from the list to be the one when Niwango fell asleep
    X = random.choice(songs)[0]
    
    return N, songs, X

def print_test_case(N, songs, X):
    print(N)
    for s, t in songs:
        print(f"{s} {t}")
    print(X)

# Generate and print a test case
N, songs, X = tcgen()
print_test_case(N, songs, X)
```

### Explanation
1. **generate_random_string(length)**: Generates a random string of lowercase English letters of the specified length.
2. **tcgen()**: Generates a test case by:
   - Randomly selecting the number of songs \(N\).
   - Creating unique song titles (ensuring no duplicates) and assigning them random durations.
   - Selecting a random song title \(X\) from the list of songs.
3. **print_test_case(N, songs, X)**: Outputs the generated test case in the required format.

### Example Output
Here is an example of what the generated test case might look like:

```
5
abc 123
def 456
ghi 789
jkl 101
mno 202
ghi
```

This ensures that the test case is formatted correctly and meets the constraints of the problem.