Não vamos desistir ainda.
Vamos entender o que está acontecendo e como resolver.
O problema
Você tem duas entidades:
public class Musica
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public int AnoLancamento { get; set; }
    // Chave estrangeira
    public int ArtistaId { get; set; }
    // Propriedade de navegação
    public Artista? Artista { get; set; }
}
e
public class Artista
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public string FotoPerfil { get; set; }
    public string Bio { get; set; }
    // Relacionamento 1:N
    public ICollection<Musica> Musicas { get; set; } = new List<Musica>();
}
O mapeamento no banco está correto.
A foreign key existe e o relacionamento está definido.
O motivo de artista estar null no JSON** é que o Entity Framework Core, por padrão, não carrega as entidades relacionadas automaticamente quando você faz uma consulta simples.
Entendendo o comportamento
Quando você faz algo assim:
var musicas = _context.Musicas.ToList();
O EF Core só carrega os dados da tabela Musicas, não faz o "join" automático com Artistas.
Por isso, ao serializar o objeto Musica para JSON, o campo Artista está null.
Solução: usar Eager Loading com .Include()
Para trazer também o artista de cada música, você precisa usar o método Include, do namespace Microsoft.EntityFrameworkCore:
using Microsoft.EntityFrameworkCore;
// ...
var musicas = _context.Musicas
    .Include(m => m.Artista)
    .ToList();
Agora, cada objeto Musica terá o campo Artista populado corretamente, e o JSON ficará assim:
{
  "musicas": [
    {
      "id": 5,
      "nome": "Oceano",
      "anoLancamento": 1989,
      "artista": {
        "id": 1,
        "nome": "Djavan",
        "fotoPerfil": "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_1280.png",
        "bio": "Djavan Caetano Viana é um cantor, compositor..."
      }
    }
  ]
}
Caso esteja usando uma API mínima (Minimal API)
Se o seu endpoint estiver assim:
app.MapGet("/musicas", (ScreenSoundContext context) =>
{
    var musicas = context.Musicas.ToList();
    return Results.Ok(new { musicas });
});
Basta alterar para:
app.MapGet("/musicas", (ScreenSoundContext context) =>
{
    var musicas = context.Musicas
        .Include(m => m.Artista)
        .ToList();
    return Results.Ok(new { musicas });
});
Outras formas de carregar os dados
Existem três formas de o EF Core carregar dados relacionados:
| Tipo | Como faz | Quando usar | 
|---|
| Eager Loading | .Include(m => m.Artista) | Quando você sabe que vai precisar dos dados relacionados. | 
| Lazy Loading | Carrega automaticamente quando acessa a propriedade ( m.Artista) — requer configuração especial. | Quando quer carregar sob demanda. | 
| Explicit Loading | Usa .Entry(m).Reference(x => x.Artista).Load()manualmente. | Quando quer controle total. | 
O curso de Entity Framework possivelmente mostrou o relacionamento e as classes, mas no curso da API você ainda precisa explicitamente incluir os dados com .Include(), já que o EF não faz isso automaticamente.
Se você quer simplificar o JSON (por exemplo, evitar que o Artista venha com a lista de músicas, o que pode causar loop de referência), pode usar um DTO:
public record MusicaDTO(int Id, string Nome, int AnoLancamento, string Artista);
e no endpoint:
app.MapGet("/musicas", (ScreenSoundContext context) =>
{
    var musicas = context.Musicas
        .Include(m => m.Artista)
        .Select(m => new MusicaDTO(m.Id, m.Nome, m.AnoLancamento, m.Artista!.Nome))
        .ToList();
    return Results.Ok(new { musicas });
});
Isso evita problemas de serialização circular e deixa a resposta mais limpa.
Analisa o conteudo do texto, faça os testes e mudanças necessarias e me envia um feedback.
Bons estudos.
Agora vai...!